Re: AW: Understanding behavior of git blame -M

2014-08-16 Thread David Kastrup
"Sokolov, Konstantin (ext)"  writes:

> Hi David,
>
> thank you very much for the exhaustive answer. The keyword "hunk" made
> me try a little bit more. So I realized that -M works as expected when
> at least three lines are moved.
>
> From your answer I discern that you find the current behavior
> correct.

I don't say any such thing and don't imply it.

-- 
David Kastrup
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


You do not have permission to post to the ms...@lists.myitforum.com list

2014-08-16 Thread ms...@lists.myitforum.com
Sorry, you do not have permission to post to the ms...@lists.myitforum.com 
mailing list.

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] convert: Stream from fd to required clean filter instead of mmap

2014-08-16 Thread John Keeping
On Wed, Aug 06, 2014 at 07:32:14AM +0200, Steffen Prohaska wrote:
[...]
> The expectation on the process size is tested using /usr/bin/time.  An
> alternative would have been tcsh, which could be used to print memory
> information as follows:
> 
> tcsh -c 'set time=(0 "%M"); '
> 
> Although the logic could perhaps be simplified with tcsh, I chose to use
> 'time' to avoid a dependency on tcsh.
[...]
> @@ -190,6 +196,58 @@ test_expect_success 'required filter clean failure' '
>   test_must_fail git add test.fc
>  '
>  
> +# Handle differences in /usr/bin/time.
> +#
> +#  - Linux: call with '-v'.
> +#output: :
> +#
> +#  - Mac: call with '-l'.
> +#output: 
> +#Strip three digits to get to KB (base 10 is good enough).
> +#
> +case $(uname -s) in
> +Linux)
> + test_set_prereq HAVE_MAX_MEM_USAGE
> + max_mem_usage_KB () {
> + /usr/bin/time -v "$@" 2>&1 |
> + grep 'Maximum resident set size' |
> + cut -d ':' -f 2
> + }
> + ;;
> +Darwin)
> + test_set_prereq HAVE_MAX_MEM_USAGE
> + max_mem_usage_KB () {
> + /usr/bin/time -l "$@" 2>&1 |
> + grep 'maximum resident set size' |
> + sed -e 's/  */ /' |
> + cut -d ' ' -f 2 |
> + sed -e 's/...$//'
> + }
> + ;;
> +esac
> +
> +max_mem_usage_is_lt_KB () {
> + limit=$1
> + shift
> + mem_usage=$(max_mem_usage_KB "$@")
> + if [ $mem_usage -lt $limit ]; then
> + true
> + else
> + printf 'Command used too much memory (expected limit %dKB, 
> actual usage %dKB).\n' \
> + $limit $mem_usage
> + false
> + fi
> +}
> +
> +test_expect_success HAVE_MAX_MEM_USAGE \
> +'filtering large input to small output should use little memory' '
> + git config filter.devnull.clean "cat >/dev/null" &&
> + git config filter.devnull.required true &&
> + for i in $(test_seq 1 30); do printf "%1048576d" 1; done >30MB &&
> + echo "30MB filter=devnull" >.gitattributes &&
> + max_mem_usage_is_lt_KB 15000 git add 30MB
> +'

This test fails for me:

-- 8< --
expecting success: 
git config filter.devnull.clean "cat >/dev/null" &&
git config filter.devnull.required true &&
for i in $(test_seq 1 30); do printf "%1048576d" 1; done >30MB &&
echo "30MB filter=devnull" >.gitattributes &&
max_mem_usage_is_lt_KB 15000 git add 30MB

Command used too much memory (expected limit 15000KB, actual usage 15808KB).
not ok 8 - filtering large input to small output should use little memory
-- >8 --

This is on Linux 3.16 x86_64 with GCC 4.8.3 and glibc 2.19.  My GCC also
has "-fstack-protector" and "-D_FORTIFY_SOURCE=2" enabled by default;
turning those off for Git decreased the memory usage by about 500KB but
not enough to make the test pass.  Of course, all of the libraries Git
is linking are also compiled with those flags...

Is the 15MB limit supposed to be imposed somewhere or is it just a guide
of how much memory we expect Git to use in this scenario?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GIT PULL] l10n updates for 2.1.0 round 1

2014-08-16 Thread Jiang Xin
I'm sorry this pull request is late for git v2.1.0.  I should send it out
yesterday night using the network of my new house, but after 2
weeks' business travel and home moving, I'm a bit lazy.

And German translation is still under review, so it is not included
in this pull request.

The following changes since commit 49f1cb93a2f11845cfa2723611a729d3d7f02f0d:

  Git 2.1.0-rc0 (2014-07-27 15:22:22 -0700)

are available in the git repository at:

  git://github.com/git-l10n/git-po

for you to fetch changes up to f7fbc357f863ecc5323f3fcf2fc9cbf2aa2a8587:

  l10n: fr.po (2257t) update for version 2.1.0 (2014-08-07 09:07:18 +0200)


Alexander Shopov (3):
  l10n: Updated Bulgarian translation of git (2228t,0f,0u)
  l10n: Updated Bulgarian translation of git (2247t,0f,0u)
  l10n: Updated Bulgarian translation of git (2257t,0f,0u)

Jean-Noel Avila (1):
  l10n: fr.po (2257t) update for version 2.1.0

Jiang Xin (6):
  l10n: git.pot: v2.1.0 round 1 (38 new, 9 removed)
  Merge remote-tracking branch 'sv/nafmo/master'
  Merge commit 'bg/alshopov/master'
  l10n: zh_CN: translations for git v2.1.0-rc0
  Merge branch 'master' of github.com:alshopov/git-po
  Merge remote-tracking branch 'l10n/vi/vnwildman/master'

Peter Krefting (2):
  l10n: Fix more typos in the Swedish translations
  l10n: sv.po: Update Swedish translation (2257t0f0u)

Trần Ngọc Quân (1):
  l10n: vi.po (2257t): Update translation

 po/bg.po| 5134 +--
 po/fr.po| 2871 +
 po/git.pot  | 2804 
 po/sv.po| 2871 +
 po/vi.po| 2853 +
 po/zh_CN.po | 2822 
 6 files changed, 10320 insertions(+), 9035 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] clean: use f(void) instead of f() to declare a pointer to a function without arguments

2014-08-16 Thread René Scharfe
Explicitly state that menu_item functions like clean_cmd don't take
any arguments by using void instead of an empty parameter list.

Found using gcc -Wstrict-prototypes.

Signed-off-by: Rene Scharfe 
---
 builtin/clean.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 1032563..3beeea6 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -67,7 +67,7 @@ struct menu_item {
char hotkey;
const char *title;
int selected;
-   int (*fn)();
+   int (*fn)(void);
 };
 
 enum menu_stuff_type {
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] read-cache.c: Ensure unmerged entries are removed

2014-08-16 Thread Jaime Soriano Pastor
I'd like to add some tests too for this, but I don't know how to
reproduce this state with git commands only, is there any way to add
entries to the index without checkings?
Or maybe it could be done by creating a "test-" command that adds the
entries to an index?

Thanks.

On Fri, Aug 15, 2014 at 11:45 PM, Junio C Hamano  wrote:
> Jaime Soriano Pastor  writes:
>
>> On Thu, Aug 14, 2014 at 1:04 AM, Junio C Hamano  wrote:
>>> Being a conservative, I'd rather avoid doing any magic during
>>> read_cache() time. "ls-files -s" for example should show the four
>>> stages so that the "broken" state can be inspected.
>>>
>> Well, only read_cache_unmerged() is modified in the sent patch, so no
>> magic is done in read_cache(), I'd also avoid changes there.
>
> Ahh, I must have overlooked that; changes being only in _unmerged()
> variant makes me feel much better, and it probably would make much
> of ...
>
>>> Yes, it would be more work,...
>
> ... moot, hopefully ;-)
>
>> git reset will clean the index anyway if the loop finishes, would it
>> be ok?
>
> Surely.
>
>> git merge is also affected by the loop in read_cache_unmerged(), but
>> any of the solutions would be enough for it as only by finishing the
>> loop with unmerged entries it will die without commiting the cache to
>> the index file.
>
> Again, true.  The mergy operations want to start from a clean slate
> and they call _unmerged() variant primarily to learn that there were
> unmerged entries in the index, only to abort the operation in that
> case, so a change to _unmerged() variant should be safe for them.
>
> I'll take another look at your patch later, but not before the 2.1
> final, and by that time you may already have sent a reroll ;-)
>
> Thanks.



-- 
Jaime Soriano Pastor - Software Developer
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/2] convert: Stream from fd to required clean filter instead of mmap

2014-08-16 Thread Steffen Prohaska

On Aug 16, 2014, at 12:27 PM, John Keeping  wrote:

>> +test_expect_success HAVE_MAX_MEM_USAGE \
>> +'filtering large input to small output should use little memory' '
>> +git config filter.devnull.clean "cat >/dev/null" &&
>> +git config filter.devnull.required true &&
>> +for i in $(test_seq 1 30); do printf "%1048576d" 1; done >30MB &&
>> +echo "30MB filter=devnull" >.gitattributes &&
>> +max_mem_usage_is_lt_KB 15000 git add 30MB
>> +'
> 
> This test fails for me:
> 
> -- 8< --
> expecting success: 
>git config filter.devnull.clean "cat >/dev/null" &&
>git config filter.devnull.required true &&
>for i in $(test_seq 1 30); do printf "%1048576d" 1; done >30MB &&
>echo "30MB filter=devnull" >.gitattributes &&
>max_mem_usage_is_lt_KB 15000 git add 30MB
> 
> Command used too much memory (expected limit 15000KB, actual usage 15808KB).
> not ok 8 - filtering large input to small output should use little memory
> -- >8 --
> 
> This is on Linux 3.16 x86_64 with GCC 4.8.3 and glibc 2.19.  My GCC also
> has "-fstack-protector" and "-D_FORTIFY_SOURCE=2" enabled by default;
> turning those off for Git decreased the memory usage by about 500KB but
> not enough to make the test pass.  Of course, all of the libraries Git
> is linking are also compiled with those flags...
> 
> Is the 15MB limit supposed to be imposed somewhere or is it just a guide
> of how much memory we expect Git to use in this scenario?

The test should confirm that the the file that is added is not mmapped to 
memory.  The process size should be relatively small independently of the size 
of the file that is added.  I wanted to keep the file size small.  The chosen 
sizes worked for me on Mac and Linux.

A simple solution could be to increase the size of the test file and the limit. 
 I'd suggest to squash the diff below.  The test should still run reasonably 
fast with a 50 MB test file.

Junio, shall I send a whole updated patch series?

Steffen


diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index 2cb2414..43de87d 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -243,9 +243,9 @@ test_expect_success HAVE_MAX_MEM_USAGE \
 'filtering large input to small output should use little memory' '
git config filter.devnull.clean "cat >/dev/null" &&
git config filter.devnull.required true &&
-   for i in $(test_seq 1 30); do printf "%1048576d" 1; done >30MB &&
-   echo "30MB filter=devnull" >.gitattributes &&
-   max_mem_usage_is_lt_KB 15000 git add 30MB
+   for i in $(test_seq 1 50); do printf "%1048576d" 1; done >50MB &&
+   echo "50MB filter=devnull" >.gitattributes &&
+   max_mem_usage_is_lt_KB 35000 git add 50MB
 '




--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 03/11] trailer: read and process config information

2014-08-16 Thread Christian Couder
Read the configuration to get trailer information, and then process
it and store it in a doubly linked list.

The config information is stored in the list whose first item is
pointed to by:

static struct trailer_item *first_conf_item;

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 trailer.c | 185 ++
 1 file changed, 185 insertions(+)

diff --git a/trailer.c b/trailer.c
index 4940e06..2d391f3 100644
--- a/trailer.c
+++ b/trailer.c
@@ -272,3 +272,188 @@ static void process_trailers_lists(struct trailer_item 
**in_tok_first,
 arg_tok);
}
 }
+
+static int set_where(struct conf_info *item, const char *value)
+{
+   if (!strcasecmp("after", value))
+   item->where = WHERE_AFTER;
+   else if (!strcasecmp("before", value))
+   item->where = WHERE_BEFORE;
+   else if (!strcasecmp("end", value))
+   item->where = WHERE_END;
+   else if (!strcasecmp("start", value))
+   item->where = WHERE_START;
+   else
+   return -1;
+   return 0;
+}
+
+static int set_if_exists(struct conf_info *item, const char *value)
+{
+   if (!strcasecmp("addIfDifferent", value))
+   item->if_exists = EXISTS_ADD_IF_DIFFERENT;
+   else if (!strcasecmp("addIfDifferentNeighbor", value))
+   item->if_exists = EXISTS_ADD_IF_DIFFERENT_NEIGHBOR;
+   else if (!strcasecmp("add", value))
+   item->if_exists = EXISTS_ADD;
+   else if (!strcasecmp("replace", value))
+   item->if_exists = EXISTS_REPLACE;
+   else if (!strcasecmp("doNothing", value))
+   item->if_exists = EXISTS_DO_NOTHING;
+   else
+   return -1;
+   return 0;
+}
+
+static int set_if_missing(struct conf_info *item, const char *value)
+{
+   if (!strcasecmp("doNothing", value))
+   item->if_missing = MISSING_DO_NOTHING;
+   else if (!strcasecmp("add", value))
+   item->if_missing = MISSING_ADD;
+   else
+   return -1;
+   return 0;
+}
+
+static void duplicate_conf(struct conf_info *dst, struct conf_info *src)
+{
+   *dst = *src;
+   if (src->name)
+   dst->name = xstrdup(src->name);
+   if (src->key)
+   dst->key = xstrdup(src->key);
+   if (src->command)
+   dst->command = xstrdup(src->command);
+}
+
+static struct trailer_item *get_conf_item(const char *name)
+{
+   struct trailer_item *item;
+   struct trailer_item *previous;
+
+   /* Look up item with same name */
+   for (previous = NULL, item = first_conf_item;
+item;
+previous = item, item = item->next) {
+   if (!strcasecmp(item->conf.name, name))
+   return item;
+   }
+
+   /* Item does not already exists, create it */
+   item = xcalloc(sizeof(struct trailer_item), 1);
+   duplicate_conf(&item->conf, &default_conf_info);
+   item->conf.name = xstrdup(name);
+
+   if (!previous)
+   first_conf_item = item;
+   else {
+   previous->next = item;
+   item->previous = previous;
+   }
+
+   return item;
+}
+
+enum trailer_info_type { TRAILER_KEY, TRAILER_COMMAND, TRAILER_WHERE,
+TRAILER_IF_EXISTS, TRAILER_IF_MISSING };
+
+static struct {
+   const char *name;
+   enum trailer_info_type type;
+} trailer_config_items[] = {
+   { "key", TRAILER_KEY },
+   { "command", TRAILER_COMMAND },
+   { "where", TRAILER_WHERE },
+   { "ifexists", TRAILER_IF_EXISTS },
+   { "ifmissing", TRAILER_IF_MISSING }
+};
+
+static int git_trailer_default_config(const char *conf_key, const char *value, 
void *cb)
+{
+   const char *trailer_item, *variable_name;
+
+   if (!skip_prefix(conf_key, "trailer.", &trailer_item))
+   return 0;
+
+   variable_name = strrchr(trailer_item, '.');
+   if (!variable_name) {
+   if (!strcmp(trailer_item, "where")) {
+   if (set_where(&default_conf_info, value) < 0)
+   warning(_("unknown value '%s' for key '%s'"),
+   value, conf_key);
+   } else if (!strcmp(trailer_item, "ifexists")) {
+   if (set_if_exists(&default_conf_info, value) < 0)
+   warning(_("unknown value '%s' for key '%s'"),
+   value, conf_key);
+   } else if (!strcmp(trailer_item, "ifmissing")) {
+   if (set_if_missing(&default_conf_info, value) < 0)
+   warning(_("unknown value '%s' for key '%s'"),
+   value, conf_key);
+   } else if (!strcmp(trailer_item, "separators")) {
+   separators = xstrdup(value);
+   

[PATCH v13 05/11] trailer: parse trailers from file or stdin

2014-08-16 Thread Christian Couder
Read trailers from a file or from stdin, parse the trailers and then
put the result into a doubly linked list.

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 trailer.c | 123 ++
 1 file changed, 123 insertions(+)

diff --git a/trailer.c b/trailer.c
index b9d3ed4..46e2fcb 100644
--- a/trailer.c
+++ b/trailer.c
@@ -64,6 +64,14 @@ static int same_trailer(struct trailer_item *a, struct 
trailer_item *b)
return same_token(a, b) && same_value(a, b);
 }
 
+static inline int contains_only_spaces(const char *str)
+{
+   const char *s = str;
+   while (*s && isspace(*s))
+   s++;
+   return !*s;
+}
+
 static void free_trailer_item(struct trailer_item *item)
 {
free(item->conf.name);
@@ -582,3 +590,118 @@ static struct trailer_item 
*process_command_line_args(struct string_list *traile
 
return arg_tok_first;
 }
+
+static struct strbuf **read_input_file(const char *file)
+{
+   struct strbuf **lines;
+   struct strbuf sb = STRBUF_INIT;
+
+   if (file) {
+   if (strbuf_read_file(&sb, file, 0) < 0)
+   die_errno(_("could not read input file '%s'"), file);
+   } else {
+   if (strbuf_read(&sb, fileno(stdin), 0) < 0)
+   die_errno(_("could not read from stdin"));
+   }
+
+   lines = strbuf_split(&sb, '\n');
+
+   strbuf_release(&sb);
+
+   return lines;
+}
+
+/*
+ * Return the (0 based) index of the start of the patch or the line
+ * count if there is no patch in the message.
+ */
+static int find_patch_start(struct strbuf **lines, int count)
+{
+   int i;
+
+   /* Get the start of the patch part if any */
+   for (i = 0; i < count; i++) {
+   if (starts_with(lines[i]->buf, "---"))
+   return i;
+   }
+
+   return count;
+}
+
+/*
+ * Return the (0 based) index of the first trailer line or count if
+ * there are no trailers. Trailers are searched only in the lines from
+ * index (count - 1) down to index 0.
+ */
+static int find_trailer_start(struct strbuf **lines, int count)
+{
+   int start, only_spaces = 1;
+
+   /*
+* Get the start of the trailers by looking starting from the end
+* for a line with only spaces before lines with one separator.
+*/
+   for (start = count - 1; start >= 0; start--) {
+   if (lines[start]->buf[0] == comment_line_char)
+   continue;
+   if (contains_only_spaces(lines[start]->buf)) {
+   if (only_spaces)
+   continue;
+   return start + 1;
+   }
+   if (strcspn(lines[start]->buf, separators) < lines[start]->len) 
{
+   if (only_spaces)
+   only_spaces = 0;
+   continue;
+   }
+   return count;
+   }
+
+   return only_spaces ? count : 0;
+}
+
+static int has_blank_line_before(struct strbuf **lines, int start)
+{
+   for (;start >= 0; start--) {
+   if (lines[start]->buf[0] == comment_line_char)
+   continue;
+   return contains_only_spaces(lines[start]->buf);
+   }
+   return 0;
+}
+
+static void print_lines(struct strbuf **lines, int start, int end)
+{
+   int i;
+   for (i = start; lines[i] && i < end; i++)
+   printf("%s", lines[i]->buf);
+}
+
+static int process_input_file(struct strbuf **lines,
+ struct trailer_item **in_tok_first,
+ struct trailer_item **in_tok_last)
+{
+   int count = 0;
+   int patch_start, trailer_start, i;
+
+   /* Get the line count */
+   while (lines[count])
+   count++;
+
+   patch_start = find_patch_start(lines, count);
+   trailer_start = find_trailer_start(lines, patch_start);
+
+   /* Print lines before the trailers as is */
+   print_lines(lines, 0, trailer_start);
+
+   if (!has_blank_line_before(lines, trailer_start - 1))
+   printf("\n");
+
+   /* Parse trailer lines */
+   for (i = trailer_start; i < patch_start; i++) {
+   struct trailer_item *new = create_trailer_item(lines[i]->buf);
+   add_trailer_item(in_tok_first, in_tok_last, new);
+   }
+
+   return patch_start;
+}
-- 
2.0.1.674.ga7f57b7


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 00/11] Add interpret-trailers builtin

2014-08-16 Thread Christian Couder
This patch series implements a new command:

git interpret-trailers

and an infrastructure to process trailers that can be reused,
for example in "commit.c".

1) Rationale:

This command should help with RFC 822 style headers, called
"trailers", that are found at the end of commit messages.

(Note that these headers do not follow and are not intended to
follow many rules that are in RFC 822. For example they do not
follow the line breaking rules, the encoding rules and probably
many other rules.)

For a long time, these trailers have become a de facto standard
way to add helpful information into commit messages.

Until now git commit has only supported the well known
"Signed-off-by: " trailer, that is used by many projects like
the Linux kernel and Git.

It is better to keep builtin/commit.c uncontaminated by any more
hard-wired logic, like what we have for the signed-off-by line.  Any
new things can and should be doable in hooks, and this filter would
help writing these hooks.

And that is why the design goal of the filter is to make it at least
as powerful as the built-in logic we have for signed-off-by lines;
that would allow us to later eject the hard-wired logic for
signed-off-by line from the main codepath, if/when we wanted to.

Alternatively, we could build a library-ish API around this filter
code and replace the hard-wired logic for signed-off-by line with a
call into that API, if/when we wanted to, but that requires (in
addition to the "at least as powerful as the built-in logic") that
the implementation of this stand-alone filter can be cleanly made
into a reusable library, so that is a bit higher bar to cross than
"everything can be doable with hooks" alternative.

2) Current state:

Currently the usage string of this command is:

git interpret-trailers [--trim-empty] [(--trailer [(=|:)])...] 
[...]

The following features are implemented:

- the result is printed on stdout
- the --trailer arguments are interpreted
- messages read from ... or stdin are interpreted
- the "trailer.separators" option in the config is interpreted (new)
- the "trailer.where" option is interpreted (new)
- the "trailer.ifexists" option is interpreted (new)
- the "trailer.ifmissing" option is interpreted (new)
- the "trailer..key" options are interpreted
- the "trailer..where" options are interpreted
- the "trailer..ifexist" options are interpreted
- the "trailer..ifmissing" options are interpreted
- the "trailer..command" config works
- $ARG can be used in commands
- messages can contain a patch
- lines in messages starting with a comment char are ignored
- there are 49 tests
- there is some documentation
- there are examples in the documentation

3) Changes since version 12, thanks to Jakub, Michael, Johan and Junio:

* "end" and "start" values for "trailer..where" have been
  implemented
* "end" has been made the default value for "where", but this default
  value can be changed using the new "trailer.where" config
  variable
* "addIfDifferentNeighbor" is now the default value for "ifexists",
  but this default can be changed using the new "trailer.ifexists"
  config variable
* the new "trailer.ifmissing" can be used to change the default value
  for "ifmissing" (which is "add")
* by default the only separator is ':', this can be changed by using
  the new "trailer.separators" config variable
* only the configured separators (or just ':' by default) are used for
  both input parsing and output printing; the only exception is that
  '=' is always accepted as separator when parsing
  "--trailer ''" command line arguments, for
  compatibility with other git commands
* 14 tests have been added

Only patches 7/11, 9/11 and 10/11 have not been changed since v12.

Christian Couder (11):
  trailer: add data structures and basic functions
  trailer: process trailers from input message and arguments
  trailer: read and process config information
  trailer: process command line trailer arguments
  trailer: parse trailers from file or stdin
  trailer: put all the processing together and print
  trailer: add interpret-trailers command
  trailer: add tests for "git interpret-trailers"
  trailer: execute command from 'trailer..command'
  trailer: add tests for commands in config file
  Documentation: add documentation for 'git interpret-trailers'

 .gitignore   |   1 +
 Documentation/git-interpret-trailers.txt | 308 +++
 Makefile |   2 +
 builtin.h|   1 +
 builtin/interpret-trailers.c |  44 ++
 command-list.txt |   1 +
 git.c|   1 +
 t/t7513-interpret-trailers.sh| 850 +++
 trailer.c| 830 ++
 trailer.h 

[PATCH v13 04/11] trailer: process command line trailer arguments

2014-08-16 Thread Christian Couder
Parse the trailer command line arguments and put
the result into an arg_tok doubly linked list.

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 trailer.c | 125 ++
 1 file changed, 125 insertions(+)

diff --git a/trailer.c b/trailer.c
index 2d391f3..b9d3ed4 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "string-list.h"
 /*
  * Copyright (c) 2013, 2014 Christian Couder 
  */
@@ -457,3 +458,127 @@ static int git_trailer_config(const char *conf_key, const 
char *value, void *cb)
}
return 0;
 }
+
+static int parse_trailer(struct strbuf *tok, struct strbuf *val, const char 
*trailer)
+{
+   size_t len;
+   struct strbuf seps = STRBUF_INIT;
+   strbuf_addstr(&seps, separators);
+   strbuf_addch(&seps, '=');
+   len = strcspn(trailer, seps.buf);
+   strbuf_release(&seps);
+   if (len == 0)
+   return error(_("empty trailer token in trailer '%s'"), trailer);
+   if (len < strlen(trailer)) {
+   strbuf_add(tok, trailer, len);
+   strbuf_trim(tok);
+   strbuf_addstr(val, trailer + len + 1);
+   strbuf_trim(val);
+   } else {
+   strbuf_addstr(tok, trailer);
+   strbuf_trim(tok);
+   }
+   return 0;
+}
+
+
+static void duplicate_conf(struct conf_info *dst, struct conf_info *src)
+{
+   *dst = *src;
+   if (src->name)
+   dst->name = xstrdup(src->name);
+   if (src->key)
+   dst->key = xstrdup(src->key);
+   if (src->command)
+   dst->command = xstrdup(src->command);
+}
+
+static const char *token_from_item(struct trailer_item *item)
+{
+   if (item->conf.key)
+   return item->conf.key;
+
+   return item->conf.name;
+}
+
+static struct trailer_item *new_trailer_item(struct trailer_item *conf_item,
+char *tok, char *val)
+{
+   struct trailer_item *new = xcalloc(sizeof(*new), 1);
+   new->value = val;
+
+   if (conf_item) {
+   duplicate_conf(&new->conf, &conf_item->conf);
+   new->token = xstrdup(token_from_item(conf_item));
+   free(tok);
+   } else {
+   duplicate_conf(&new->conf, &default_conf_info);
+   new->token = tok;
+   }
+
+   return new;
+}
+
+static int token_matches_item(const char *tok, struct trailer_item *item, int 
alnum_len)
+{
+   if (!strncasecmp(tok, item->conf.name, alnum_len))
+   return 1;
+   return item->conf.key ? !strncasecmp(tok, item->conf.key, alnum_len) : 
0;
+}
+
+static struct trailer_item *create_trailer_item(const char *string)
+{
+   struct strbuf tok = STRBUF_INIT;
+   struct strbuf val = STRBUF_INIT;
+   struct trailer_item *item;
+   int tok_alnum_len;
+
+   if (parse_trailer(&tok, &val, string))
+   return NULL;
+
+   tok_alnum_len = alnum_len(tok.buf, tok.len);
+
+   /* Lookup if the token matches something in the config */
+   for (item = first_conf_item; item; item = item->next) {
+   if (token_matches_item(tok.buf, item, tok_alnum_len)) {
+   strbuf_release(&tok);
+   return new_trailer_item(item,
+   NULL,
+   strbuf_detach(&val, NULL));
+   }
+   }
+
+   return new_trailer_item(NULL,
+   strbuf_detach(&tok, NULL),
+   strbuf_detach(&val, NULL));
+}
+
+static void add_trailer_item(struct trailer_item **first,
+struct trailer_item **last,
+struct trailer_item *new)
+{
+   if (!new)
+   return;
+   if (!*last) {
+   *first = new;
+   *last = new;
+   } else {
+   (*last)->next = new;
+   new->previous = *last;
+   *last = new;
+   }
+}
+
+static struct trailer_item *process_command_line_args(struct string_list 
*trailers)
+{
+   struct trailer_item *arg_tok_first = NULL;
+   struct trailer_item *arg_tok_last = NULL;
+   struct string_list_item *tr;
+
+   for_each_string_list_item(tr, trailers) {
+   struct trailer_item *new = create_trailer_item(tr->string);
+   add_trailer_item(&arg_tok_first, &arg_tok_last, new);
+   }
+
+   return arg_tok_first;
+}
-- 
2.0.1.674.ga7f57b7


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 01/11] trailer: add data structures and basic functions

2014-08-16 Thread Christian Couder
We will use a doubly linked list to store all information
about trailers and their configuration.

This way we can easily remove or add trailers to or from
trailer lists while traversing the lists in either direction.

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 Makefile  |  1 +
 trailer.c | 64 +++
 2 files changed, 65 insertions(+)
 create mode 100644 trailer.c

diff --git a/Makefile b/Makefile
index 63a210d..ef82972 100644
--- a/Makefile
+++ b/Makefile
@@ -888,6 +888,7 @@ LIB_OBJS += submodule-config.o
 LIB_OBJS += symlinks.o
 LIB_OBJS += tag.o
 LIB_OBJS += trace.o
+LIB_OBJS += trailer.o
 LIB_OBJS += transport.o
 LIB_OBJS += transport-helper.o
 LIB_OBJS += tree-diff.o
diff --git a/trailer.c b/trailer.c
new file mode 100644
index 000..2adc1b7
--- /dev/null
+++ b/trailer.c
@@ -0,0 +1,64 @@
+#include "cache.h"
+/*
+ * Copyright (c) 2013, 2014 Christian Couder 
+ */
+
+enum action_where { WHERE_END, WHERE_AFTER, WHERE_BEFORE, WHERE_START };
+enum action_if_exists { EXISTS_ADD_IF_DIFFERENT_NEIGHBOR, 
EXISTS_ADD_IF_DIFFERENT,
+   EXISTS_ADD, EXISTS_REPLACE, EXISTS_DO_NOTHING };
+enum action_if_missing { MISSING_ADD, MISSING_DO_NOTHING };
+
+struct conf_info {
+   char *name;
+   char *key;
+   char *command;
+   enum action_where where;
+   enum action_if_exists if_exists;
+   enum action_if_missing if_missing;
+};
+
+static struct conf_info default_conf_info;
+
+struct trailer_item {
+   struct trailer_item *previous;
+   struct trailer_item *next;
+   const char *token;
+   const char *value;
+   struct conf_info conf;
+};
+
+static struct trailer_item *first_conf_item;
+
+static char *separators = ":";
+
+static int after_or_end(enum action_where where)
+{
+   return (where == WHERE_AFTER) || (where == WHERE_END);
+}
+
+/* Get the length of buf from its beginning until its last alphanumeric 
character */
+static size_t alnum_len(const char *buf, size_t len)
+{
+   while (len > 0 && !isalnum(buf[len - 1]))
+   len--;
+   return len;
+}
+
+static int same_token(struct trailer_item *a, struct trailer_item *b)
+{
+   size_t a_alnum_len = alnum_len(a->token, strlen(a->token));
+   size_t b_alnum_len = alnum_len(b->token, strlen(b->token));
+   size_t min_alnum_len = (a_alnum_len > b_alnum_len) ? b_alnum_len : 
a_alnum_len;
+
+   return !strncasecmp(a->token, b->token, min_alnum_len);
+}
+
+static int same_value(struct trailer_item *a, struct trailer_item *b)
+{
+   return !strcasecmp(a->value, b->value);
+}
+
+static int same_trailer(struct trailer_item *a, struct trailer_item *b)
+{
+   return same_token(a, b) && same_value(a, b);
+}
-- 
2.0.1.674.ga7f57b7


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 02/11] trailer: process trailers from input message and arguments

2014-08-16 Thread Christian Couder
Implement the logic to process trailers from the input message
and from arguments.

At the beginning trailers from the input message are in their
own "in_tok" doubly linked list, and trailers from arguments
are in their own "arg_tok" doubly linked list.

The lists are traversed and when an "arg_tok" should be "applied",
it is removed from its list and inserted into the "in_tok" list.

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 trailer.c | 210 ++
 1 file changed, 210 insertions(+)

diff --git a/trailer.c b/trailer.c
index 2adc1b7..4940e06 100644
--- a/trailer.c
+++ b/trailer.c
@@ -62,3 +62,213 @@ static int same_trailer(struct trailer_item *a, struct 
trailer_item *b)
 {
return same_token(a, b) && same_value(a, b);
 }
+
+static void free_trailer_item(struct trailer_item *item)
+{
+   free(item->conf.name);
+   free(item->conf.key);
+   free(item->conf.command);
+   free((char *)item->token);
+   free((char *)item->value);
+   free(item);
+}
+
+static void update_last(struct trailer_item **last)
+{
+   if (*last)
+   while ((*last)->next != NULL)
+   *last = (*last)->next;
+}
+
+static void update_first(struct trailer_item **first)
+{
+   if (*first)
+   while ((*first)->previous != NULL)
+   *first = (*first)->previous;
+}
+
+static void add_arg_to_input_list(struct trailer_item *on_tok,
+ struct trailer_item *arg_tok,
+ struct trailer_item **first,
+ struct trailer_item **last)
+{
+   if (after_or_end(arg_tok->conf.where)) {
+   arg_tok->next = on_tok->next;
+   on_tok->next = arg_tok;
+   arg_tok->previous = on_tok;
+   if (arg_tok->next)
+   arg_tok->next->previous = arg_tok;
+   update_last(last);
+   } else {
+   arg_tok->previous = on_tok->previous;
+   on_tok->previous = arg_tok;
+   arg_tok->next = on_tok;
+   if (arg_tok->previous)
+   arg_tok->previous->next = arg_tok;
+   update_first(first);
+   }
+}
+
+static int check_if_different(struct trailer_item *in_tok,
+ struct trailer_item *arg_tok,
+ int check_all)
+{
+   enum action_where where = arg_tok->conf.where;
+   do {
+   if (!in_tok)
+   return 1;
+   if (same_trailer(in_tok, arg_tok))
+   return 0;
+   /*
+* if we want to add a trailer after another one,
+* we have to check those before this one
+*/
+   in_tok = after_or_end(where) ? in_tok->previous : in_tok->next;
+   } while (check_all);
+   return 1;
+}
+
+static void remove_from_list(struct trailer_item *item,
+struct trailer_item **first,
+struct trailer_item **last)
+{
+   struct trailer_item *next = item->next;
+   struct trailer_item *previous = item->previous;
+
+   if (next) {
+   item->next->previous = previous;
+   item->next = NULL;
+   } else if (last)
+   *last = previous;
+
+   if (previous) {
+   item->previous->next = next;
+   item->previous = NULL;
+   } else if (first)
+   *first = next;
+}
+
+static struct trailer_item *remove_first(struct trailer_item **first)
+{
+   struct trailer_item *item = *first;
+   *first = item->next;
+   if (item->next) {
+   item->next->previous = NULL;
+   item->next = NULL;
+   }
+   return item;
+}
+
+static void apply_arg_if_exists(struct trailer_item *in_tok,
+   struct trailer_item *arg_tok,
+   struct trailer_item *on_tok,
+   struct trailer_item **in_tok_first,
+   struct trailer_item **in_tok_last)
+{
+   switch (arg_tok->conf.if_exists) {
+   case EXISTS_DO_NOTHING:
+   free_trailer_item(arg_tok);
+   break;
+   case EXISTS_REPLACE:
+   add_arg_to_input_list(on_tok, arg_tok,
+ in_tok_first, in_tok_last);
+   remove_from_list(in_tok, in_tok_first, in_tok_last);
+   free_trailer_item(in_tok);
+   break;
+   case EXISTS_ADD:
+   add_arg_to_input_list(on_tok, arg_tok,
+ in_tok_first, in_tok_last);
+   break;
+   case EXISTS_ADD_IF_DIFFERENT:
+   if (check_if_different(in_tok, arg_tok, 1))
+   add_arg_to_input_list(on_tok, arg_tok,
+   

[PATCH v13 06/11] trailer: put all the processing together and print

2014-08-16 Thread Christian Couder
This patch adds the process_trailers() function that
calls all the previously added processing functions
and then prints the results on the standard output.

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 trailer.c | 81 +--
 trailer.h |  6 +
 2 files changed, 75 insertions(+), 12 deletions(-)
 create mode 100644 trailer.h

diff --git a/trailer.c b/trailer.c
index 46e2fcb..8e41b8f 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "string-list.h"
+#include "trailer.h"
 /*
  * Copyright (c) 2013, 2014 Christian Couder 
  */
@@ -82,6 +83,35 @@ static void free_trailer_item(struct trailer_item *item)
free(item);
 }
 
+static char last_non_space_char(const char *s)
+{
+   int i;
+   for (i = strlen(s) - 1; i >= 0; i--)
+   if (!isspace(s[i]))
+   return s[i];
+   return '\0';
+}
+
+static void print_tok_val(const char *tok, const char *val)
+{
+   char c = last_non_space_char(tok);
+   if (!c)
+   return;
+   if (strchr(separators, c))
+   printf("%s%s\n", tok, val);
+   else
+   printf("%s%c %s\n", tok, separators[0], val);
+}
+
+static void print_all(struct trailer_item *first, int trim_empty)
+{
+   struct trailer_item *item;
+   for (item = first; item; item = item->next) {
+   if (!trim_empty || strlen(item->value) > 0)
+   print_tok_val(item->token, item->value);
+   }
+}
+
 static void update_last(struct trailer_item **last)
 {
if (*last)
@@ -489,18 +519,6 @@ static int parse_trailer(struct strbuf *tok, struct strbuf 
*val, const char *tra
return 0;
 }
 
-
-static void duplicate_conf(struct conf_info *dst, struct conf_info *src)
-{
-   *dst = *src;
-   if (src->name)
-   dst->name = xstrdup(src->name);
-   if (src->key)
-   dst->key = xstrdup(src->key);
-   if (src->command)
-   dst->command = xstrdup(src->command);
-}
-
 static const char *token_from_item(struct trailer_item *item)
 {
if (item->conf.key)
@@ -705,3 +723,42 @@ static int process_input_file(struct strbuf **lines,
 
return patch_start;
 }
+
+static void free_all(struct trailer_item **first)
+{
+   while (*first) {
+   struct trailer_item *item = remove_first(first);
+   free_trailer_item(item);
+   }
+}
+
+void process_trailers(const char *file, int trim_empty, struct string_list 
*trailers)
+{
+   struct trailer_item *in_tok_first = NULL;
+   struct trailer_item *in_tok_last = NULL;
+   struct trailer_item *arg_tok_first;
+   struct strbuf **lines;
+   int patch_start;
+
+   /* Default config must be setup first */
+   git_config(git_trailer_default_config, NULL);
+   git_config(git_trailer_config, NULL);
+
+   lines = read_input_file(file);
+
+   /* Print the lines before the trailers */
+   patch_start = process_input_file(lines, &in_tok_first, &in_tok_last);
+
+   arg_tok_first = process_command_line_args(trailers);
+
+   process_trailers_lists(&in_tok_first, &in_tok_last, &arg_tok_first);
+
+   print_all(in_tok_first, trim_empty);
+
+   free_all(&in_tok_first);
+
+   /* Print the lines after the trailers as is */
+   print_lines(lines, patch_start, INT_MAX);
+
+   strbuf_list_free(lines);
+}
diff --git a/trailer.h b/trailer.h
new file mode 100644
index 000..8eb25d5
--- /dev/null
+++ b/trailer.h
@@ -0,0 +1,6 @@
+#ifndef TRAILER_H
+#define TRAILER_H
+
+void process_trailers(const char *file, int trim_empty, struct string_list 
*trailers);
+
+#endif /* TRAILER_H */
-- 
2.0.1.674.ga7f57b7


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 08/11] trailer: add tests for "git interpret-trailers"

2014-08-16 Thread Christian Couder
Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 t/t7513-interpret-trailers.sh | 726 ++
 1 file changed, 726 insertions(+)
 create mode 100755 t/t7513-interpret-trailers.sh

diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh
new file mode 100755
index 000..fa37565
--- /dev/null
+++ b/t/t7513-interpret-trailers.sh
@@ -0,0 +1,726 @@
+#!/bin/sh
+#
+# Copyright (c) 2013, 2014 Christian Couder
+#
+
+test_description='git interpret-trailers'
+
+. ./test-lib.sh
+
+# When we want one trailing space at the end of each line, let's use sed
+# to make sure that these spaces are not removed by any automatic tool.
+
+test_expect_success 'setup' '
+   : >empty &&
+   cat >basic_message <<-\EOF &&
+   subject
+
+   body
+   EOF
+   cat >complex_message_body <<-\EOF &&
+   my subject
+
+   my body which is long
+   and contains some special
+   chars like : = ? !
+
+   EOF
+   sed -e "s/ Z\$/ /" >complex_message_trailers <<-\EOF &&
+   Fixes: Z
+   Acked-by: Z
+   Reviewed-by: Z
+   Signed-off-by: Z
+   EOF
+   cat >basic_patch <<-\EOF
+   ---
+foo.txt | 2 +-
+1 file changed, 1 insertion(+), 1 deletion(-)
+
+   diff --git a/foo.txt b/foo.txt
+   index 0353767..1d91aa1 100644
+   --- a/foo.txt
+   +++ b/foo.txt
+   @@ -1,3 +1,3 @@
+
+   -bar
+   +baz
+
+   --
+   1.9.rc0.11.ga562ddc
+
+   EOF
+'
+
+test_expect_success 'without config' '
+   sed -e "s/ Z\$/ /" >expected <<-\EOF &&
+
+   ack: Peff
+   Reviewed-by: Z
+   Acked-by: Johan
+   EOF
+   git interpret-trailers --trailer "ack = Peff" --trailer "Reviewed-by" \
+   --trailer "Acked-by: Johan" empty >actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'without config in another order' '
+   sed -e "s/ Z\$/ /" >expected <<-\EOF &&
+
+   Acked-by: Johan
+   Reviewed-by: Z
+   ack: Peff
+   EOF
+   git interpret-trailers --trailer "Acked-by: Johan" --trailer 
"Reviewed-by" \
+   --trailer "ack = Peff" empty >actual &&
+   test_cmp expected actual
+'
+
+test_expect_success '--trim-empty without config' '
+   cat >expected <<-\EOF &&
+
+   ack: Peff
+   Acked-by: Johan
+   EOF
+   git interpret-trailers --trim-empty --trailer ack=Peff \
+   --trailer "Reviewed-by" --trailer "Acked-by: Johan" \
+   --trailer "sob:" empty >actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'with config setup' '
+   git config trailer.ack.key "Acked-by: " &&
+   cat >expected <<-\EOF &&
+
+   Acked-by: Peff
+   EOF
+   git interpret-trailers --trim-empty --trailer "ack = Peff" empty 
>actual &&
+   test_cmp expected actual &&
+   git interpret-trailers --trim-empty --trailer "Acked-by = Peff" empty 
>actual &&
+   test_cmp expected actual &&
+   git interpret-trailers --trim-empty --trailer "Acked-by :Peff" empty 
>actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'with config setup and ":=" as separators' '
+   git config trailer.separators ":=" &&
+   git config trailer.ack.key "Acked-by= " &&
+   cat >expected <<-\EOF &&
+
+   Acked-by= Peff
+   EOF
+   git interpret-trailers --trim-empty --trailer "ack = Peff" empty 
>actual &&
+   test_cmp expected actual &&
+   git interpret-trailers --trim-empty --trailer "Acked-by= Peff" empty 
>actual &&
+   test_cmp expected actual &&
+   git interpret-trailers --trim-empty --trailer "Acked-by : Peff" empty 
>actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'with config setup and "%" as separators' '
+   git config trailer.separators "%" &&
+   cat >expected <<-\EOF &&
+
+   bug% 42
+   count% 10
+   bug% 422
+   EOF
+   git interpret-trailers --trim-empty --trailer "bug = 42" \
+   --trailer count%10 --trailer "test: stuff" \
+   --trailer "bug % 422" empty >actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'with "%" as separators and a message with trailers' '
+   cat >special_message <<-\EOF &&
+   Special Message
+
+   bug% 42
+   count% 10
+   bug% 422
+   EOF
+   cat >expected <<-\EOF &&
+   Special Message
+
+   bug% 42
+   count% 10
+   bug% 422
+   count% 100
+   EOF
+   git interpret-trailers --trailer count%100 \
+   special_message >actual &&
+   test_cmp expected actual
+'

[PATCH v13 10/11] trailer: add tests for commands in config file

2014-08-16 Thread Christian Couder
And add a few other tests for some special cases.

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 t/t7513-interpret-trailers.sh | 124 ++
 1 file changed, 124 insertions(+)

diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh
index fa37565..562c00a 100755
--- a/t/t7513-interpret-trailers.sh
+++ b/t/t7513-interpret-trailers.sh
@@ -723,4 +723,128 @@ test_expect_success 'default "where" is now "after"' '
test_cmp expected actual
 '
 
+test_expect_success 'with simple command' '
+   git config trailer.sign.key "Signed-off-by: " &&
+   git config trailer.sign.where "after" &&
+   git config trailer.sign.ifExists "addIfDifferentNeighbor" &&
+   git config trailer.sign.command "echo \"A U Thor 
\"" &&
+   cat complex_message_body >expected &&
+   sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
+   Fixes: Z
+   Acked-by= Z
+   Reviewed-by:
+   Signed-off-by: Z
+   Signed-off-by: A U Thor 
+   EOF
+   git interpret-trailers --trailer "review:" --trailer "fix=22" \
+   actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'with command using commiter information' '
+   git config trailer.sign.ifExists "addIfDifferent" &&
+   git config trailer.sign.command "echo \"\$GIT_COMMITTER_NAME 
<\$GIT_COMMITTER_EMAIL>\"" &&
+   cat complex_message_body >expected &&
+   sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
+   Fixes: Z
+   Acked-by= Z
+   Reviewed-by:
+   Signed-off-by: Z
+   Signed-off-by: C O Mitter 
+   EOF
+   git interpret-trailers --trailer "review:" --trailer "fix=22" \
+   actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'with command using author information' '
+   git config trailer.sign.key "Signed-off-by: " &&
+   git config trailer.sign.where "after" &&
+   git config trailer.sign.ifExists "addIfDifferentNeighbor" &&
+   git config trailer.sign.command "echo \"\$GIT_AUTHOR_NAME 
<\$GIT_AUTHOR_EMAIL>\"" &&
+   cat complex_message_body >expected &&
+   sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
+   Fixes: Z
+   Acked-by= Z
+   Reviewed-by:
+   Signed-off-by: Z
+   Signed-off-by: A U Thor 
+   EOF
+   git interpret-trailers --trailer "review:" --trailer "fix=22" \
+   actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'setup a commit' '
+   echo "Content of the first commit." > a.txt &&
+   git add a.txt &&
+   git commit -m "Add file a.txt"
+'
+
+test_expect_success 'with command using $ARG' '
+   git config trailer.fix.ifExists "overwrite" &&
+   git config trailer.fix.command "git log -1 --oneline --format=\"%h 
(%s)\" --abbrev-commit --abbrev=14 \$ARG" &&
+   FIXED=$(git log -1 --oneline --format="%h (%s)" --abbrev-commit 
--abbrev=14 HEAD) &&
+   cat complex_message_body >expected &&
+   sed -e "s/ Z\$/ /" >>expected <<-EOF &&
+   Fixes: $FIXED
+   Acked-by= Z
+   Reviewed-by:
+   Signed-off-by: Z
+   Signed-off-by: A U Thor 
+   EOF
+   git interpret-trailers --trailer "review:" --trailer "fix=HEAD" \
+   actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'with failing command using $ARG' '
+   git config trailer.fix.ifExists "overwrite" &&
+   git config trailer.fix.command "false \$ARG" &&
+   cat complex_message_body >expected &&
+   sed -e "s/ Z\$/ /" >>expected <<-EOF &&
+   Fixes: Z
+   Acked-by= Z
+   Reviewed-by:
+   Signed-off-by: Z
+   Signed-off-by: A U Thor 
+   EOF
+   git interpret-trailers --trailer "review:" --trailer "fix=HEAD" \
+   actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'with empty tokens' '
+   cat >expected <<-EOF &&
+
+   Signed-off-by: A U Thor 
+   EOF
+   git interpret-trailers --trailer ":" --trailer ":test" >actual <<-EOF &&
+   EOF
+   test_cmp expected actual
+'
+
+test_expect_success 'with command but no key' '
+   git config --unset trailer.sign.key &&
+   cat >expected <<-EOF &&
+
+   sign: A U Thor 
+   EOF
+   git interpret-trailers >actual <<-EOF &&
+   EOF
+   test_cmp expected actual
+'
+
+test_expect_success 'with no command and no key' '
+   git config --unset trailer.review.key &&
+   cat >expected <<-EOF &&
+
+   review: Junio
+   sign: A U Thor 
+   EOF
+   git interpret-trailers --trailer "review:Junio" >actual <<-EOF &&
+   EOF
+   test_cmp expected actual
+'
+
 test_done
-- 
2.0.1.674.ga7f57b7


--
To unsubscribe from this list: send the line "unsubscribe git" in
th

[PATCH v13 11/11] Documentation: add documentation for 'git interpret-trailers'

2014-08-16 Thread Christian Couder
While at it add git-interpret-trailers to "command-list.txt".

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 Documentation/git-interpret-trailers.txt | 308 +++
 command-list.txt |   1 +
 2 files changed, 309 insertions(+)
 create mode 100644 Documentation/git-interpret-trailers.txt

diff --git a/Documentation/git-interpret-trailers.txt 
b/Documentation/git-interpret-trailers.txt
new file mode 100644
index 000..cf5b194
--- /dev/null
+++ b/Documentation/git-interpret-trailers.txt
@@ -0,0 +1,308 @@
+git-interpret-trailers(1)
+=
+
+NAME
+
+git-interpret-trailers - help add stuctured information into commit messages
+
+SYNOPSIS
+
+[verse]
+'git interpret-trailers' [--trim-empty] [(--trailer [(=|:)])...] 
[...]
+
+DESCRIPTION
+---
+Help adding 'trailers' lines, that look similar to RFC 822 e-mail
+headers, at the end of the otherwise free-form part of a commit
+message.
+
+This command reads some patches or commit messages from either the
+ arguments or the standard input if no  is specified. Then
+this command applies the arguments passed using the `--trailer`
+option, if any, to the commit message part of each input file. The
+result is emitted on the standard output.
+
+Some configuration variables control the way the `--trailer` arguments
+are applied to each commit message and the way any existing trailer in
+the commit message is changed. They also make it possible to
+automatically add some trailers.
+
+By default, a '=' or ':' argument given
+using `--trailer` will be appended after the existing trailers only if
+the last trailer has a different (, ) pair (or if there
+is no existing trailer). The  and  parts will be trimmed
+to remove starting and trailing whitespace, and the resulting trimmed
+ and  will appear in the message like this:
+
+
+token: value
+
+
+This means that the trimmed  and  will be separated by
+`': '` (one colon followed by one space).
+
+By default the new trailer will appear at the end of all the existing
+trailers. If there is no existing trailer, the new trailer will appear
+after the commit message part of the ouput, and, if there is no line
+with only spaces at the end of the commit message part, one blank line
+will be added before the new trailer.
+
+The trailers are recognized in the input message using the following
+rules:
+
+* by default only lines that contains a ':' (colon) are considered
+  trailers,
+
+* the trailer lines must all be next to each other,
+
+* after them it's only possible to have some lines that contain only
+  spaces, and then a patch; the patch part is recognized using the
+  fact that its first line starts with '---' (three minus signs),
+
+* before them there must be at least one line with only spaces.
+
+Note that 'trailers' do not follow and are not intended to follow many
+rules for RFC 822 headers. For example they do not follow the line
+folding rules, the encoding rules and probably many other rules.
+
+OPTIONS
+---
+--trim-empty::
+   If the  part of any trailer contains only whitespace,
+   the whole trailer will be removed from the resulting message.
+   This apply to existing trailers as well as new trailers.
+
+--trailer [(=|:)]::
+   Specify a (, ) pair that should be applied as a
+   trailer to the input messages. See the description of this
+   command.
+
+CONFIGURATION VARIABLES
+---
+
+trailer.separators::
+   This option tells which characters are recognized as trailer
+   separators. By default only ':' is recognized as a trailer
+   separator, except that '=' is always accepted on the command
+   line for compatibility with other git commands.
++
+The first character given by this option will be the default character
+used when another separator is not specified in the config for this
+trailer.
++
+For example, if the value for this option is "%=$", then only lines
+using the format '' with  containing '%', '='
+or '$' and then spaces will be considered trailers. And '%' will be
+the default separator used, so by default trailers will appear like:
+'% ' (one percent sign and one space will appear between
+the token and the value).
+
+trailer.where::
+   This option tells where a new trailer will be added.
++
+This can be `end`, which is the default, `start`, `after` or `before`.
++
+If it is `end`, then each new trailer will appear at the end of the
+existing trailers.
++
+If it is `start`, then each new trailer will appear at the start,
+instead of the end, of the existing trailers.
++
+If it is `after`, then each new trailer will appear just after the
+last trailer with the same .
++
+If it is `before`, then each new trailer will appear just before the
+last trailer with the same .
+
+trailer.ifexists::
+   This option makes it possible to c

[PATCH v13 07/11] trailer: add interpret-trailers command

2014-08-16 Thread Christian Couder
This patch adds the "git interpret-trailers" command.
This command uses the previously added process_trailers()
function in trailer.c.

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 .gitignore   |  1 +
 Makefile |  1 +
 builtin.h|  1 +
 builtin/interpret-trailers.c | 44 
 git.c|  1 +
 5 files changed, 48 insertions(+)
 create mode 100644 builtin/interpret-trailers.c

diff --git a/.gitignore b/.gitignore
index cf0d191..85593de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,6 +74,7 @@
 /git-index-pack
 /git-init
 /git-init-db
+/git-interpret-trailers
 /git-instaweb
 /git-log
 /git-ls-files
diff --git a/Makefile b/Makefile
index ef82972..0b06ae0 100644
--- a/Makefile
+++ b/Makefile
@@ -953,6 +953,7 @@ BUILTIN_OBJS += builtin/hash-object.o
 BUILTIN_OBJS += builtin/help.o
 BUILTIN_OBJS += builtin/index-pack.o
 BUILTIN_OBJS += builtin/init-db.o
+BUILTIN_OBJS += builtin/interpret-trailers.o
 BUILTIN_OBJS += builtin/log.o
 BUILTIN_OBJS += builtin/ls-files.o
 BUILTIN_OBJS += builtin/ls-remote.o
diff --git a/builtin.h b/builtin.h
index 5d91f31..b87df70 100644
--- a/builtin.h
+++ b/builtin.h
@@ -73,6 +73,7 @@ extern int cmd_hash_object(int argc, const char **argv, const 
char *prefix);
 extern int cmd_help(int argc, const char **argv, const char *prefix);
 extern int cmd_index_pack(int argc, const char **argv, const char *prefix);
 extern int cmd_init_db(int argc, const char **argv, const char *prefix);
+extern int cmd_interpret_trailers(int argc, const char **argv, const char 
*prefix);
 extern int cmd_log(int argc, const char **argv, const char *prefix);
 extern int cmd_log_reflog(int argc, const char **argv, const char *prefix);
 extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c
new file mode 100644
index 000..46838d2
--- /dev/null
+++ b/builtin/interpret-trailers.c
@@ -0,0 +1,44 @@
+/*
+ * Builtin "git interpret-trailers"
+ *
+ * Copyright (c) 2013, 2014 Christian Couder 
+ *
+ */
+
+#include "cache.h"
+#include "builtin.h"
+#include "parse-options.h"
+#include "string-list.h"
+#include "trailer.h"
+
+static const char * const git_interpret_trailers_usage[] = {
+   N_("git interpret-trailers [--trim-empty] [(--trailer 
[(=|:)])...] [...]"),
+   NULL
+};
+
+int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)
+{
+   int trim_empty = 0;
+   struct string_list trailers = STRING_LIST_INIT_DUP;
+
+   struct option options[] = {
+   OPT_BOOL(0, "trim-empty", &trim_empty, N_("trim empty 
trailers")),
+   OPT_STRING_LIST(0, "trailer", &trailers, N_("trailer"),
+   N_("trailer(s) to add")),
+   OPT_END()
+   };
+
+   argc = parse_options(argc, argv, prefix, options,
+git_interpret_trailers_usage, 0);
+
+   if (argc) {
+   int i;
+   for (i = 0; i < argc; i++)
+   process_trailers(argv[i], trim_empty, &trailers);
+   } else
+   process_trailers(NULL, trim_empty, &trailers);
+
+   string_list_clear(&trailers, 0);
+
+   return 0;
+}
diff --git a/git.c b/git.c
index 5ebb32f..e327a90 100644
--- a/git.c
+++ b/git.c
@@ -417,6 +417,7 @@ static struct cmd_struct commands[] = {
{ "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
{ "init", cmd_init_db, NO_SETUP },
{ "init-db", cmd_init_db, NO_SETUP },
+   { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP },
{ "log", cmd_log, RUN_SETUP },
{ "ls-files", cmd_ls_files, RUN_SETUP },
{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
-- 
2.0.1.674.ga7f57b7


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 09/11] trailer: execute command from 'trailer..command'

2014-08-16 Thread Christian Couder
Let the user specify a command that will give on its standard output
the value to use for the specified trailer.

Signed-off-by: Christian Couder 
Signed-off-by: Junio C Hamano 
---
 trailer.c | 66 +++
 1 file changed, 66 insertions(+)

diff --git a/trailer.c b/trailer.c
index 8e41b8f..baef034 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1,5 +1,7 @@
 #include "cache.h"
 #include "string-list.h"
+#include "run-command.h"
+#include "string-list.h"
 #include "trailer.h"
 /*
  * Copyright (c) 2013, 2014 Christian Couder 
@@ -14,6 +16,7 @@ struct conf_info {
char *name;
char *key;
char *command;
+   unsigned command_uses_arg : 1;
enum action_where where;
enum action_if_exists if_exists;
enum action_if_missing if_missing;
@@ -33,6 +36,8 @@ static struct trailer_item *first_conf_item;
 
 static char *separators = ":";
 
+#define TRAILER_ARG_STRING "$ARG"
+
 static int after_or_end(enum action_where where)
 {
return (where == WHERE_AFTER) || (where == WHERE_END);
@@ -73,6 +78,13 @@ static inline int contains_only_spaces(const char *str)
return !*s;
 }
 
+static inline void strbuf_replace(struct strbuf *sb, const char *a, const char 
*b)
+{
+   const char *ptr = strstr(sb->buf, a);
+   if (ptr)
+   strbuf_splice(sb, ptr - sb->buf, strlen(a), b, strlen(b));
+}
+
 static void free_trailer_item(struct trailer_item *item)
 {
free(item->conf.name);
@@ -478,6 +490,7 @@ static int git_trailer_config(const char *conf_key, const 
char *value, void *cb)
if (conf->command)
warning(_("more than one %s"), conf_key);
conf->command = xstrdup(value);
+   conf->command_uses_arg = !!strstr(conf->command, 
TRAILER_ARG_STRING);
break;
case TRAILER_WHERE:
if (set_where(conf, value))
@@ -519,6 +532,46 @@ static int parse_trailer(struct strbuf *tok, struct strbuf 
*val, const char *tra
return 0;
 }
 
+static int read_from_command(struct child_process *cp, struct strbuf *buf)
+{
+   if (run_command(cp))
+   return error("running trailer command '%s' failed", 
cp->argv[0]);
+   if (strbuf_read(buf, cp->out, 1024) < 1)
+   return error("reading from trailer command '%s' failed", 
cp->argv[0]);
+   strbuf_trim(buf);
+   return 0;
+}
+
+static const char *apply_command(const char *command, const char *arg)
+{
+   struct strbuf cmd = STRBUF_INIT;
+   struct strbuf buf = STRBUF_INIT;
+   struct child_process cp;
+   const char *argv[] = {NULL, NULL};
+   const char *result;
+
+   strbuf_addstr(&cmd, command);
+   if (arg)
+   strbuf_replace(&cmd, TRAILER_ARG_STRING, arg);
+
+   argv[0] = cmd.buf;
+   memset(&cp, 0, sizeof(cp));
+   cp.argv = argv;
+   cp.env = local_repo_env;
+   cp.no_stdin = 1;
+   cp.out = -1;
+   cp.use_shell = 1;
+
+   if (read_from_command(&cp, &buf)) {
+   strbuf_release(&buf);
+   result = xstrdup("");
+   } else
+   result = strbuf_detach(&buf, NULL);
+
+   strbuf_release(&cmd);
+   return result;
+}
+
 static const char *token_from_item(struct trailer_item *item)
 {
if (item->conf.key)
@@ -537,6 +590,10 @@ static struct trailer_item *new_trailer_item(struct 
trailer_item *conf_item,
duplicate_conf(&new->conf, &conf_item->conf);
new->token = xstrdup(token_from_item(conf_item));
free(tok);
+   if (conf_item->conf.command_uses_arg || !val) {
+   new->value = apply_command(conf_item->conf.command, 
val);
+   free(val);
+   }
} else {
duplicate_conf(&new->conf, &default_conf_info);
new->token = tok;
@@ -600,12 +657,21 @@ static struct trailer_item 
*process_command_line_args(struct string_list *traile
struct trailer_item *arg_tok_first = NULL;
struct trailer_item *arg_tok_last = NULL;
struct string_list_item *tr;
+   struct trailer_item *item;
 
for_each_string_list_item(tr, trailers) {
struct trailer_item *new = create_trailer_item(tr->string);
add_trailer_item(&arg_tok_first, &arg_tok_last, new);
}
 
+   /* Add conf commands that don't use $ARG */
+   for (item = first_conf_item; item; item = item->next) {
+   if (item->conf.command && !item->conf.command_uses_arg) {
+   struct trailer_item *new = new_trailer_item(item, NULL, 
NULL);
+   add_trailer_item(&arg_tok_first, &arg_tok_last, new);
+   }
+   }
+
return arg_tok_first;
 }
 
-- 
2.0.1.674.ga7f57b7


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordo

Re: [PATCH v2 2/2] convert: Stream from fd to required clean filter instead of mmap

2014-08-16 Thread Andreas Schwab
Steffen Prohaska  writes:

> The test should confirm that the the file that is added is not mmapped to
> memory.

RSS doesn't tell you that.  You can mmap a big file without RSS getting
bigger.

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 03/10] setup: convert setup_git_directory_gently_1 et al. to strbuf

2014-08-16 Thread Torsten Bögershausen
On 2014-07-28 20.26, René Scharfe wrote:
> Convert setup_git_directory_gently_1() and its helper functions
> setup_explicit_git_dir(), setup_discovered_git_dir() and
> setup_bare_git_dir() to use a struct strbuf to hold the current working
> directory.  Replacing the PATH_MAX-sized buffer used before removes a
> path length limition on some file systems.  The functions are converted
> all in one go because they all read and write the variable cwd.
> 
> Signed-off-by: Rene Scharfe 
> ---
>  setup.c | 85 
> +
>  1 file changed, 43 insertions(+), 42 deletions(-)
> 
> diff --git a/setup.c b/setup.c
> index 0a22f8b..c8b8a97 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -387,7 +387,7 @@ const char *read_gitfile(const char *path)
>  }
>  
>  static const char *setup_explicit_git_dir(const char *gitdirenv,
> -   char *cwd, int len,
> +   struct strbuf *cwd,
> int *nongit_ok)
>  {
>   const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
> @@ -441,7 +441,7 @@ static const char *setup_explicit_git_dir(const char 
> *gitdirenv,
>   die_errno("Could not chdir to '%s'", 
> git_work_tree_cfg);
>   if (!getcwd(core_worktree, PATH_MAX))
>   die_errno("Could not get directory '%s'", 
> git_work_tree_cfg);
> - if (chdir(cwd))
> + if (chdir(cwd->buf))
>   die_errno("Could not come back to cwd");
>   set_git_work_tree(core_worktree);
>   }
> @@ -459,21 +459,20 @@ static const char *setup_explicit_git_dir(const char 
> *gitdirenv,
>   worktree = get_git_work_tree();
>  
>   /* both get_git_work_tree() and cwd are already normalized */
> - if (!strcmp(cwd, worktree)) { /* cwd == worktree */
> + if (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */
>   set_git_dir(gitdirenv);
>   free(gitfile);
>   return NULL;
>   }
>  
> - offset = dir_inside_of(cwd, worktree);
> + offset = dir_inside_of(cwd->buf, worktree);
>   if (offset >= 0) {  /* cwd inside worktree? */
>   set_git_dir(real_path(gitdirenv));
>   if (chdir(worktree))
>   die_errno("Could not chdir to '%s'", worktree);
> - cwd[len++] = '/';
> - cwd[len] = '\0';
> + strbuf_addch(cwd, '/');
>   free(gitfile);
> - return cwd + offset;
> + return cwd->buf + offset;
>   }
>  
>   /* cwd outside worktree */
> @@ -483,7 +482,7 @@ static const char *setup_explicit_git_dir(const char 
> *gitdirenv,
>  }
>  
>  static const char *setup_discovered_git_dir(const char *gitdir,
> - char *cwd, int offset, int len,
> + struct strbuf *cwd, int offset,
>   int *nongit_ok)
>  {
>   if (check_repository_format_gently(gitdir, nongit_ok))
> @@ -491,17 +490,17 @@ static const char *setup_discovered_git_dir(const char 
> *gitdir,
>  
>   /* --work-tree is set without --git-dir; use discovered one */
>   if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
> - if (offset != len && !is_absolute_path(gitdir))
> + if (offset != cwd->len && !is_absolute_path(gitdir))
>   gitdir = xstrdup(real_path(gitdir));
> - if (chdir(cwd))
> + if (chdir(cwd->buf))
>   die_errno("Could not come back to cwd");
> - return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok);
> + return setup_explicit_git_dir(gitdir, cwd, nongit_ok);
>   }
>  
>   /* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
>   if (is_bare_repository_cfg > 0) {
> - set_git_dir(offset == len ? gitdir : real_path(gitdir));
> - if (chdir(cwd))
> + set_git_dir(offset == cwd->len ? gitdir : real_path(gitdir));
> + if (chdir(cwd->buf))
>   die_errno("Could not come back to cwd");
>   return NULL;
>   }
> @@ -512,18 +511,18 @@ static const char *setup_discovered_git_dir(const char 
> *gitdir,
>   set_git_dir(gitdir);
>   inside_git_dir = 0;
>   inside_work_tree = 1;
> - if (offset == len)
> + if (offset == cwd->len)
>   return NULL;
>  
>   /* Make "offset" point to past the '/', and add a '/' at the end */
>   offset++;
> - cwd[len++] = '/';
> - cwd[len] = 0;
> - return cwd + offset;
> + strbuf_addch(cwd, '/');
> + return cwd->buf + offset;
>  }
>  
>  /* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */
> -static const char *setup_bare_git_dir(char *cwd, int offset, int len, int

[PATCH 2/2] Push the Makefile variable NATIVE_CRLF to C

2014-08-16 Thread Torsten Bögershausen
Re-do the fix in 757543ae0c5d8d:
Propagate the Makefile variable NATIVE_CRLF to the C preprocessor

Signed-off-by: Torsten Bögershausen 
---
 Makefile | 4 
 1 file changed, 4 insertions(+)

diff --git a/Makefile b/Makefile
index 63a210d..00ba537 100644
--- a/Makefile
+++ b/Makefile
@@ -1482,6 +1482,10 @@ ifdef NO_REGEX
COMPAT_OBJS += compat/regex/regex.o
 endif
 
+ifdef NATIVE_CRLF
+   BASIC_CFLAGS += -DNATIVE_CRLF
+endif
+
 ifdef USE_NED_ALLOCATOR
COMPAT_CFLAGS += -Icompat/nedmalloc
COMPAT_OBJS += compat/nedmalloc/nedmalloc.o
-- 
2.1.0.rc2.210.g636bceb

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] t0027: Tests for core.eol=native, eol=lf, eol=crlf

2014-08-16 Thread Torsten Bögershausen
Add test cases for core.eol "native" and "" (unset).
(MINGW uses CRLF, all other systems LF as native line endings)

Add test cases for the attributes "eol=lf" and "eol=crlf"

Other minor changes:
- Use the more portable 'tr' instead of 'od -c' to convert '\n' into 'Q'
  and '\0' into 'N'
- Style fixes for shell functions according to the coding guide lines
- Replace "txtbin" with "attr"

Signed-off-by: Torsten Bögershausen 
---
 t/t0027-auto-crlf.sh | 220 ---
 1 file changed, 120 insertions(+), 100 deletions(-)

diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index 72dd3e8..2a4a6c1 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -10,30 +10,26 @@ then
test_done
 fi
 
-
-compare_files()
-{
-   od -c <"$1" >"$1".expect &&
-   od -c <"$2" >"$2".actual &&
+compare_files () {
+   tr '\015\000' QN <"$1" >"$1".expect &&
+   tr '\015\000' QN <"$2" >"$2".actual &&
test_cmp "$1".expect "$2".actual &&
rm "$1".expect "$2".actual
 }
 
-compare_ws_file()
-{
+compare_ws_file () {
pfx=$1
exp=$2.expect
act=$pfx.actual.$3
-   od -c <"$2" >"$exp" &&
-   od -c <"$3" >"$act" &&
+   tr '\015\000' QN <"$2" >"$exp" &&
+   tr '\015\000' QN <"$3" >"$act" &&
test_cmp $exp $act &&
rm $exp $act
 }
 
-create_gitattributes()
-{
-   txtbin=$1
-   case "$txtbin" in
+create_gitattributes () {
+   attr=$1
+   case "$attr" in
auto)
echo "*.txt text=auto" >.gitattributes
;;
@@ -43,35 +39,43 @@ create_gitattributes()
-text)
echo "*.txt -text" >.gitattributes
;;
-   *)
+   crlf)
+   echo "*.txt eol=crlf" >.gitattributes
+   ;;
+   lf)
+   echo "*.txt eol=lf" >.gitattributes
+   ;;
+   "")
echo >.gitattributes
;;
+   *)
+   echo >&2 invalid attribute: $attr
+   exit 1
+   ;;
esac
 }
 
-create_file_in_repo()
-{
+create_file_in_repo () {
crlf=$1
-   txtbin=$2
-   create_gitattributes "$txtbin" &&
+   attr=$2
+   create_gitattributes "$attr" &&
for f in LF CRLF LF_mix_CR CRLF_mix_LF CRLF_nul
do
-   pfx=crlf_${crlf}_attr_${txtbin}_$f.txt &&
+   pfx=crlf_${crlf}_attr_${attr}_$f.txt &&
cp $f $pfx && git -c core.autocrlf=$crlf add $pfx
done &&
git commit -m "core.autocrlf $crlf"
 }
 
-check_files_in_repo()
-{
+check_files_in_repo () {
crlf=$1
-   txtbin=$2
+   attr=$2
lfname=$3
crlfname=$4
lfmixcrlf=$5
lfmixcr=$6
crlfnul=$7
-   pfx=crlf_${crlf}_attr_${txtbin}_ &&
+   pfx=crlf_${crlf}_attr_${attr}_ &&
compare_files $lfname ${pfx}LF.txt &&
compare_files $crlfname ${pfx}CRLF.txt &&
compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt &&
@@ -80,19 +84,18 @@ check_files_in_repo()
 }
 
 
-check_files_in_ws()
-{
+check_files_in_ws () {
eol=$1
crlf=$2
-   txtbin=$3
+   attr=$3
lfname=$4
crlfname=$5
lfmixcrlf=$6
lfmixcr=$7
crlfnul=$8
-   create_gitattributes $txtbin &&
+   create_gitattributes $attr &&
git config core.autocrlf $crlf &&
-   pfx=eol_${eol}_crlf_${crlf}_attr_${txtbin}_ &&
+   pfx=eol_${eol}_crlf_${crlf}_attr_${attr}_ &&
src=crlf_false_attr__ &&
for f in LF CRLF LF_mix_CR CRLF_mix_LF CRLF_nul
do
@@ -104,42 +107,24 @@ check_files_in_ws()
fi
done
 
-
-   test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf 
gitattributes=$txtbin file=LF" "
+   test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf 
gitattributes=$attr file=LF" "
compare_ws_file $pfx $lfname${src}LF.txt
"
-   test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf 
gitattributes=$txtbin file=CRLF" "
+   test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf 
gitattributes=$attr file=CRLF" "
compare_ws_file $pfx $crlfname  ${src}CRLF.txt
"
-   test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf 
gitattributes=$txtbin file=CRLF_mix_LF" "
+   test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf 
gitattributes=$attr file=CRLF_mix_LF" "
compare_ws_file $pfx $lfmixcrlf ${src}CRLF_mix_LF.txt
"
-   test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf 
gitattributes=$txtbin file=LF_mix_CR" "
+   test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf 
gitattributes=$attr file=LF_mix_CR" "
compare_ws_file $pfx $lfmixcr   ${src}LF_mix_CR.txt
"
-   test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf 
gitattrib

t5534 broken when gpg not installed

2014-08-16 Thread Torsten Bögershausen
(I couldn't find a post for this patch)
The following is needed for systems without gpg to make t5534 pass:



diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh
index 3acc864..ee5aaff 100755
--- a/t/t5534-push-signed.sh
+++ b/t/t5534-push-signed.sh
@@ -45,7 +45,7 @@ test_expect_success 'unsigned push does not send push 
certificate' '
! test -s dst/push-cert
 '
 
-test_expect_success 'signed push sends push certificate' '
+test_expect_success GPG 'signed push sends push certificate' '
prepare_dst &&
mkdir -p dst/.git/hooks &&
write_script dst/.git/hooks/post-receive <<-\EOF &&
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 03/10] setup: convert setup_git_directory_gently_1 et al. to strbuf

2014-08-16 Thread René Scharfe
> Is there a chance to squueze this in:
> 
> 
> $ git diff
> diff --git a/setup.c b/setup.c
> index 526cdf6..fb61860 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -734,7 +734,7 @@ static const char *setup_git_directory_gently_1(int 
> *nongit_ok)
>  string_list_clear(&ceiling_dirs, 0);
>  }
> 
> -   if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
> +   if (ceil_offset < 0 && has_dos_drive_prefix(cwd.buf))
>  ceil_offset = 1;
> 
> 

Ouch, thanks for catching this.

Perhaps the following patch should go in as well.

-- >8 --
Subject: [PATCH] turn path macros into inline function

Use static inline functions instead of macros for has_dos_drive_prefix,
offset_1st_component, is_dir_sep and find_last_dir_sep in order to let
the compiler do type checking.

The definitions of offset_1st_component and is_dir_sep are switched
around because the former uses the latter.

Signed-off-by: Rene Scharfe 
---
 git-compat-util.h | 28 ++--
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/git-compat-util.h b/git-compat-util.h
index f587749..0b6c13a 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -264,19 +264,35 @@ extern char *gitbasename(char *);
 #endif
 
 #ifndef has_dos_drive_prefix
-#define has_dos_drive_prefix(path) 0
+static inline int git_has_dos_drive_prefix(const char *path)
+{
+   return 0;
+}
+#define has_dos_drive_prefix git_has_dos_drive_prefix
 #endif
 
-#ifndef offset_1st_component
-#define offset_1st_component(path) (is_dir_sep((path)[0]))
+#ifndef is_dir_sep
+static inline int git_is_dir_sep(int c)
+{
+   return c == '/';
+}
+#define is_dir_sep git_is_dir_sep
 #endif
 
-#ifndef is_dir_sep
-#define is_dir_sep(c) ((c) == '/')
+#ifndef offset_1st_component
+static inline int git_offset_1st_component(const char *path)
+{
+   return is_dir_sep(path[0]);
+}
+#define offset_1st_component git_offset_1st_component
 #endif
 
 #ifndef find_last_dir_sep
-#define find_last_dir_sep(path) strrchr(path, '/')
+static inline char *git_find_last_dir_sep(const char *path)
+{
+   return strrchr(path, '/');
+}
+#define find_last_dir_sep git_find_last_dir_sep
 #endif
 
 #if defined(__HP_cc) && (__HP_cc >= 61000)
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v13 00/11] Add interpret-trailers builtin

2014-08-16 Thread Christian Couder
On Sat, Aug 16, 2014 at 6:06 PM, Christian Couder
 wrote:
>
> 3) Changes since version 12, thanks to Jakub, Michael, Johan and Junio:
>
> * "end" and "start" values for "trailer..where" have been
>   implemented
> * "end" has been made the default value for "where", but this default
>   value can be changed using the new "trailer.where" config
>   variable
> * "addIfDifferentNeighbor" is now the default value for "ifexists",
>   but this default can be changed using the new "trailer.ifexists"
>   config variable
> * the new "trailer.ifmissing" can be used to change the default value
>   for "ifmissing" (which is "add")
> * by default the only separator is ':', this can be changed by using
>   the new "trailer.separators" config variable
> * only the configured separators (or just ':' by default) are used for
>   both input parsing and output printing; the only exception is that
>   '=' is always accepted as separator when parsing
>   "--trailer ''" command line arguments, for
>   compatibility with other git commands
> * 14 tests have been added

I forgot the following change:

* "overwrite" value for "ifexists" option has been replaced with
  "replace" value; when used with "where = after" or
  "where = before", "replace" does the same thing as "overwrite"
  did; but when used with "where = end" or "where = start", the
  new trailer appears at the end or the start of the existing trailers,
  instead of where the replaced trailer was
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] run-command: introduce CHILD_PROCESS_INIT

2014-08-16 Thread René Scharfe
Most struct child_process variables are cleared using memset right after
declaration.  Provide a macro, CHILD_PROCESS_INIT, that can be used to
initialize them statically instead.  That's shorter, doesn't require a
function call and is slightly more readable (especially given that we
already have similar macros like STRBUF_INIT, ARGV_ARRAY_INIT etc.).

Signed-off-by: Rene Scharfe 
---
 Documentation/technical/api-run-command.txt |  4 ++--
 archive-tar.c   |  3 +--
 builtin/add.c   |  3 +--
 builtin/commit.c|  3 +--
 builtin/help.c  |  3 +--
 builtin/merge.c |  3 +--
 builtin/notes.c |  3 +--
 builtin/remote-ext.c|  3 +--
 builtin/repack.c|  3 +--
 builtin/replace.c   |  4 ++--
 builtin/verify-pack.c   |  3 +--
 bundle.c|  6 ++
 connected.c |  3 +--
 convert.c   |  3 +--
 credential-cache.c  |  3 +--
 credential.c|  3 +--
 daemon.c|  8 +++-
 diff.c  |  3 +--
 editor.c|  3 +--
 fetch-pack.c|  3 +--
 gpg-interface.c |  6 ++
 http-backend.c  |  3 +--
 http.c  |  3 +--
 imap-send.c |  2 +-
 prompt.c|  3 +--
 remote-curl.c   |  3 +--
 remote-testsvn.c|  3 +--
 run-command.h   |  2 ++
 send-pack.c |  3 +--
 submodule.c | 21 +++--
 test-run-command.c  |  4 +---
 test-subprocess.c   |  3 +--
 transport.c | 12 
 upload-pack.c   |  3 +--
 wt-status.c |  3 +--
 35 files changed, 51 insertions(+), 93 deletions(-)

diff --git a/Documentation/technical/api-run-command.txt 
b/Documentation/technical/api-run-command.txt
index 69510ae..ca066bf 100644
--- a/Documentation/technical/api-run-command.txt
+++ b/Documentation/technical/api-run-command.txt
@@ -96,8 +96,8 @@ command to run in a sub-process.
 
 The caller:
 
-1. allocates and clears (memset(&chld, 0, sizeof(chld));) a
-   struct child_process variable;
+1. allocates and clears (memset(&chld, 0, sizeof(chld)); or
+   using CHILD_PROCESS_INIT) a struct child_process variable;
 2. initializes the members;
 3. calls start_command();
 4. processes the data;
diff --git a/archive-tar.c b/archive-tar.c
index 719b629..0d1e6bd 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -395,7 +395,7 @@ static int write_tar_filter_archive(const struct archiver 
*ar,
struct archiver_args *args)
 {
struct strbuf cmd = STRBUF_INIT;
-   struct child_process filter;
+   struct child_process filter = CHILD_PROCESS_INIT;
const char *argv[2];
int r;
 
@@ -406,7 +406,6 @@ static int write_tar_filter_archive(const struct archiver 
*ar,
if (args->compression_level >= 0)
strbuf_addf(&cmd, " -%d", args->compression_level);
 
-   memset(&filter, 0, sizeof(filter));
argv[0] = cmd.buf;
argv[1] = NULL;
filter.argv = argv;
diff --git a/builtin/add.c b/builtin/add.c
index 4baf3a5..352b85e 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -180,7 +180,7 @@ static int edit_patch(int argc, const char **argv, const 
char *prefix)
char *file = git_pathdup("ADD_EDIT.patch");
const char *apply_argv[] = { "apply", "--recount", "--cached",
NULL, NULL };
-   struct child_process child;
+   struct child_process child = CHILD_PROCESS_INIT;
struct rev_info rev;
int out;
struct stat st;
@@ -214,7 +214,6 @@ static int edit_patch(int argc, const char **argv, const 
char *prefix)
if (!st.st_size)
die(_("Empty patch. Aborted."));
 
-   memset(&child, 0, sizeof(child));
child.git_cmd = 1;
child.argv = apply_argv;
if (run_command(&child))
diff --git a/builtin/commit.c b/builtin/commit.c
index 5ed6036..b8b8663 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1508,7 +1508,7 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
 {
/* oldsha1 SP newsha1 LF NUL */
static char buf[2*40 + 3];
-   struct child_process proc;
+   struct child_process proc = CHILD_PROCESS_INIT;
const char *argv[3];
int code;
size_t n

Feature Request: `git remote prune --all`

2014-08-16 Thread Travis Carden
I would like to propose the addition of a `git remote prune --all`
command option or similar mechanism for pruning all remotes in a
repository. For lack of such a feature, I've been using the following
bash alias:

alias git-remote-prune-all='for REMOTE in `git remote`; do echo
"Pruning $REMOTE"; git remote prune $REMOTE; done;'
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Running make in contrib/subtree does not create executable

2014-08-16 Thread Jack Nagel
Running "make" in contrib/subtree no longer creates the git-subtree executable:

$ git describe
v2.1.0
$ make -C contrib/subtree
/Library/Developer/CommandLineTools/usr/bin/make -C ../../ GIT-VERSION-FILE
GIT_VERSION = 2.1.0
make[1]: `GIT-VERSION-FILE' is up to date.
/Library/Developer/CommandLineTools/usr/bin/make -C ../../ GIT-VERSION-FILE
make[1]: `GIT-VERSION-FILE' is up to date.
make: `../../GIT-VERSION-FILE' is up to date.
$ ls contrib/subtree/git-subtree
ls: contrib/subtree/git-subtree: No such file or directory

The change appears to be inadvertent. I bisected it to
8e2a5ccad11bc21eb72499133bc884024e299983 ("contrib/subtree/Makefile:
use GIT-VERSION-FILE").

This was reproduced on OS X 10.9 with GNU make 3.81.

-Jack
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html