Re: [PATCH 1/8] tag: Remove a TODO item from the test suite

2017-03-18 Thread Jakub Narębski
W dniu 18.03.2017 o 11:32, Ævar Arnfjörð Bjarmason pisze:

> @@ -136,7 +135,6 @@ test_expect_success \
>   'listing a tag using a matching pattern should output that tag' \
>   'test $(git tag -l mytag) = mytag'
>  
> -# todo: git tag -l now returns always zero, when fixed, change this test
>  test_expect_success \
>   'listing tags using a non-matching pattern should suceed' \
>   'git tag -l xxx'

Could you fix s/suceed/succeed/ in the test description,
while at it?

-- 
Jakub Narębski



Re: Is there a way to have a local version of a header file?

2017-03-18 Thread David Lang

On Sat, 18 Mar 2017, Junio C Hamano wrote:


David Lang  writes:


Ship a config.h.sample file, have a Makefile rule that is forced to
run before any compilation happens that checks if config.h exists
and then created it if missing by copying config.h.sample over, and
then all other source files can include config.h without having to
know anything about config.h.sample's existence.

Did I miss something?


There is no makefile with the arduino IDE/build system :-(


How does "the build system" you want to make it work with actually
work?  Is it incapable of "compiling" a "source file" into an
"object file" that happens to be a text using an arbitrary
"compiler"?


It looks for all *.ino files (which need to contain C code) in the specified 
("project") directory and compiles and links them all into one blob, it adds a 
smidge of code at the beginning to run setup() followed by loop(). It then dumps 
this blob (via serial/USB) into the flash of the device that will run it.


it's a very dumbed down system, designed for non-programmers to do trivial 
things (blink a few LEDs, etc) that's been pushed to far more sophisticated uses 
than it was ever designed for.


David Lang


I was hoping that readers are imaginative enough to replace Makefile
with whatever way things are normally built with when reading my
message, and the reader can just replace "source file" with
"config.h.sample", "compiler" with "test -f config.h || cat
config.h.sample >config.h" and "object file" with "config.h".



Re: Is there a way to have a local version of a header file?

2017-03-18 Thread Samuel Lijin
Arduino is basically a simplified/streamlined cross-compilation
toolchain with very tightly coupled IDE integration.

I'd just provide a .sample and tell people what to do with it in the
README. The alternative is to provide config.h as is and tell people
to use "git update-index --assume-unchanged" immediately after cloning
to ignore changes to the file, but this is prone to people
accidentally committing credentials.

On Sat, Mar 18, 2017 at 6:11 PM, Junio C Hamano  wrote:
> David Lang  writes:
>
>>> Ship a config.h.sample file, have a Makefile rule that is forced to
>>> run before any compilation happens that checks if config.h exists
>>> and then created it if missing by copying config.h.sample over, and
>>> then all other source files can include config.h without having to
>>> know anything about config.h.sample's existence.
>>>
>>> Did I miss something?
>>
>> There is no makefile with the arduino IDE/build system :-(
>
> How does "the build system" you want to make it work with actually
> work?  Is it incapable of "compiling" a "source file" into an
> "object file" that happens to be a text using an arbitrary
> "compiler"?
>
> I was hoping that readers are imaginative enough to replace Makefile
> with whatever way things are normally built with when reading my
> message, and the reader can just replace "source file" with
> "config.h.sample", "compiler" with "test -f config.h || cat
> config.h.sample >config.h" and "object file" with "config.h".


Re: [PATCH v2 1/2] l10n: Introduce framework for localizing man pages

2017-03-18 Thread Junio C Hamano
Junio C Hamano  writes:

> Jean-Noel Avila  writes:
>
>> Providing git in localized version is a good step for general adoption
>> of the tool. But as of now, if one needs to refer to the manual pages,
>> they are still confronted to english. The aim is to provide
>> documentation to users in their own language.
>
> Please outline how the end result looks like here.  Where are the
> localized man pages installed?  Do installers get to choose to build
> and install the localization for some but not all languages and if
> so how?  etc.
>
>> signed-off-by: Jean-Noel Avila 
>
> s/sign/Sign/;
>
>> -man: man1 man5 man7
>> +man: man1 man5 man7 man_l10n
>
> Hmmm, at least in the early days of the topic, I'd prefer that "make
> doc" and "make install" I need to run dozens of times a day from the
> toplevel not to require po4a.
>
> Thanks.

Travis seems to have failed.  Perhaps something like this is needed,
at least?

 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index 591cc57b80..719e5cdb00 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,6 +20,7 @@ addons:
 - language-pack-is
 - git-svn
 - apache2
+- po4a
 
 env:
   global:


Re: [PATCH] send-email: Net::SMTP::SSL is obsolete, use only when necessary

2017-03-18 Thread Dennis Kaarsemaker
On Sat, 2017-03-18 at 23:47 +0100, Ævar Arnfjörð Bjarmason wrote:

> On Sat, Mar 18, 2017 at 11:23 PM, Dennis Kaarsemaker
>  wrote:
>
> > +   require Net::SMTP;
> > +   my $use_net_smtp_ssl = $Net::SMTP::VERSION lt "1.28";
> > +   $smtp_domain ||= maildomain();
> > +
> 
> While Net::SMTP is unlikely to change its versioning scheme, let's use
> comparisons via the version module here in case they do change it to
> something silly, and this ends up introducing a bug.

ok.

> > [...]
> > +   if ($smtp->code != 220) {
> > +   die sprintf(__("Server does 
> > not support STARTTLS! %s"), $smtp->message);
> 
> Here a new message you're adding gets __(), makes sense.

Didn't add it, it just moved from a bit further below :)

> > +   else {
> > +   $smtp->starttls(ssl_verify_params())
> > +   or die "STARTTLS failed! 
> > ".IO::Socket::SSL::errstr();
> > +   }
> 
> I see you just copied that from above but I wonder if it makes sense
> to just mark both occurrences with __() too while we're at it.

ok.

D.


[PATCH 12/20] submodule: convert check_for_new_submodule_commits to object_id

2017-03-18 Thread brian m. carlson
All of the callers of this function have been converted, so convert this
function and update the callers.  This function also calls
sha1_array_append, which we'll convert shortly.

Signed-off-by: brian m. carlson 
---
 builtin/fetch.c | 6 +++---
 submodule.c | 4 ++--
 submodule.h | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index b5ad09d046..a41b892dcc 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -659,7 +659,7 @@ static int update_local_ref(struct ref *ref,
 
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
(recurse_submodules != RECURSE_SUBMODULES_ON))
-   check_for_new_submodule_commits(ref->new_oid.hash);
+   check_for_new_submodule_commits(>new_oid);
r = s_update_ref(msg, ref, 0);
format_display(display, r ? '!' : '*', what,
   r ? _("unable to update local ref") : NULL,
@@ -675,7 +675,7 @@ static int update_local_ref(struct ref *ref,
strbuf_add_unique_abbrev(, ref->new_oid.hash, 
DEFAULT_ABBREV);
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
(recurse_submodules != RECURSE_SUBMODULES_ON))
-   check_for_new_submodule_commits(ref->new_oid.hash);
+   check_for_new_submodule_commits(>new_oid);
r = s_update_ref("fast-forward", ref, 1);
format_display(display, r ? '!' : ' ', quickref.buf,
   r ? _("unable to update local ref") : NULL,
@@ -690,7 +690,7 @@ static int update_local_ref(struct ref *ref,
strbuf_add_unique_abbrev(, ref->new_oid.hash, 
DEFAULT_ABBREV);
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
(recurse_submodules != RECURSE_SUBMODULES_ON))
-   check_for_new_submodule_commits(ref->new_oid.hash);
+   check_for_new_submodule_commits(>new_oid);
r = s_update_ref("forced-update", ref, 1);
format_display(display, r ? '!' : '+', quickref.buf,
   r ? _("unable to update local ref") : _("forced 
update"),
diff --git a/submodule.c b/submodule.c
index 3200b7bb2b..5c5c18ec3d 100644
--- a/submodule.c
+++ b/submodule.c
@@ -821,14 +821,14 @@ static int add_sha1_to_array(const char *ref, const 
struct object_id *oid,
return 0;
 }
 
-void check_for_new_submodule_commits(unsigned char new_sha1[20])
+void check_for_new_submodule_commits(struct object_id *oid)
 {
if (!initialized_fetch_ref_tips) {
for_each_ref(add_sha1_to_array, _tips_before_fetch);
initialized_fetch_ref_tips = 1;
}
 
-   sha1_array_append(_tips_after_fetch, new_sha1);
+   sha1_array_append(_tips_after_fetch, oid->hash);
 }
 
 static int add_sha1_to_argv(const unsigned char sha1[20], void *data)
diff --git a/submodule.h b/submodule.h
index c8a0c9cb29..9c32b28b12 100644
--- a/submodule.h
+++ b/submodule.h
@@ -58,7 +58,7 @@ extern void show_submodule_inline_diff(FILE *f, const char 
*path,
const char *del, const char *add, const char *reset,
const struct diff_options *opt);
 extern void set_config_fetch_recurse_submodules(int value);
-extern void check_for_new_submodule_commits(unsigned char new_sha1[20]);
+extern void check_for_new_submodule_commits(struct object_id *oid);
 extern int fetch_populated_submodules(const struct argv_array *options,
   const char *prefix, int command_line_option,
   int quiet, int max_parallel_jobs);


[PATCH 01/20] Define new hash-size constants for allocating memory

2017-03-18 Thread brian m. carlson
Since we will want to transition to a new hash at some point in the
future, and that hash may be larger in size than 160 bits, introduce two
constants that can be used for allocating a sufficient amount of memory.
They can be increased to reflect the largest supported hash size.

Signed-off-by: brian m. carlson 
---
 cache.h | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/cache.h b/cache.h
index 9b2157f591..cb301d8d7d 100644
--- a/cache.h
+++ b/cache.h
@@ -66,8 +66,12 @@ unsigned long git_deflate_bound(git_zstream *, unsigned 
long);
 #define GIT_SHA1_RAWSZ 20
 #define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
 
+/* The length in byte and in hex digits of the largest possible hash value. */
+#define GIT_MAX_RAWSZ GIT_SHA1_RAWSZ
+#define GIT_MAX_HEXSZ GIT_SHA1_HEXSZ
+
 struct object_id {
-   unsigned char hash[GIT_SHA1_RAWSZ];
+   unsigned char hash[GIT_MAX_RAWSZ];
 };
 
 #if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)


[PATCH 11/20] sha1_name: convert disambiguate_hint_fn to take object_id

2017-03-18 Thread brian m. carlson
Convert this function pointer type and the functions that implement it
to take a struct object_id.  Introduce a temporary in
show_ambiguous_object to avoid having to convert for_each_abbrev at this
point.

Signed-off-by: brian m. carlson 
---
 sha1_name.c | 64 -
 1 file changed, 34 insertions(+), 30 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index cf6f4be0c6..2e38aedfa5 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -11,7 +11,7 @@
 
 static int get_sha1_oneline(const char *, unsigned char *, struct commit_list 
*);
 
-typedef int (*disambiguate_hint_fn)(const unsigned char *, void *);
+typedef int (*disambiguate_hint_fn)(const struct object_id *, void *);
 
 struct disambiguate_state {
int len; /* length of prefix in hex chars */
@@ -29,7 +29,7 @@ struct disambiguate_state {
unsigned always_call_fn:1;
 };
 
-static void update_candidates(struct disambiguate_state *ds, const unsigned 
char *current)
+static void update_candidates(struct disambiguate_state *ds, const struct 
object_id *current)
 {
if (ds->always_call_fn) {
ds->ambiguous = ds->fn(current, ds->cb_data) ? 1 : 0;
@@ -37,10 +37,10 @@ static void update_candidates(struct disambiguate_state 
*ds, const unsigned char
}
if (!ds->candidate_exists) {
/* this is the first candidate */
-   hashcpy(ds->candidate.hash, current);
+   oidcpy(>candidate, current);
ds->candidate_exists = 1;
return;
-   } else if (!hashcmp(ds->candidate.hash, current)) {
+   } else if (!oidcmp(>candidate, current)) {
/* the same as what we already have seen */
return;
}
@@ -52,14 +52,14 @@ static void update_candidates(struct disambiguate_state 
*ds, const unsigned char
}
 
if (!ds->candidate_checked) {
-   ds->candidate_ok = ds->fn(ds->candidate.hash, ds->cb_data);
+   ds->candidate_ok = ds->fn(>candidate, ds->cb_data);
ds->disambiguate_fn_used = 1;
ds->candidate_checked = 1;
}
 
if (!ds->candidate_ok) {
/* discard the candidate; we know it does not satisfy fn */
-   hashcpy(ds->candidate.hash, current);
+   oidcpy(>candidate, current);
ds->candidate_checked = 0;
return;
}
@@ -107,15 +107,15 @@ static void find_short_object_filename(struct 
disambiguate_state *ds)
continue;
 
while (!ds->ambiguous && (de = readdir(dir)) != NULL) {
-   unsigned char sha1[20];
+   struct object_id oid;
 
-   if (strlen(de->d_name) != 38)
+   if (strlen(de->d_name) != GIT_SHA1_HEXSZ - 2)
continue;
if (memcmp(de->d_name, ds->hex_pfx + 2, ds->len - 2))
continue;
-   memcpy(hex + 2, de->d_name, 38);
-   if (!get_sha1_hex(hex, sha1))
-   update_candidates(ds, sha1);
+   memcpy(hex + 2, de->d_name, GIT_SHA1_HEXSZ - 2);
+   if (!get_oid_hex(hex, ))
+   update_candidates(ds, );
}
closedir(dir);
}
@@ -140,7 +140,7 @@ static void unique_in_pack(struct packed_git *p,
   struct disambiguate_state *ds)
 {
uint32_t num, last, i, first = 0;
-   const unsigned char *current = NULL;
+   const struct object_id *current = NULL;
 
open_pack_index(p);
num = p->num_objects;
@@ -169,8 +169,9 @@ static void unique_in_pack(struct packed_git *p,
 * 0, 1 or more objects that actually match(es).
 */
for (i = first; i < num && !ds->ambiguous; i++) {
-   current = nth_packed_object_sha1(p, i);
-   if (!match_sha(ds->len, ds->bin_pfx.hash, current))
+   struct object_id oid;
+   current = nth_packed_object_oid(, p, i);
+   if (!match_sha(ds->len, ds->bin_pfx.hash, current->hash))
break;
update_candidates(ds, current);
}
@@ -213,7 +214,7 @@ static int finish_object_disambiguation(struct 
disambiguate_state *ds,
 * same repository!
 */
ds->candidate_ok = (!ds->disambiguate_fn_used ||
-   ds->fn(ds->candidate.hash, ds->cb_data));
+   ds->fn(>candidate, ds->cb_data));
 
if (!ds->candidate_ok)
return SHORT_NAME_AMBIGUOUS;
@@ -222,57 +223,57 @@ static int finish_object_disambiguation(struct 
disambiguate_state *ds,
return 0;
 }
 
-static int disambiguate_commit_only(const unsigned char *sha1, 

[PATCH 09/20] test-sha1-array: convert most code to struct object_id

2017-03-18 Thread brian m. carlson
This helper is very small, so convert the entire thing.

Signed-off-by: brian m. carlson 
---
 t/helper/test-sha1-array.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/t/helper/test-sha1-array.c b/t/helper/test-sha1-array.c
index f7a53c4ad6..b4bb97fccc 100644
--- a/t/helper/test-sha1-array.c
+++ b/t/helper/test-sha1-array.c
@@ -14,16 +14,16 @@ int cmd_main(int argc, const char **argv)
 
while (strbuf_getline(, stdin) != EOF) {
const char *arg;
-   unsigned char sha1[20];
+   struct object_id oid;
 
if (skip_prefix(line.buf, "append ", )) {
-   if (get_sha1_hex(arg, sha1))
+   if (get_oid_hex(arg, ))
die("not a hexadecimal SHA1: %s", arg);
-   sha1_array_append(, sha1);
+   sha1_array_append(, oid.hash);
} else if (skip_prefix(line.buf, "lookup ", )) {
-   if (get_sha1_hex(arg, sha1))
+   if (get_oid_hex(arg, ))
die("not a hexadecimal SHA1: %s", arg);
-   printf("%d\n", sha1_array_lookup(, sha1));
+   printf("%d\n", sha1_array_lookup(, oid.hash));
} else if (!strcmp(line.buf, "clear"))
sha1_array_clear();
else if (!strcmp(line.buf, "for_each_unique"))


[PATCH 05/20] builtin/pull: convert portions to struct object_id

2017-03-18 Thread brian m. carlson
Convert the caller of sha1_array_append to struct object_id.

Signed-off-by: brian m. carlson 
---
 builtin/pull.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index 3ecb881b0b..a9f7553f30 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -335,16 +335,16 @@ static void get_merge_heads(struct sha1_array 
*merge_heads)
const char *filename = git_path("FETCH_HEAD");
FILE *fp;
struct strbuf sb = STRBUF_INIT;
-   unsigned char sha1[GIT_SHA1_RAWSZ];
+   struct object_id oid;
 
if (!(fp = fopen(filename, "r")))
die_errno(_("could not open '%s' for reading"), filename);
while (strbuf_getline_lf(, fp) != EOF) {
-   if (get_sha1_hex(sb.buf, sha1))
+   if (get_oid_hex(sb.buf, ))
continue;  /* invalid line: does not start with SHA1 */
if (starts_with(sb.buf + GIT_SHA1_HEXSZ, "\tnot-for-merge\t"))
continue;  /* ref is not-for-merge */
-   sha1_array_append(merge_heads, sha1);
+   sha1_array_append(merge_heads, oid.hash);
}
fclose(fp);
strbuf_release();


Re: Is there a way to have a local version of a header file?

2017-03-18 Thread Junio C Hamano
David Lang  writes:

>> Ship a config.h.sample file, have a Makefile rule that is forced to
>> run before any compilation happens that checks if config.h exists
>> and then created it if missing by copying config.h.sample over, and
>> then all other source files can include config.h without having to
>> know anything about config.h.sample's existence.
>>
>> Did I miss something?
>
> There is no makefile with the arduino IDE/build system :-(

How does "the build system" you want to make it work with actually
work?  Is it incapable of "compiling" a "source file" into an
"object file" that happens to be a text using an arbitrary
"compiler"?

I was hoping that readers are imaginative enough to replace Makefile
with whatever way things are normally built with when reading my
message, and the reader can just replace "source file" with
"config.h.sample", "compiler" with "test -f config.h || cat
config.h.sample >config.h" and "object file" with "config.h".


Re: How do I make 'git diff --no-index' follow symlinks?

2017-03-18 Thread Dennis Kaarsemaker
On Sat, 2017-03-18 at 12:30 -0700, Junio C Hamano wrote:
> Sounds like
> 
> https://public-inbox.org/git/2016201958.2175-1-den...@kaarsemaker.net/
> 
> to me.  A key message in the thread may be:
> 
> 
> https://public-inbox.org/git/alpine.DEB.2.20.1611121106110.3746@virtualbox/

Sorry for the delay in sending v3. I've had a serious case of
Lennonitis (Life is what happens to you while you're busy making other
plans).

D.


Re: [PATCH] send-email: Net::SMTP::SSL is obsolete, use only when necessary

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Sat, Mar 18, 2017 at 11:23 PM, Dennis Kaarsemaker
 wrote:
> Net::SMTP itself can do the necessary SSL and STARTTLS bits just fine
> since version 1.28, and Net::SMTP::SSL is now deprecated. Since 1.28
> isn't that old yet, keep the old code in place and use it when
> necessary.
>
> Signed-off-by: Dennis Kaarsemaker 
> ---
>  Note: I've only been able to test the starttls bits. None of the smtp servers
>  I use actually use ssl, only starttls.
>
>  git-send-email.perl | 52 ++--
>  1 file changed, 34 insertions(+), 18 deletions(-)
>
> diff --git a/git-send-email.perl b/git-send-email.perl
> index eea0a517f7..e247ea39dd 100755
> --- a/git-send-email.perl
> +++ b/git-send-email.perl
> @@ -1353,10 +1353,12 @@ EOF
> die __("The required SMTP server is not properly 
> defined.")
> }
>
> +   require Net::SMTP;
> +   my $use_net_smtp_ssl = $Net::SMTP::VERSION lt "1.28";
> +   $smtp_domain ||= maildomain();
> +

While Net::SMTP is unlikely to change its versioning scheme, let's use
comparisons via the version module here in case they do change it to
something silly, and this ends up introducing a bug.

E.g. 04.00 would be considered a higher version by CPAN than 1.28, but
not by this code:

$ perl -wE 'my ($x, $y) = @ARGV; my ($vx, $vy) = map {
version->parse($_) } ($x, $y); say $vx < $vy ? "vlower" : "vhigher";
say $x lt $y ? "slower" : "shigher"' 04.00 1.28
vhigher
slower

If we grep ::VERSION we can find other cases where we've gotten this
wrong, unlikely to bite us in practice, but version.pm is in core (so
core that you don't even need to use/require it), so let's do this
better for new code.


>[...]
> +   if ($smtp->code != 220) {
> +   die sprintf(__("Server does 
> not support STARTTLS! %s"), $smtp->message);

Here a new message you're adding gets __(), makes sense.

> +   }
> +   require Net::SMTP::SSL;
> $smtp = 
> Net::SMTP::SSL->start_SSL($smtp,
>   
> ssl_verify_params())
> or die "STARTTLS failed! 
> ".IO::Socket::SSL::errstr();
> -   $smtp_encryption = '';
> -   # Send EHLO again to receive fresh
> -   # supported commands
> -   $smtp->hello($smtp_domain);
> -   } else {
> -   die sprintf(__("Server does not 
> support STARTTLS! %s"), $smtp->message);
> }
> +   else {
> +   $smtp->starttls(ssl_verify_params())
> +   or die "STARTTLS failed! 
> ".IO::Socket::SSL::errstr();
> +   }

I see you just copied that from above but I wonder if it makes sense
to just mark both occurrences with __() too while we're at it.


Re: [PATCH v2 1/2] l10n: Introduce framework for localizing man pages

2017-03-18 Thread Jean-Noël AVILA
Le samedi 18 mars 2017, 12:41:22 CET Junio C Hamano a écrit :
> Jean-Noel Avila  writes:
> > Providing git in localized version is a good step for general adoption
> > of the tool. But as of now, if one needs to refer to the manual pages,
> > they are still confronted to english. The aim is to provide
> > documentation to users in their own language.
> 
> Please outline how the end result looks like here.  Where are the
> localized man pages installed?  Do installers get to choose to build
> and install the localization for some but not all languages and if
> so how?  etc.
> 
> > signed-off-by: Jean-Noel Avila 
> 
> s/sign/Sign/;
> 
> > -man: man1 man5 man7
> > +man: man1 man5 man7 man_l10n
> 
> Hmmm, at least in the early days of the topic, I'd prefer that "make
> doc" and "make install" I need to run dozens of times a day from the
> toplevel not to require po4a.
> 
> Thanks.

Fair enough. 

Anyway, now I see  there's a take away from the discussion thread. Right now 
the man pages are tagged with the actual version of git, because the 
documentation is supposed to change at the same pace as the code. But that may 
not be true for translations, In this case, the automatic running of po4a will 
generate fuzzy matches which are not going to be used in the translated texts, 
leading to patchworked manpages, depending on the level of acceptance of 
untranslated entities.

If we want to freeze the translated manpages at a given version of git until a 
new version of the manpages is fully translated, we'll have to commit the 
translated .txt and force in some way the version to freeze (not using the 
generic asciidoc target of the Makefile).  But, that may drag the version of 
translations far behind the original if translation is stalled.

Or maybe people will not be so upset by mixed language manpages when the 
translation is lagging, but will prefer to have a "best available translation" 
of up-to-date pages. Plus that would be managed automatically by po4a's level 
of translation threshold to effectively generate a translated man page as long 
as the untranslated parts are still sparse in the mixed-up text.

For now, I keep this last option.


[PATCH] rev-parse: match @{u}, @{push} and ^{} case-insensitively

2017-03-18 Thread Ævar Arnfjörð Bjarmason
Change the revision parsing logic to match @{upstream}, @{u}, @{push},
^{commit}, ^{tree} etc. case-insensitively. All of these cases
currently emit "unknown revision or path not in the working tree"
errors.

This change makes them equivalent to their lower-case versions, and
consistent with other revision format specifications, e.g. 'master@{6
hours ago}', which is equivalent to 'master@{6 HoUrS aGo}'.

The use-case for this is being able to hold the shift key down while
typing @{u} on certain keyboard layouts, which makes the sequence
easier to type, and reduces cases where git throws an error at the
user where it could do what he means instead.

This change was independently authored to scratch a longtime itch, but
when I was about to submit it I discovered that a similar patch had
been submitted unsuccessfully before by Conrad Irwin in August 2011 as
"rev-parse: Allow @{U} as a synonym for @{u}"[1].

The objection from Junio at the time[2] was that by lower-casing
{...}:

[The door would be closed on] allow[ing] @{/regexp} to find a
reflog entry that matches the given pattern, and in such a use
case we would certainly want to take the pattern in a case
sensitive way.

This appears to be an objection related to the code structure at the
time, but the current code does not conflate the parsing of
@{upstream}, @{push}, ^{tree} etc. with any other @{STRING} or ^{TYPE}
we might add in the future and want to keep case-sensitive.

The new starts_with_case() function is a copy of the existing adjacent
starts_with(), just with a tolower() in the "else if".

The tests for this patch are more exhaustive than in the 2011
submission. The starting point for them was to first change the code
to only support upper-case versions of the existing words, seeing what
broke, and amending the breaking tests to check upper case & mixed
case as appropriate, and where not redundant to other similar tests.

1. <1313287071-7851-1-git-send-email-conrad.ir...@gmail.com>
2. <7vhb5fd4zy@alter.siamese.dyndns.org>

Signed-off-by: Ævar Arnfjörð Bjarmason 
---
 Documentation/revisions.txt   | 11 ++-
 git-compat-util.h |  1 +
 sha1_name.c   | 12 ++--
 strbuf.c  |  9 +
 t/t1450-fsck.sh   |  7 +++
 t/t1507-rev-parse-upstream.sh | 15 +++
 t/t1511-rev-parse-caret.sh| 13 +
 t/t1514-rev-parse-push.sh |  8 ++--
 8 files changed, 63 insertions(+), 13 deletions(-)

diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index ba11b9c95e..55bde6ea65 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -96,7 +96,8 @@ some output processing may assume ref names in UTF-8.
   refers to the branch that the branch specified by branchname is set to build 
on
   top of (configured with `branch..remote` and
   `branch..merge`).  A missing branchname defaults to the
-  current one.
+  current one. Both '@\{upstream\}', '@\{u\}' are case-insensitive, so e.g.
+  '@\{UPSTREAM\}', '@\{U\}' or '@\{Upstream\}' also work.
 
 '@\{push\}', e.g. 'master@\{push\}', '@\{push\}'::
   The suffix '@\{push}' reports the branch "where we would push to" if
@@ -122,6 +123,9 @@ refs/remotes/myfork/mybranch
 Note in the example that we set up a triangular workflow, where we pull
 from one location and push to another. In a non-triangular workflow,
 '@\{push}' is the same as '@\{upstream}', and there is no need for it.
++
+'@\{push}' is matched case-insensitively, so e.g. '@\{PUSH}' or
+'@\{Push}' also works.
 
 '{caret}', e.g. 'HEAD{caret}, v1.5.1{caret}0'::
   A suffix '{caret}' to a revision parameter means the first parent of
@@ -158,6 +162,11 @@ it does not have to be dereferenced even once to get to an 
object.
 +
 'rev{caret}\{tag\}' can be used to ensure that 'rev' identifies an
 existing tag object.
++
+The {caret}{} part is matched case-insensitively. So
+e.g. '{caret}\{commit\}' can be equivalently specified as
+'{caret}\{COMMIT\}', '{caret}\{Commit\}' etc., '{caret}\{tree\}' as
+'{caret}\{TREE\}' and so forth.
 
 '{caret}{}', e.g. 'v0.99.8{caret}{}'::
   A suffix '{caret}' followed by an empty brace pair
diff --git a/git-compat-util.h b/git-compat-util.h
index e626851fe9..2b3b581a7c 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -448,6 +448,7 @@ extern void set_die_is_recursing_routine(int 
(*routine)(void));
 extern void set_error_handle(FILE *);
 
 extern int starts_with(const char *str, const char *prefix);
+extern int starts_with_case(const char *str, const char *prefix);
 
 /*
  * If the string "str" begins with the string found in "prefix", return 1.
diff --git a/sha1_name.c b/sha1_name.c
index cda9e49b12..8ff215932d 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -549,7 +549,7 @@ static inline int at_mark(const char *string, int len,
for (i = 0; i < nr; i++) {
int suffix_len = strlen(suffix[i]);
if (suffix_len <= 

Re: Is there a way to have a local version of a header file?

2017-03-18 Thread David Lang

On Sat, 18 Mar 2017, Junio C Hamano wrote:


Ævar Arnfjörð Bjarmason  writes:


There might be some way I haven't thought of, in particular maybe you
can use gitattributes to define a custom diff/merge driver that always
reports no changes, or some ways to (ab)use the index to make git
ignore any changes to the file.


Why does this have to be so difficult?

Ship a config.h.sample file, have a Makefile rule that is forced to
run before any compilation happens that checks if config.h exists
and then created it if missing by copying config.h.sample over, and
then all other source files can include config.h without having to
know anything about config.h.sample's existence.

Did I miss something?


There is no makefile with the arduino IDE/build system :-(

David Lang

[PATCH] send-email: Net::SMTP::SSL is obsolete, use only when necessary

2017-03-18 Thread Dennis Kaarsemaker
Net::SMTP itself can do the necessary SSL and STARTTLS bits just fine
since version 1.28, and Net::SMTP::SSL is now deprecated. Since 1.28
isn't that old yet, keep the old code in place and use it when
necessary.

Signed-off-by: Dennis Kaarsemaker 
---
 Note: I've only been able to test the starttls bits. None of the smtp servers
 I use actually use ssl, only starttls.

 git-send-email.perl | 52 ++--
 1 file changed, 34 insertions(+), 18 deletions(-)

diff --git a/git-send-email.perl b/git-send-email.perl
index eea0a517f7..e247ea39dd 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -1353,10 +1353,12 @@ EOF
die __("The required SMTP server is not properly 
defined.")
}
 
+   require Net::SMTP;
+   my $use_net_smtp_ssl = $Net::SMTP::VERSION lt "1.28";
+   $smtp_domain ||= maildomain();
+
if ($smtp_encryption eq 'ssl') {
$smtp_server_port ||= 465; # ssmtp
-   require Net::SMTP::SSL;
-   $smtp_domain ||= maildomain();
require IO::Socket::SSL;
 
# Suppress "variable accessed once" warning.
@@ -1368,34 +1370,48 @@ EOF
# Net::SMTP::SSL->new() does not forward any SSL options
IO::Socket::SSL::set_client_defaults(
ssl_verify_params());
-   $smtp ||= Net::SMTP::SSL->new($smtp_server,
- Hello => $smtp_domain,
- Port => $smtp_server_port,
- Debug => $debug_net_smtp);
+
+   if ($use_net_smtp_ssl) {
+   require Net::SMTP::SSL;
+   $smtp ||= Net::SMTP::SSL->new($smtp_server,
+ Hello => 
$smtp_domain,
+ Port => 
$smtp_server_port,
+ Debug => 
$debug_net_smtp);
+   }
+   else {
+   $smtp ||= Net::SMTP->new($smtp_server,
+Hello => $smtp_domain,
+Port => 
$smtp_server_port,
+Debug => 
$debug_net_smtp,
+SSL => 1);
+   }
}
else {
-   require Net::SMTP;
-   $smtp_domain ||= maildomain();
$smtp_server_port ||= 25;
$smtp ||= Net::SMTP->new($smtp_server,
 Hello => $smtp_domain,
 Debug => $debug_net_smtp,
 Port => $smtp_server_port);
if ($smtp_encryption eq 'tls' && $smtp) {
-   require Net::SMTP::SSL;
-   $smtp->command('STARTTLS');
-   $smtp->response();
-   if ($smtp->code == 220) {
+   if ($use_net_smtp_ssl) {
+   $smtp->command('STARTTLS');
+   $smtp->response();
+   if ($smtp->code != 220) {
+   die sprintf(__("Server does not 
support STARTTLS! %s"), $smtp->message);
+   }
+   require Net::SMTP::SSL;
$smtp = Net::SMTP::SSL->start_SSL($smtp,
  
ssl_verify_params())
or die "STARTTLS failed! 
".IO::Socket::SSL::errstr();
-   $smtp_encryption = '';
-   # Send EHLO again to receive fresh
-   # supported commands
-   $smtp->hello($smtp_domain);
-   } else {
-   die sprintf(__("Server does not support 
STARTTLS! %s"), $smtp->message);
}
+   else {
+   $smtp->starttls(ssl_verify_params())
+   or die "STARTTLS failed! 
".IO::Socket::SSL::errstr();
+   }
+   

[PATCH 06/20] builtin/receive-pack: convert portions to struct object_id

2017-03-18 Thread brian m. carlson
Convert some hardcoded constants into uses of parse_oid_hex.
Additionally, convert all uses of struct command, and miscellaneous
other functions necessary for that.  This work is necessary to be able
to convert sha1_array_append later on.

Signed-off-by: brian m. carlson 
---
 builtin/receive-pack.c | 97 +-
 1 file changed, 49 insertions(+), 48 deletions(-)

diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index f61efd5eed..b1aef26443 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -309,8 +309,8 @@ struct command {
unsigned int skip_update:1,
 did_not_exist:1;
int index;
-   unsigned char old_sha1[20];
-   unsigned char new_sha1[20];
+   struct object_id old_oid;
+   struct object_id new_oid;
char ref_name[FLEX_ARRAY]; /* more */
 };
 
@@ -723,7 +723,7 @@ static int feed_receive_hook(void *state_, const char 
**bufp, size_t *sizep)
return -1; /* EOF */
strbuf_reset(>buf);
strbuf_addf(>buf, "%s %s %s\n",
-   sha1_to_hex(cmd->old_sha1), sha1_to_hex(cmd->new_sha1),
+   oid_to_hex(>old_oid), oid_to_hex(>new_oid),
cmd->ref_name);
state->cmd = cmd->next;
if (bufp) {
@@ -764,8 +764,8 @@ static int run_update_hook(struct command *cmd)
return 0;
 
argv[1] = cmd->ref_name;
-   argv[2] = sha1_to_hex(cmd->old_sha1);
-   argv[3] = sha1_to_hex(cmd->new_sha1);
+   argv[2] = oid_to_hex(>old_oid);
+   argv[3] = oid_to_hex(>new_oid);
argv[4] = NULL;
 
proc.no_stdin = 1;
@@ -988,8 +988,8 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
const char *name = cmd->ref_name;
struct strbuf namespaced_name_buf = STRBUF_INIT;
const char *namespaced_name, *ret;
-   unsigned char *old_sha1 = cmd->old_sha1;
-   unsigned char *new_sha1 = cmd->new_sha1;
+   struct object_id *old_oid = >old_oid;
+   struct object_id *new_oid = >new_oid;
 
/* only refs/... are allowed */
if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) {
@@ -1014,20 +1014,20 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
refuse_unconfigured_deny();
return "branch is currently checked out";
case DENY_UPDATE_INSTEAD:
-   ret = update_worktree(new_sha1);
+   ret = update_worktree(new_oid->hash);
if (ret)
return ret;
break;
}
}
 
-   if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
+   if (!is_null_oid(new_oid) && !has_object_file(new_oid)) {
error("unpack should have generated %s, "
- "but I can't find it!", sha1_to_hex(new_sha1));
+ "but I can't find it!", oid_to_hex(new_oid));
return "bad pack";
}
 
-   if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
+   if (!is_null_oid(old_oid) && is_null_oid(new_oid)) {
if (deny_deletes && starts_with(name, "refs/heads/")) {
rp_error("denying ref deletion for %s", name);
return "deletion prohibited";
@@ -1053,14 +1053,14 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
}
}
 
-   if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
-   !is_null_sha1(old_sha1) &&
+   if (deny_non_fast_forwards && !is_null_oid(new_oid) &&
+   !is_null_oid(old_oid) &&
starts_with(name, "refs/heads/")) {
struct object *old_object, *new_object;
struct commit *old_commit, *new_commit;
 
-   old_object = parse_object(old_sha1);
-   new_object = parse_object(new_sha1);
+   old_object = parse_object(old_oid->hash);
+   new_object = parse_object(new_oid->hash);
 
if (!old_object || !new_object ||
old_object->type != OBJ_COMMIT ||
@@ -1081,10 +1081,10 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)
return "hook declined";
}
 
-   if (is_null_sha1(new_sha1)) {
+   if (is_null_oid(new_oid)) {
struct strbuf err = STRBUF_INIT;
-   if (!parse_object(old_sha1)) {
-   old_sha1 = NULL;
+   if (!parse_object(old_oid->hash)) {
+   old_oid = NULL;
if (ref_exists(name)) {
rp_warning("Allowing deletion of corrupt ref.");
} else {
@@ -1094,7 +1094,7 @@ static const char *update(struct command *cmd, struct 
shallow_info *si)

[PATCH 04/20] builtin/diff: convert to struct object_id

2017-03-18 Thread brian m. carlson
Signed-off-by: brian m. carlson 
---
 builtin/diff.c | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/builtin/diff.c b/builtin/diff.c
index 3d64b85337..398eee00d5 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -21,7 +21,7 @@
 #define DIFF_NO_INDEX_IMPLICIT 2
 
 struct blobinfo {
-   unsigned char sha1[20];
+   struct object_id oid;
const char *name;
unsigned mode;
 };
@@ -31,22 +31,22 @@ static const char builtin_diff_usage[] =
 
 static void stuff_change(struct diff_options *opt,
 unsigned old_mode, unsigned new_mode,
-const unsigned char *old_sha1,
-const unsigned char *new_sha1,
-int old_sha1_valid,
-int new_sha1_valid,
+const struct object_id *old_oid,
+const struct object_id *new_oid,
+int old_oid_valid,
+int new_oid_valid,
 const char *old_name,
 const char *new_name)
 {
struct diff_filespec *one, *two;
 
-   if (!is_null_sha1(old_sha1) && !is_null_sha1(new_sha1) &&
-   !hashcmp(old_sha1, new_sha1) && (old_mode == new_mode))
+   if (!is_null_oid(old_oid) && !is_null_oid(new_oid) &&
+   !oidcmp(old_oid, new_oid) && (old_mode == new_mode))
return;
 
if (DIFF_OPT_TST(opt, REVERSE_DIFF)) {
SWAP(old_mode, new_mode);
-   SWAP(old_sha1, new_sha1);
+   SWAP(old_oid, new_oid);
SWAP(old_name, new_name);
}
 
@@ -57,8 +57,8 @@ static void stuff_change(struct diff_options *opt,
 
one = alloc_filespec(old_name);
two = alloc_filespec(new_name);
-   fill_filespec(one, old_sha1, old_sha1_valid, old_mode);
-   fill_filespec(two, new_sha1, new_sha1_valid, new_mode);
+   fill_filespec(one, old_oid->hash, old_oid_valid, old_mode);
+   fill_filespec(two, new_oid->hash, new_oid_valid, new_mode);
 
diff_queue(_queued_diff, one, two);
 }
@@ -89,7 +89,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
 
stuff_change(>diffopt,
 blob[0].mode, canon_mode(st.st_mode),
-blob[0].sha1, null_sha1,
+[0].oid, _oid,
 1, 0,
 path, path);
diffcore_std(>diffopt);
@@ -114,7 +114,7 @@ static int builtin_diff_blobs(struct rev_info *revs,
 
stuff_change(>diffopt,
 blob[0].mode, blob[1].mode,
-blob[0].sha1, blob[1].sha1,
+[0].oid, [1].oid,
 1, 1,
 blob[0].name, blob[1].name);
diffcore_std(>diffopt);
@@ -160,7 +160,7 @@ static int builtin_diff_tree(struct rev_info *revs,
 struct object_array_entry *ent0,
 struct object_array_entry *ent1)
 {
-   const unsigned char *(sha1[2]);
+   const struct object_id *(oid[2]);
int swap = 0;
 
if (argc > 1)
@@ -172,9 +172,9 @@ static int builtin_diff_tree(struct rev_info *revs,
 */
if (ent1->item->flags & UNINTERESTING)
swap = 1;
-   sha1[swap] = ent0->item->oid.hash;
-   sha1[1 - swap] = ent1->item->oid.hash;
-   diff_tree_sha1(sha1[0], sha1[1], "", >diffopt);
+   oid[swap] = >item->oid;
+   oid[1 - swap] = >item->oid;
+   diff_tree_sha1(oid[0]->hash, oid[1]->hash, "", >diffopt);
log_tree_diff_flush(revs);
return 0;
 }
@@ -408,7 +408,7 @@ int cmd_diff(int argc, const char **argv, const char 
*prefix)
} else if (obj->type == OBJ_BLOB) {
if (2 <= blobs)
die(_("more than two blobs given: '%s'"), name);
-   hashcpy(blob[blobs].sha1, obj->oid.hash);
+   hashcpy(blob[blobs].oid.hash, obj->oid.hash);
blob[blobs].name = name;
blob[blobs].mode = entry->mode;
blobs++;


[PATCH 02/20] Convert GIT_SHA1_HEXSZ used for allocation to GIT_MAX_HEXSZ

2017-03-18 Thread brian m. carlson
Since we will likely be introducing a new hash function at some point,
and that hash function might be longer than 40 hex characters, use the
constant GIT_MAX_HEXSZ, which is designed to be suitable for
allocations, instead of GIT_SHA1_HEXSZ.  This will ease the transition
down the line by distinguishing between places where we need to allocate
memory suitable for the largest hash from those where we need to handle
the current hash.

Signed-off-by: brian m. carlson 
---
 bisect.c  | 2 +-
 builtin/blame.c   | 4 ++--
 builtin/merge-index.c | 2 +-
 builtin/merge.c   | 2 +-
 builtin/rev-list.c| 2 +-
 diff.c| 4 ++--
 hex.c | 2 +-
 sha1_file.c   | 2 +-
 sha1_name.c   | 6 +++---
 transport.c   | 2 +-
 10 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/bisect.c b/bisect.c
index 30808cadf7..21c3e34636 100644
--- a/bisect.c
+++ b/bisect.c
@@ -682,7 +682,7 @@ static int is_expected_rev(const struct object_id *oid)
 
 static int bisect_checkout(const unsigned char *bisect_rev, int no_checkout)
 {
-   char bisect_rev_hex[GIT_SHA1_HEXSZ + 1];
+   char bisect_rev_hex[GIT_MAX_HEXSZ + 1];
 
memcpy(bisect_rev_hex, sha1_to_hex(bisect_rev), GIT_SHA1_HEXSZ + 1);
update_ref(NULL, "BISECT_EXPECTED_REV", bisect_rev, NULL, 0, 
UPDATE_REFS_DIE_ON_ERR);
diff --git a/builtin/blame.c b/builtin/blame.c
index f7aa95f4ba..07506a3e45 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1890,7 +1890,7 @@ static void emit_porcelain(struct scoreboard *sb, struct 
blame_entry *ent,
int cnt;
const char *cp;
struct origin *suspect = ent->suspect;
-   char hex[GIT_SHA1_HEXSZ + 1];
+   char hex[GIT_MAX_HEXSZ + 1];
 
oid_to_hex_r(hex, >commit->object.oid);
printf("%s %d %d %d\n",
@@ -1928,7 +1928,7 @@ static void emit_other(struct scoreboard *sb, struct 
blame_entry *ent, int opt)
const char *cp;
struct origin *suspect = ent->suspect;
struct commit_info ci;
-   char hex[GIT_SHA1_HEXSZ + 1];
+   char hex[GIT_MAX_HEXSZ + 1];
int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);
 
get_commit_info(suspect->commit, , 1);
diff --git a/builtin/merge-index.c b/builtin/merge-index.c
index 2d1b6db6bd..c99443b095 100644
--- a/builtin/merge-index.c
+++ b/builtin/merge-index.c
@@ -9,7 +9,7 @@ static int merge_entry(int pos, const char *path)
 {
int found;
const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
-   char hexbuf[4][GIT_SHA1_HEXSZ + 1];
+   char hexbuf[4][GIT_MAX_HEXSZ + 1];
char ownbuf[4][60];
 
if (pos >= active_nr)
diff --git a/builtin/merge.c b/builtin/merge.c
index 7554b8d412..a2cceea3fb 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -1296,7 +1296,7 @@ int cmd_merge(int argc, const char **argv, const char 
*prefix)
if (verify_signatures) {
for (p = remoteheads; p; p = p->next) {
struct commit *commit = p->item;
-   char hex[GIT_SHA1_HEXSZ + 1];
+   char hex[GIT_MAX_HEXSZ + 1];
struct signature_check signature_check;
memset(_check, 0, sizeof(signature_check));
 
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 0aa93d5891..bcf77f0b8a 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -212,7 +212,7 @@ static void print_var_int(const char *var, int val)
 static int show_bisect_vars(struct rev_list_info *info, int reaches, int all)
 {
int cnt, flags = info->flags;
-   char hex[GIT_SHA1_HEXSZ + 1] = "";
+   char hex[GIT_MAX_HEXSZ + 1] = "";
struct commit_list *tried;
struct rev_info *revs = info->revs;
 
diff --git a/diff.c b/diff.c
index a628ac3a95..330b640c68 100644
--- a/diff.c
+++ b/diff.c
@@ -398,7 +398,7 @@ static struct diff_tempfile {
 */
const char *name;
 
-   char hex[GIT_SHA1_HEXSZ + 1];
+   char hex[GIT_MAX_HEXSZ + 1];
char mode[10];
 
/*
@@ -4219,7 +4219,7 @@ const char *diff_aligned_abbrev(const struct object_id 
*oid, int len)
 * uniqueness across all objects (statistically speaking).
 */
if (abblen < GIT_SHA1_HEXSZ - 3) {
-   static char hex[GIT_SHA1_HEXSZ + 1];
+   static char hex[GIT_MAX_HEXSZ + 1];
if (len < abblen && abblen <= len + 2)
xsnprintf(hex, sizeof(hex), "%s%.*s", abbrev, 
len+3-abblen, "..");
else
diff --git a/hex.c b/hex.c
index eab7b626ee..28b44118cb 100644
--- a/hex.c
+++ b/hex.c
@@ -85,7 +85,7 @@ char *oid_to_hex_r(char *buffer, const struct object_id *oid)
 char *sha1_to_hex(const unsigned char *sha1)
 {
static int bufno;
-   static char hexbuffer[4][GIT_SHA1_HEXSZ + 1];
+   static char hexbuffer[4][GIT_MAX_HEXSZ + 1];
bufno = (bufno + 1) % ARRAY_SIZE(hexbuffer);

[PATCH 10/20] sha1_name: convert struct disambiguate_state to object_id

2017-03-18 Thread brian m. carlson
Convert struct disambiguate_state to use struct object_id by changing
the structure definition and applying the following semantic patch:

@@
struct disambiguate_state E1;
@@
- E1.bin_pfx
+ E1.bin_pfx.hash

@@
struct disambiguate_state *E1;
@@
- E1->bin_pfx
+ E1->bin_pfx.hash

@@
struct disambiguate_state E1;
@@
- E1.candidate
+ E1.candidate.hash

@@
struct disambiguate_state *E1;
@@
- E1->candidate
+ E1->candidate.hash

This conversion is needed so we can convert disambiguate_hint_fn later.

Signed-off-by: brian m. carlson 
---
 sha1_name.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 3db166b40b..cf6f4be0c6 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -16,11 +16,11 @@ typedef int (*disambiguate_hint_fn)(const unsigned char *, 
void *);
 struct disambiguate_state {
int len; /* length of prefix in hex chars */
char hex_pfx[GIT_MAX_HEXSZ + 1];
-   unsigned char bin_pfx[GIT_MAX_RAWSZ];
+   struct object_id bin_pfx;
 
disambiguate_hint_fn fn;
void *cb_data;
-   unsigned char candidate[GIT_MAX_RAWSZ];
+   struct object_id candidate;
unsigned candidate_exists:1;
unsigned candidate_checked:1;
unsigned candidate_ok:1;
@@ -37,10 +37,10 @@ static void update_candidates(struct disambiguate_state 
*ds, const unsigned char
}
if (!ds->candidate_exists) {
/* this is the first candidate */
-   hashcpy(ds->candidate, current);
+   hashcpy(ds->candidate.hash, current);
ds->candidate_exists = 1;
return;
-   } else if (!hashcmp(ds->candidate, current)) {
+   } else if (!hashcmp(ds->candidate.hash, current)) {
/* the same as what we already have seen */
return;
}
@@ -52,14 +52,14 @@ static void update_candidates(struct disambiguate_state 
*ds, const unsigned char
}
 
if (!ds->candidate_checked) {
-   ds->candidate_ok = ds->fn(ds->candidate, ds->cb_data);
+   ds->candidate_ok = ds->fn(ds->candidate.hash, ds->cb_data);
ds->disambiguate_fn_used = 1;
ds->candidate_checked = 1;
}
 
if (!ds->candidate_ok) {
/* discard the candidate; we know it does not satisfy fn */
-   hashcpy(ds->candidate, current);
+   hashcpy(ds->candidate.hash, current);
ds->candidate_checked = 0;
return;
}
@@ -151,7 +151,7 @@ static void unique_in_pack(struct packed_git *p,
int cmp;
 
current = nth_packed_object_sha1(p, mid);
-   cmp = hashcmp(ds->bin_pfx, current);
+   cmp = hashcmp(ds->bin_pfx.hash, current);
if (!cmp) {
first = mid;
break;
@@ -170,7 +170,7 @@ static void unique_in_pack(struct packed_git *p,
 */
for (i = first; i < num && !ds->ambiguous; i++) {
current = nth_packed_object_sha1(p, i);
-   if (!match_sha(ds->len, ds->bin_pfx, current))
+   if (!match_sha(ds->len, ds->bin_pfx.hash, current))
break;
update_candidates(ds, current);
}
@@ -213,12 +213,12 @@ static int finish_object_disambiguation(struct 
disambiguate_state *ds,
 * same repository!
 */
ds->candidate_ok = (!ds->disambiguate_fn_used ||
-   ds->fn(ds->candidate, ds->cb_data));
+   ds->fn(ds->candidate.hash, ds->cb_data));
 
if (!ds->candidate_ok)
return SHORT_NAME_AMBIGUOUS;
 
-   hashcpy(sha1, ds->candidate);
+   hashcpy(sha1, ds->candidate.hash);
return 0;
 }
 
@@ -332,7 +332,7 @@ static int init_object_disambiguation(const char *name, int 
len,
ds->hex_pfx[i] = c;
if (!(i & 1))
val <<= 4;
-   ds->bin_pfx[i >> 1] |= val;
+   ds->bin_pfx.hash[i >> 1] |= val;
}
 
ds->len = len;


[PATCH 03/20] Convert GIT_SHA1_RAWSZ used for allocation to GIT_MAX_RAWSZ

2017-03-18 Thread brian m. carlson
Since we will likely be introducing a new hash function at some point,
and that hash function might be longer than 20 bytes, use the constant
GIT_MAX_RAWSZ, which is designed to be suitable for allocations, instead
of GIT_SHA1_RAWSZ.  This will ease the transition down the line by
distinguishing between places where we need to allocate memory suitable
for the largest hash from those where we need to handle the current
hash.

Signed-off-by: brian m. carlson 
---
 builtin/patch-id.c | 2 +-
 builtin/receive-pack.c | 2 +-
 cache.h| 2 +-
 patch-ids.c| 2 +-
 patch-ids.h| 2 +-
 sha1_file.c| 4 ++--
 sha1_name.c| 4 ++--
 wt-status.h| 2 +-
 8 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/builtin/patch-id.c b/builtin/patch-id.c
index a84d0003a3..81552e02e4 100644
--- a/builtin/patch-id.c
+++ b/builtin/patch-id.c
@@ -55,7 +55,7 @@ static int scan_hunk_header(const char *p, int *p_before, int 
*p_after)
 
 static void flush_one_hunk(struct object_id *result, git_SHA_CTX *ctx)
 {
-   unsigned char hash[GIT_SHA1_RAWSZ];
+   unsigned char hash[GIT_MAX_RAWSZ];
unsigned short carry = 0;
int i;
 
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 83492af05f..f61efd5eed 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1165,7 +1165,7 @@ static void check_aliased_update(struct command *cmd, 
struct string_list *list)
const char *dst_name;
struct string_list_item *item;
struct command *dst_cmd;
-   unsigned char sha1[GIT_SHA1_RAWSZ];
+   unsigned char sha1[GIT_MAX_RAWSZ];
int flag;
 
strbuf_addf(, "%s%s", get_git_namespace(), cmd->ref_name);
diff --git a/cache.h b/cache.h
index cb301d8d7d..5cdd9cd229 100644
--- a/cache.h
+++ b/cache.h
@@ -968,7 +968,7 @@ extern char *sha1_pack_index_name(const unsigned char 
*sha1);
 extern const char *find_unique_abbrev(const unsigned char *sha1, int len);
 extern int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len);
 
-extern const unsigned char null_sha1[GIT_SHA1_RAWSZ];
+extern const unsigned char null_sha1[GIT_MAX_RAWSZ];
 extern const struct object_id null_oid;
 
 static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
diff --git a/patch-ids.c b/patch-ids.c
index ce285c2e0c..fa8f11de82 100644
--- a/patch-ids.c
+++ b/patch-ids.c
@@ -71,7 +71,7 @@ static int init_patch_id_entry(struct patch_id *patch,
   struct commit *commit,
   struct patch_ids *ids)
 {
-   unsigned char header_only_patch_id[GIT_SHA1_RAWSZ];
+   unsigned char header_only_patch_id[GIT_MAX_RAWSZ];
 
patch->commit = commit;
if (commit_patch_id(commit, >diffopts, header_only_patch_id, 1))
diff --git a/patch-ids.h b/patch-ids.h
index 0f34ea11ea..b9e5751f8e 100644
--- a/patch-ids.h
+++ b/patch-ids.h
@@ -3,7 +3,7 @@
 
 struct patch_id {
struct hashmap_entry ent;
-   unsigned char patch_id[GIT_SHA1_RAWSZ];
+   unsigned char patch_id[GIT_MAX_RAWSZ];
struct commit *commit;
 };
 
diff --git a/sha1_file.c b/sha1_file.c
index cc6b93c8a9..657666b815 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1611,7 +1611,7 @@ static void mark_bad_packed_object(struct packed_git *p,
if (!hashcmp(sha1, p->bad_object_sha1 + GIT_SHA1_RAWSZ * i))
return;
p->bad_object_sha1 = xrealloc(p->bad_object_sha1,
- st_mult(GIT_SHA1_RAWSZ,
+ st_mult(GIT_MAX_RAWSZ,
  st_add(p->num_bad_objects, 1)));
hashcpy(p->bad_object_sha1 + GIT_SHA1_RAWSZ * p->num_bad_objects, sha1);
p->num_bad_objects++;
@@ -3918,7 +3918,7 @@ static int check_stream_sha1(git_zstream *stream,
 const unsigned char *expected_sha1)
 {
git_SHA_CTX c;
-   unsigned char real_sha1[GIT_SHA1_RAWSZ];
+   unsigned char real_sha1[GIT_MAX_RAWSZ];
unsigned char buf[4096];
unsigned long total_read;
int status = Z_OK;
diff --git a/sha1_name.c b/sha1_name.c
index 964201bc26..3db166b40b 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -16,11 +16,11 @@ typedef int (*disambiguate_hint_fn)(const unsigned char *, 
void *);
 struct disambiguate_state {
int len; /* length of prefix in hex chars */
char hex_pfx[GIT_MAX_HEXSZ + 1];
-   unsigned char bin_pfx[GIT_SHA1_RAWSZ];
+   unsigned char bin_pfx[GIT_MAX_RAWSZ];
 
disambiguate_hint_fn fn;
void *cb_data;
-   unsigned char candidate[GIT_SHA1_RAWSZ];
+   unsigned char candidate[GIT_MAX_RAWSZ];
unsigned candidate_exists:1;
unsigned candidate_checked:1;
unsigned candidate_ok:1;
diff --git a/wt-status.h b/wt-status.h
index 54fec77032..6018c627b1 100644
--- a/wt-status.h
+++ b/wt-status.h

[PATCH 08/20] parse-options-cb: convert sha1_array_append caller to struct object_id

2017-03-18 Thread brian m. carlson
Signed-off-by: brian m. carlson 
---
 parse-options-cb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/parse-options-cb.c b/parse-options-cb.c
index b7d8f7dcb2..40ece4d8c2 100644
--- a/parse-options-cb.c
+++ b/parse-options-cb.c
@@ -96,7 +96,7 @@ int parse_opt_commits(const struct option *opt, const char 
*arg, int unset)
 
 int parse_opt_object_name(const struct option *opt, const char *arg, int unset)
 {
-   unsigned char sha1[20];
+   struct object_id oid;
 
if (unset) {
sha1_array_clear(opt->value);
@@ -104,9 +104,9 @@ int parse_opt_object_name(const struct option *opt, const 
char *arg, int unset)
}
if (!arg)
return -1;
-   if (get_sha1(arg, sha1))
+   if (get_oid(arg, ))
return error(_("malformed object name '%s'"), arg);
-   sha1_array_append(opt->value, sha1);
+   sha1_array_append(opt->value, oid.hash);
return 0;
 }
 


[PATCH 00/20] object_id part 7

2017-03-18 Thread brian m. carlson
This is part 7 in the continuing transition to use struct object_id.

This series focuses on two main areas: adding two constants for the
maximum hash size we'll be using (which will be suitable for allocating
memory) and converting struct sha1_array to struct oid_array.

The rationale for adding separate constants for allocating memory is
that with a new 256-bit hash function, we're going to need two different
items: a constant for allocating memory that's as large as the largest
hash, and a global variable telling us size the current hash is.  I've
opted to provide GIT_MAX_RAWSZ and GIT_MAX_HEXSZ for allocating memory,
and leave GIT_SHA1_RAWSZ and GIT_SHA1_HEXSZ as values that can be later
replaced by the aforementioned global.

Replacing struct sha1_array with struct oid_array necessarily involves
converting the shallow code, so I did that.  The structure now handles
objects of struct object_id.  While I renamed the documentation (since
people will search for that), I chose not to rename the sha1-array.[ch]
files or the test helper because I didn't think it was worth the hassle,
especially for people who don't have rename support turned on by
default.  Of course, if the consensus is that they should be, I'll do so
in v2.

I chose to use Coccinelle quite a bit in this series, as it automates a
lot of the manual work and aides in review.  There is also some use of
Perl one-liners.

This series is available at https://github.com/bk2204/git under
object-id-part7; it may be rebased.  Future series are available in
various states as the object-id-part8, object-id-part9, and
object-id-part10 series.

brian m. carlson (20):
  Define new hash-size constants for allocating memory
  Convert GIT_SHA1_HEXSZ used for allocation to GIT_MAX_HEXSZ
  Convert GIT_SHA1_RAWSZ used for allocation to GIT_MAX_RAWSZ
  builtin/diff: convert to struct object_id
  builtin/pull: convert portions to struct object_id
  builtin/receive-pack: convert portions to struct object_id
  fsck: convert init_skiplist to struct object_id
  parse-options-cb: convert sha1_array_append caller to struct object_id
  test-sha1-array: convert most code to struct object_id
  sha1_name: convert struct disambiguate_state to object_id
  sha1_name: convert disambiguate_hint_fn to take object_id
  submodule: convert check_for_new_submodule_commits to object_id
  builtin/pull: convert to struct object_id
  sha1-array: convert internal storage for struct sha1_array to
object_id
  Make sha1_array_append take a struct object_id *
  Convert remaining callers of sha1_array_lookup to object_id
  Convert sha1_array_lookup to take struct object_id
  Convert sha1_array_for_each_unique and for_each_abbrev to object_id
  Rename sha1_array to oid_array
  Documentation: update and rename api-sha1-array.txt

 .../{api-sha1-array.txt => api-oid-array.txt}  |  44 +++
 bisect.c   |  43 ---
 builtin/blame.c|   4 +-
 builtin/cat-file.c |  14 +--
 builtin/diff.c |  40 +++
 builtin/fetch-pack.c   |   2 +-
 builtin/fetch.c|   6 +-
 builtin/merge-index.c  |   2 +-
 builtin/merge.c|   2 +-
 builtin/pack-objects.c |  24 ++--
 builtin/patch-id.c |   2 +-
 builtin/pull.c |  98 +++
 builtin/receive-pack.c | 133 +++--
 builtin/rev-list.c |   2 +-
 builtin/rev-parse.c|   4 +-
 builtin/send-pack.c|   4 +-
 cache.h|  10 +-
 combine-diff.c |  18 +--
 commit.h   |  14 +--
 connect.c  |   8 +-
 diff.c |   4 +-
 diff.h |   4 +-
 fetch-pack.c   |  32 ++---
 fetch-pack.h   |   4 +-
 fsck.c |  17 +--
 fsck.h |   2 +-
 hex.c  |   2 +-
 parse-options-cb.c |   8 +-
 patch-ids.c|   2 +-
 patch-ids.h|   2 +-
 ref-filter.c   |  22 ++--
 ref-filter.h   |   2 +-
 remote-curl.c  |   4 +-
 remote.h   |   6 +-
 send-pack.c|   6 +-
 

[PATCH 07/20] fsck: convert init_skiplist to struct object_id

2017-03-18 Thread brian m. carlson
Convert a hardcoded constant buffer size to a use of GIT_MAX_HEXSZ, and
use parse_oid_hex to reduce the dependency on the size of the hash.
This function is a caller of sha1_array_append, which will be converted
later.

Signed-off-by: brian m. carlson 
---
 fsck.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/fsck.c b/fsck.c
index 939792752b..aff4ae6fd4 100644
--- a/fsck.c
+++ b/fsck.c
@@ -134,8 +134,8 @@ static void init_skiplist(struct fsck_options *options, 
const char *path)
 {
static struct sha1_array skiplist = SHA1_ARRAY_INIT;
int sorted, fd;
-   char buffer[41];
-   unsigned char sha1[20];
+   char buffer[GIT_MAX_HEXSZ + 1];
+   struct object_id oid;
 
if (options->skiplist)
sorted = options->skiplist->sorted;
@@ -148,17 +148,18 @@ static void init_skiplist(struct fsck_options *options, 
const char *path)
if (fd < 0)
die("Could not open skip list: %s", path);
for (;;) {
+   const char *p;
int result = read_in_full(fd, buffer, sizeof(buffer));
if (result < 0)
die_errno("Could not read '%s'", path);
if (!result)
break;
-   if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n')
+   if (parse_oid_hex(buffer, , ) || *p != '\n')
die("Invalid SHA-1: %s", buffer);
-   sha1_array_append(, sha1);
+   sha1_array_append(, oid.hash);
if (sorted && skiplist.nr > 1 &&
hashcmp(skiplist.sha1[skiplist.nr - 2],
-   sha1) > 0)
+   oid.hash) > 0)
sorted = 0;
}
close(fd);


[PATCH v3 1/2] diff --no-index: optionally follow symlinks

2017-03-18 Thread Dennis Kaarsemaker
Git's diff machinery does not follow symlinks, which makes sense as git
itself also does not, but stores the symlink destination.

In --no-index mode however, it is useful for diff to be able to follow
symlinks, matching the behaviour of ordinary diff. A new --dereference
(name copied from diff) option has been added to enable this behaviour.
--no-dereference can be used to disable it again.

Signed-off-by: Dennis Kaarsemaker 
---
 Documentation/diff-options.txt |  9 +
 diff-no-index.c|  7 ---
 diff.c | 12 ++--
 diff.h |  2 +-
 t/t4053-diff-no-index.sh   | 44 ++
 5 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 2d77a19626..5a9d58b701 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -216,6 +216,15 @@ any of those replacements occurred.
commit range.  Defaults to `diff.submodule` or the 'short' format
if the config option is unset.
 
+ifdef::git-diff[]
+--dereference::
+--no-dereference::
+   Normally, "git diff --no-index" will compare symlinks by comparing what
+   they point to. The `--dereference` option will make it compare the 
content
+   of the linked files. The `--no-dereference` option disables an earlier
+   `--dereference`.
+endif::git-diff[]
+
 --color[=]::
Show colored diff.
`--color` (i.e. without '=') is the same as `--color=always`.
diff --git a/diff-no-index.c b/diff-no-index.c
index f420786039..fe48f32ddd 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -40,7 +40,7 @@ static int read_directory_contents(const char *path, struct 
string_list *list)
  */
 static const char file_from_standard_input[] = "-";
 
-static int get_mode(const char *path, int *mode)
+static int get_mode(const char *path, int *mode, int dereference)
 {
struct stat st;
 
@@ -52,7 +52,7 @@ static int get_mode(const char *path, int *mode)
 #endif
else if (path == file_from_standard_input)
*mode = create_ce_mode(0666);
-   else if (lstat(path, ))
+   else if (dereference ? stat(path, ) : lstat(path, ))
return error("Could not access '%s'", path);
else
*mode = st.st_mode;
@@ -93,7 +93,8 @@ static int queue_diff(struct diff_options *o,
 {
int mode1 = 0, mode2 = 0;
 
-   if (get_mode(name1, ) || get_mode(name2, ))
+   if (get_mode(name1, , DIFF_OPT_TST(o, DEREFERENCE)) ||
+   get_mode(name2, , DIFF_OPT_TST(o, DEREFERENCE)))
return -1;
 
if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) {
diff --git a/diff.c b/diff.c
index be11e4ef2b..2afecfb939 100644
--- a/diff.c
+++ b/diff.c
@@ -2815,7 +2815,7 @@ int diff_populate_filespec(struct diff_filespec *s, 
unsigned int flags)
s->size = xsize_t(st.st_size);
if (!s->size)
goto empty;
-   if (S_ISLNK(st.st_mode)) {
+   if (S_ISLNK(s->mode)) {
struct strbuf sb = STRBUF_INIT;
 
if (strbuf_readlink(, s->path, s->size))
@@ -2825,6 +2825,10 @@ int diff_populate_filespec(struct diff_filespec *s, 
unsigned int flags)
s->should_free = 1;
return 0;
}
+   if (S_ISLNK(st.st_mode)) {
+   stat(s->path, );
+   s->size = xsize_t(st.st_size);
+   }
if (size_only)
return 0;
if ((flags & CHECK_BINARY) &&
@@ -3884,7 +3888,11 @@ int diff_opt_parse(struct diff_options *options,
else if (!strcmp(arg, "--no-follow")) {
DIFF_OPT_CLR(options, FOLLOW_RENAMES);
DIFF_OPT_CLR(options, DEFAULT_FOLLOW_RENAMES);
-   } else if (!strcmp(arg, "--color"))
+   } else if (!strcmp(arg, "--dereference"))
+   DIFF_OPT_SET(options, DEREFERENCE);
+   else if (!strcmp(arg, "--no-dereference"))
+   DIFF_OPT_CLR(options, DEREFERENCE);
+   else if (!strcmp(arg, "--color"))
options->use_color = 1;
else if (skip_prefix(arg, "--color=", )) {
int value = git_config_colorbool(NULL, arg);
diff --git a/diff.h b/diff.h
index 25ae60d5ff..db33dc67f6 100644
--- a/diff.h
+++ b/diff.h
@@ -69,7 +69,7 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct 
diff_options *opt, void *data)
 #define DIFF_OPT_FIND_COPIES_HARDER  (1 <<  6)
 #define DIFF_OPT_FOLLOW_RENAMES  (1 <<  7)
 #define DIFF_OPT_RENAME_EMPTY(1 <<  8)
-/* (1 <<  9) unused */
+#define DIFF_OPT_DEREFERENCE (1 <<  9)
 #define DIFF_OPT_HAS_CHANGES (1 << 10)
 #define DIFF_OPT_QUICK   (1 << 11)
 #define DIFF_OPT_NO_INDEX(1 << 12)
diff --git 

[PATCH v3 0/2] diff --no-index: support symlinks and pipes

2017-03-18 Thread Dennis Kaarsemaker
git diff <(command1) <(command2) is less useful than it could be, all it 
outputs is:

diff --git a/dev/fd/63 b/dev/fd/62
index 9e6542b297..9f7b2c291b 12
--- a/dev/fd/63
+++ b/dev/fd/62
@@ -1 +1 @@
-pipe:[464811685]
\ No newline at end of file
+pipe:[464811687]
\ No newline at end of file

Normal diff provides arguably better output: the diff of the output of the
commands. This series makes it possible for git diff --no-index to follow
symlinks and read from pipes, mimicking the behaviour of normal diff.

v1: http://public-inbox.org/git/2016201958.2175-1-den...@kaarsemaker.net/
v2: http://public-inbox.org/git/20170113102021.6054-1-den...@kaarsemaker.net/

Changes since v2, prompted by feedback from Junio:

- A --derefence option was added and the default is no longer to dereference
  symlinks.
- Instead of looking at what canon_mode returns, use the original mode of 
  files to override behaviour for pipes.
- Turn the !S_ISREG(...) check into a should_mmap_file_contents helper.

Dennis Kaarsemaker (2):
  diff --no-index: optionally follow symlinks
  diff --no-index: support reading from pipes

 Documentation/diff-options.txt |  9 +++
 diff-no-index.c| 16 ++---
 diff.c | 30 +++
 diff.h |  2 +-
 t/t4053-diff-no-index.sh   | 54 ++
 t/test-lib.sh  |  4 
 6 files changed, 107 insertions(+), 8 deletions(-)

-- 
2.12.0-437-g0cc2799



Re: [PATCH] Inconsistency between git log and git rev-parse for ^HEAD^@

2017-03-18 Thread Andreas Gruenbacher
On Sat, Mar 18, 2017 at 9:18 PM, Junio C Hamano  wrote:
> Andreas Gruenbacher  writes:
>
>> Hello,
>>
>> the log and rev-parse commands both support the rev^@ syntax which stands for
>> all parents of rev.  The log command also supports ^rev^@ to exclude all of 
>> the
>> parents of rev, but rev-parse does not.  Should this be fixed?
>>
>> If so, the following patch would be a start.
>
> Hmph, would ^A..B and ^A...B also be turned into B..A and B...A in a
> similar way?  I think the latter would not make much sense but ^A..B
> might.

The previous patch supports neither. I agree about ^A...B, and I don't
think supporting ^A..B is relevant.

> In any case, accepting ^rev^@ may make sense nevertheless.

Andreas


[PATCH v3 2/2] diff --no-index: support reading from pipes

2017-03-18 Thread Dennis Kaarsemaker
diff <(command1) <(command2) provides useful output, let's make it
possible for git to do the same.

Signed-off-by: Dennis Kaarsemaker 
---
 diff-no-index.c  |  9 +
 diff.c   | 18 --
 t/t4053-diff-no-index.sh | 10 ++
 t/test-lib.sh|  4 
 4 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/diff-no-index.c b/diff-no-index.c
index fe48f32ddd..1262a587e5 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -83,6 +83,15 @@ static struct diff_filespec *noindex_filespec(const char 
*name, int mode)
name = "/dev/null";
s = alloc_filespec(name);
fill_filespec(s, null_sha1, 0, mode);
+   /*
+* In --no-index mode, we support reading from pipes. canon_mode, 
called by
+* fill_filespec, gets confused by this and thinks we now have 
subprojects.
+* To help the rest of the diff machinery along, we now override what
+* canon_mode says. This is done here instead of in canon_mode, because 
the
+* rest of git does not (and should not) support pipes.
+*/
+   if (S_ISFIFO(mode))
+   s->mode = S_IFREG | ce_permissions(mode);
if (name == file_from_standard_input)
populate_from_stdin(s);
return s;
diff --git a/diff.c b/diff.c
index 2afecfb939..4f74a54d74 100644
--- a/diff.c
+++ b/diff.c
@@ -2765,6 +2765,11 @@ static int diff_populate_gitlink(struct diff_filespec 
*s, int size_only)
return 0;
 }
 
+static int should_mmap_file_contents(struct stat *st)
+{
+   return S_ISREG(st->st_mode);
+}
+
 /*
  * While doing rename detection and pickaxe operation, we may need to
  * grab the data for the blob (or file) for our own in-core comparison.
@@ -2839,9 +2844,18 @@ int diff_populate_filespec(struct diff_filespec *s, 
unsigned int flags)
fd = open(s->path, O_RDONLY);
if (fd < 0)
goto err_empty;
-   s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0);
+   if (!should_mmap_file_contents()) {
+   struct strbuf sb = STRBUF_INIT;
+   strbuf_read(, fd, 0);
+   s->size = sb.len;
+   s->data = strbuf_detach(, NULL);
+   s->should_free = 1;
+   }
+   else {
+   s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, 
fd, 0);
+   s->should_munmap = 1;
+   }
close(fd);
-   s->should_munmap = 1;
 
/*
 * Convert from working tree format to canonical git format
diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh
index 8c87bffb34..2d9b322315 100755
--- a/t/t4053-diff-no-index.sh
+++ b/t/t4053-diff-no-index.sh
@@ -171,4 +171,14 @@ test_expect_success SYMLINKS 'diff --no-index 
--no-dereference does not follow s
test_cmp expect actual
 '
 
+test_expect_success PROCESS_SUBSTITUTION 'diff --no-index works on fifos' '
+   cat >expect <<-EOF &&
+   @@ -1 +1 @@
+   -1
+   +2
+   EOF
+   test_expect_code 1 git diff --no-index --dereference <(echo 1) <(echo 
2) | tail -n +5 > actual &&
+   test_cmp expect actual
+'
+
 test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 11562bde10..78f3d24651 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1128,3 +1128,7 @@ build_option () {
 test_lazy_prereq LONG_IS_64BIT '
test 8 -le "$(build_option sizeof-long)"
 '
+
+test_lazy_prereq PROCESS_SUBSTITUTION '
+   eval "foo=<(echo test)" 2>/dev/null
+'
-- 
2.12.0-437-g0cc2799



[PATCH 18/20] Convert sha1_array_for_each_unique and for_each_abbrev to object_id

2017-03-18 Thread brian m. carlson
Make sha1_array_for_each_unique take a callback using struct object_id.
Since one of these callbacks is an argument to for_each_abbrev, convert
those as well.  Rename various functions, replacing "sha1" with "oid".

Signed-off-by: brian m. carlson 
---
 builtin/cat-file.c |  4 ++--
 builtin/receive-pack.c | 12 ++--
 builtin/rev-parse.c|  4 ++--
 cache.h|  2 +-
 sha1-array.c   |  4 ++--
 sha1-array.h   |  6 +++---
 sha1_name.c| 14 ++
 submodule.c| 20 ++--
 t/helper/test-sha1-array.c |  6 +++---
 9 files changed, 35 insertions(+), 37 deletions(-)

diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 8fbb667170..eb0043231d 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -401,10 +401,10 @@ struct object_cb_data {
struct expand_data *expand;
 };
 
-static int batch_object_cb(const unsigned char sha1[20], void *vdata)
+static int batch_object_cb(const struct object_id *oid, void *vdata)
 {
struct object_cb_data *data = vdata;
-   hashcpy(data->expand->oid.hash, sha1);
+   oidcpy(>expand->oid, oid);
batch_object_write(NULL, data->opt, data->expand);
return 0;
 }
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 4b282ac53e..88927a8169 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -225,10 +225,10 @@ static int receive_pack_config(const char *var, const 
char *value, void *cb)
return git_default_config(var, value, cb);
 }
 
-static void show_ref(const char *path, const unsigned char *sha1)
+static void show_ref(const char *path, const struct object_id *oid)
 {
if (sent_capabilities) {
-   packet_write_fmt(1, "%s %s\n", sha1_to_hex(sha1), path);
+   packet_write_fmt(1, "%s %s\n", oid_to_hex(oid), path);
} else {
struct strbuf cap = STRBUF_INIT;
 
@@ -244,7 +244,7 @@ static void show_ref(const char *path, const unsigned char 
*sha1)
strbuf_addstr(, " push-options");
strbuf_addf(, " agent=%s", git_user_agent_sanitized());
packet_write_fmt(1, "%s %s%c%s\n",
-sha1_to_hex(sha1), path, 0, cap.buf);
+oid_to_hex(oid), path, 0, cap.buf);
strbuf_release();
sent_capabilities = 1;
}
@@ -271,7 +271,7 @@ static int show_ref_cb(const char *path_full, const struct 
object_id *oid,
} else {
oidset_insert(seen, oid);
}
-   show_ref(path, oid->hash);
+   show_ref(path, oid);
return 0;
 }
 
@@ -284,7 +284,7 @@ static void show_one_alternate_ref(const char *refname,
if (oidset_insert(seen, oid))
return;
 
-   show_ref(".have", oid->hash);
+   show_ref(".have", oid);
 }
 
 static void write_head_info(void)
@@ -295,7 +295,7 @@ static void write_head_info(void)
for_each_alternate_ref(show_one_alternate_ref, );
oidset_clear();
if (!sent_capabilities)
-   show_ref("capabilities^{}", null_sha1);
+   show_ref("capabilities^{}", _oid);
 
advertise_shallow_grafts(1);
 
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 2549643267..24f679bd89 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -205,9 +205,9 @@ static int anti_reference(const char *refname, const struct 
object_id *oid, int
return 0;
 }
 
-static int show_abbrev(const unsigned char *sha1, void *cb_data)
+static int show_abbrev(const struct object_id *oid, void *cb_data)
 {
-   show_rev(NORMAL, sha1, NULL);
+   show_rev(NORMAL, oid->hash, NULL);
return 0;
 }
 
diff --git a/cache.h b/cache.h
index 5cdd9cd229..991d82d6f3 100644
--- a/cache.h
+++ b/cache.h
@@ -1343,7 +1343,7 @@ extern int get_sha1_with_context(const char *str, 
unsigned flags, unsigned char
 
 extern int get_oid(const char *str, struct object_id *oid);
 
-typedef int each_abbrev_fn(const unsigned char *sha1, void *);
+typedef int each_abbrev_fn(const struct object_id *oid, void *);
 extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *);
 
 extern int set_disambiguate_hint_config(const char *var, const char *value);
diff --git a/sha1-array.c b/sha1-array.c
index 1082b3dc11..82a7f4435c 100644
--- a/sha1-array.c
+++ b/sha1-array.c
@@ -43,7 +43,7 @@ void sha1_array_clear(struct sha1_array *array)
 }
 
 int sha1_array_for_each_unique(struct sha1_array *array,
-   for_each_sha1_fn fn,
+   for_each_oid_fn fn,
void *data)
 {
int i;
@@ -55,7 +55,7 @@ int sha1_array_for_each_unique(struct sha1_array *array,
int ret;
if (i > 0 && !oidcmp(array->oid + i, array->oid + i - 1))
continue;
-   ret = 

[PATCH 19/20] Rename sha1_array to oid_array

2017-03-18 Thread brian m. carlson
Since this structure handles an array of object IDs, rename it to struct
oid_array.  Also rename the accessor functions and the initialization
constant.

This commit was produced mechanically by providing non-Documentation
files to the following Perl one-liners:

perl -pi -E 's/struct sha1_array/struct oid_array/g'
perl -pi -E 's/\bsha1_array_/oid_array_/g'
perl -pi -E 's/SHA1_ARRAY_INIT/OID_ARRAY_INIT/g'

Signed-off-by: brian m. carlson 
---
 bisect.c   | 16 
 builtin/cat-file.c | 10 +-
 builtin/diff.c |  6 +++---
 builtin/fetch-pack.c   |  2 +-
 builtin/pack-objects.c | 10 +-
 builtin/pull.c |  6 +++---
 builtin/receive-pack.c | 24 +++
 builtin/send-pack.c|  4 ++--
 combine-diff.c | 12 ++--
 commit.h   | 14 +++---
 connect.c  |  8 
 diff.h |  4 ++--
 fetch-pack.c   | 26 -
 fetch-pack.h   |  4 ++--
 fsck.c |  6 +++---
 fsck.h |  2 +-
 parse-options-cb.c |  4 ++--
 ref-filter.c   |  6 +++---
 ref-filter.h   |  2 +-
 remote-curl.c  |  2 +-
 remote.h   |  6 +++---
 send-pack.c|  4 ++--
 send-pack.h|  2 +-
 sha1-array.c   | 14 +++---
 sha1-array.h   | 12 ++--
 sha1_name.c|  8 
 shallow.c  | 12 ++--
 submodule.c| 48 +++---
 submodule.h|  6 +++---
 t/helper/test-sha1-array.c | 10 +-
 transport.c| 20 +--
 31 files changed, 155 insertions(+), 155 deletions(-)

diff --git a/bisect.c b/bisect.c
index f193257509..54d69e77b9 100644
--- a/bisect.c
+++ b/bisect.c
@@ -12,8 +12,8 @@
 #include "sha1-array.h"
 #include "argv-array.h"
 
-static struct sha1_array good_revs;
-static struct sha1_array skipped_revs;
+static struct oid_array good_revs;
+static struct oid_array skipped_revs;
 
 static struct object_id *current_bad_oid;
 
@@ -413,9 +413,9 @@ static int register_ref(const char *refname, const struct 
object_id *oid,
current_bad_oid = xmalloc(sizeof(*current_bad_oid));
oidcpy(current_bad_oid, oid);
} else if (starts_with(refname, good_prefix.buf)) {
-   sha1_array_append(_revs, oid);
+   oid_array_append(_revs, oid);
} else if (starts_with(refname, "skip-")) {
-   sha1_array_append(_revs, oid);
+   oid_array_append(_revs, oid);
}
 
strbuf_release(_prefix);
@@ -451,7 +451,7 @@ static void read_bisect_paths(struct argv_array *array)
fclose(fp);
 }
 
-static char *join_sha1_array_hex(struct sha1_array *array, char delim)
+static char *join_sha1_array_hex(struct oid_array *array, char delim)
 {
struct strbuf joined_hexs = STRBUF_INIT;
int i;
@@ -499,7 +499,7 @@ struct commit_list *filter_skipped(struct commit_list *list,
while (list) {
struct commit_list *next = list->next;
list->next = NULL;
-   if (0 <= sha1_array_lookup(_revs, 
>item->object.oid)) {
+   if (0 <= oid_array_lookup(_revs, 
>item->object.oid)) {
if (skipped_first && !*skipped_first)
*skipped_first = 1;
/* Move current to tried list */
@@ -789,9 +789,9 @@ static void check_merge_bases(int no_checkout)
const struct object_id *mb = >item->object.oid;
if (!oidcmp(mb, current_bad_oid)) {
handle_bad_merge_base();
-   } else if (0 <= sha1_array_lookup(_revs, mb)) {
+   } else if (0 <= oid_array_lookup(_revs, mb)) {
continue;
-   } else if (0 <= sha1_array_lookup(_revs, mb)) {
+   } else if (0 <= oid_array_lookup(_revs, mb)) {
handle_skipped_merge_base(mb);
} else {
printf(_("Bisecting: a merge base must be tested\n"));
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index eb0043231d..1890d7a639 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -413,7 +413,7 @@ static int batch_loose_object(const struct object_id *oid,
  const char *path,
  void *data)
 {
-   sha1_array_append(data, oid);
+   oid_array_append(data, oid);
return 0;
 }
 
@@ -422,7 +422,7 @@ static int batch_packed_object(const struct object_id *oid,
   uint32_t pos,
   void *data)
 {
-   sha1_array_append(data, oid);
+   oid_array_append(data, oid);
return 0;
 

[PATCH 16/20] Convert remaining callers of sha1_array_lookup to object_id

2017-03-18 Thread brian m. carlson
There are a very small number of callers which don't already use struct
object_id.  Convert them.

Signed-off-by: brian m. carlson 
---
 bisect.c   | 14 +++---
 builtin/pack-objects.c | 16 
 ref-filter.c   | 22 +++---
 3 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/bisect.c b/bisect.c
index 886e630884..a25d008693 100644
--- a/bisect.c
+++ b/bisect.c
@@ -754,9 +754,9 @@ static void handle_bad_merge_base(void)
exit(1);
 }
 
-static void handle_skipped_merge_base(const unsigned char *mb)
+static void handle_skipped_merge_base(const struct object_id *mb)
 {
-   char *mb_hex = sha1_to_hex(mb);
+   char *mb_hex = oid_to_hex(mb);
char *bad_hex = oid_to_hex(current_bad_oid);
char *good_hex = join_sha1_array_hex(_revs, ' ');
 
@@ -787,16 +787,16 @@ static void check_merge_bases(int no_checkout)
result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1);
 
for (; result; result = result->next) {
-   const unsigned char *mb = result->item->object.oid.hash;
-   if (!hashcmp(mb, current_bad_oid->hash)) {
+   const struct object_id *mb = >item->object.oid;
+   if (!oidcmp(mb, current_bad_oid)) {
handle_bad_merge_base();
-   } else if (0 <= sha1_array_lookup(_revs, mb)) {
+   } else if (0 <= sha1_array_lookup(_revs, mb->hash)) {
continue;
-   } else if (0 <= sha1_array_lookup(_revs, mb)) {
+   } else if (0 <= sha1_array_lookup(_revs, mb->hash)) {
handle_skipped_merge_base(mb);
} else {
printf(_("Bisecting: a merge base must be tested\n"));
-   exit(bisect_checkout(mb, no_checkout));
+   exit(bisect_checkout(mb->hash, no_checkout));
}
}
 
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index dfeacd5c37..dca1b68e69 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -2670,14 +2670,14 @@ static int has_sha1_pack_kept_or_nonlocal(const 
unsigned char *sha1)
  */
 static struct sha1_array recent_objects;
 
-static int loosened_object_can_be_discarded(const unsigned char *sha1,
+static int loosened_object_can_be_discarded(const struct object_id *oid,
unsigned long mtime)
 {
if (!unpack_unreachable_expiration)
return 0;
if (mtime > unpack_unreachable_expiration)
return 0;
-   if (sha1_array_lookup(_objects, sha1) >= 0)
+   if (sha1_array_lookup(_objects, oid->hash) >= 0)
return 0;
return 1;
 }
@@ -2686,7 +2686,7 @@ static void loosen_unused_packed_objects(struct rev_info 
*revs)
 {
struct packed_git *p;
uint32_t i;
-   const unsigned char *sha1;
+   struct object_id oid;
 
for (p = packed_git; p; p = p->next) {
if (!p->pack_local || p->pack_keep)
@@ -2696,11 +2696,11 @@ static void loosen_unused_packed_objects(struct 
rev_info *revs)
die("cannot open pack index");
 
for (i = 0; i < p->num_objects; i++) {
-   sha1 = nth_packed_object_sha1(p, i);
-   if (!packlist_find(_pack, sha1, NULL) &&
-   !has_sha1_pack_kept_or_nonlocal(sha1) &&
-   !loosened_object_can_be_discarded(sha1, p->mtime))
-   if (force_object_loose(sha1, p->mtime))
+   nth_packed_object_oid(, p, i);
+   if (!packlist_find(_pack, oid.hash, NULL) &&
+   !has_sha1_pack_kept_or_nonlocal(oid.hash) &&
+   !loosened_object_can_be_discarded(, p->mtime))
+   if (force_object_loose(oid.hash, p->mtime))
die("unable to force loose object");
}
}
diff --git a/ref-filter.c b/ref-filter.c
index 9c82b5b9d6..d3dcb53dd5 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1677,22 +1677,22 @@ static int filter_pattern_match(struct ref_filter 
*filter, const char *refname)
  * the need to parse the object via parse_object(). peel_ref() might be a
  * more efficient alternative to obtain the pointee.
  */
-static const unsigned char *match_points_at(struct sha1_array *points_at,
-   const unsigned char *sha1,
-   const char *refname)
+static const struct object_id *match_points_at(struct sha1_array *points_at,
+  const struct object_id *oid,
+  const char *refname)
 {
-   const unsigned char *tagged_sha1 = NULL;
+   const struct object_id *tagged_oid = NULL;

[PATCH 17/20] Convert sha1_array_lookup to take struct object_id

2017-03-18 Thread brian m. carlson
Convert this function by changing the declaration and definition and
applying the following semantic patch to update the callers:

@@
expression E1, E2;
@@
- sha1_array_lookup(E1, E2.hash)
+ sha1_array_lookup(E1, )

@@
expression E1, E2;
@@
- sha1_array_lookup(E1, E2->hash)
+ sha1_array_lookup(E1, E2)

Signed-off-by: brian m. carlson 
---
 bisect.c   | 7 +++
 builtin/pack-objects.c | 2 +-
 fsck.c | 2 +-
 ref-filter.c   | 4 ++--
 sha1-array.c   | 4 ++--
 sha1-array.h   | 2 +-
 t/helper/test-sha1-array.c | 2 +-
 7 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/bisect.c b/bisect.c
index a25d008693..f193257509 100644
--- a/bisect.c
+++ b/bisect.c
@@ -499,8 +499,7 @@ struct commit_list *filter_skipped(struct commit_list *list,
while (list) {
struct commit_list *next = list->next;
list->next = NULL;
-   if (0 <= sha1_array_lookup(_revs,
-  list->item->object.oid.hash)) {
+   if (0 <= sha1_array_lookup(_revs, 
>item->object.oid)) {
if (skipped_first && !*skipped_first)
*skipped_first = 1;
/* Move current to tried list */
@@ -790,9 +789,9 @@ static void check_merge_bases(int no_checkout)
const struct object_id *mb = >item->object.oid;
if (!oidcmp(mb, current_bad_oid)) {
handle_bad_merge_base();
-   } else if (0 <= sha1_array_lookup(_revs, mb->hash)) {
+   } else if (0 <= sha1_array_lookup(_revs, mb)) {
continue;
-   } else if (0 <= sha1_array_lookup(_revs, mb->hash)) {
+   } else if (0 <= sha1_array_lookup(_revs, mb)) {
handle_skipped_merge_base(mb);
} else {
printf(_("Bisecting: a merge base must be tested\n"));
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index dca1b68e69..028c7be9a2 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -2677,7 +2677,7 @@ static int loosened_object_can_be_discarded(const struct 
object_id *oid,
return 0;
if (mtime > unpack_unreachable_expiration)
return 0;
-   if (sha1_array_lookup(_objects, oid->hash) >= 0)
+   if (sha1_array_lookup(_objects, oid) >= 0)
return 0;
return 1;
 }
diff --git a/fsck.c b/fsck.c
index 6682de1de5..24daedd6cc 100644
--- a/fsck.c
+++ b/fsck.c
@@ -280,7 +280,7 @@ static int report(struct fsck_options *options, struct 
object *object,
return 0;
 
if (options->skiplist && object &&
-   sha1_array_lookup(options->skiplist, object->oid.hash) 
>= 0)
+   sha1_array_lookup(options->skiplist, >oid) >= 0)
return 0;
 
if (msg_type == FSCK_FATAL)
diff --git a/ref-filter.c b/ref-filter.c
index d3dcb53dd5..4ee7ebcda3 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1684,14 +1684,14 @@ static const struct object_id *match_points_at(struct 
sha1_array *points_at,
const struct object_id *tagged_oid = NULL;
struct object *obj;
 
-   if (sha1_array_lookup(points_at, oid->hash) >= 0)
+   if (sha1_array_lookup(points_at, oid) >= 0)
return oid;
obj = parse_object(oid->hash);
if (!obj)
die(_("malformed object at '%s'"), refname);
if (obj->type == OBJ_TAG)
tagged_oid = &((struct tag *)obj)->tagged->oid;
-   if (tagged_oid && sha1_array_lookup(points_at, tagged_oid->hash) >= 0)
+   if (tagged_oid && sha1_array_lookup(points_at, tagged_oid) >= 0)
return tagged_oid;
return NULL;
 }
diff --git a/sha1-array.c b/sha1-array.c
index 26e596b264..1082b3dc11 100644
--- a/sha1-array.c
+++ b/sha1-array.c
@@ -26,11 +26,11 @@ static const unsigned char *sha1_access(size_t index, void 
*table)
return array[index].hash;
 }
 
-int sha1_array_lookup(struct sha1_array *array, const unsigned char *sha1)
+int sha1_array_lookup(struct sha1_array *array, const struct object_id *oid)
 {
if (!array->sorted)
sha1_array_sort(array);
-   return sha1_pos(sha1, array->oid, array->nr, sha1_access);
+   return sha1_pos(oid->hash, array->oid, array->nr, sha1_access);
 }
 
 void sha1_array_clear(struct sha1_array *array)
diff --git a/sha1-array.h b/sha1-array.h
index 7b06fbf1c1..4cc55b15af 100644
--- a/sha1-array.h
+++ b/sha1-array.h
@@ -11,7 +11,7 @@ struct sha1_array {
 #define SHA1_ARRAY_INIT { NULL, 0, 0, 0 }
 
 void sha1_array_append(struct sha1_array *array, const struct object_id *sha1);
-int sha1_array_lookup(struct sha1_array *array, const unsigned char *sha1);
+int sha1_array_lookup(struct sha1_array *array, const struct object_id *oid);
 void 

[PATCH 20/20] Documentation: update and rename api-sha1-array.txt

2017-03-18 Thread brian m. carlson
Since the structure and functions have changed names, update the code
examples and the documentation.  Rename the file to match the new name
of the API.

Signed-off-by: brian m. carlson 
---
 .../{api-sha1-array.txt => api-oid-array.txt}  | 44 +++---
 1 file changed, 22 insertions(+), 22 deletions(-)
 rename Documentation/technical/{api-sha1-array.txt => api-oid-array.txt} (61%)

diff --git a/Documentation/technical/api-sha1-array.txt 
b/Documentation/technical/api-oid-array.txt
similarity index 61%
rename from Documentation/technical/api-sha1-array.txt
rename to Documentation/technical/api-oid-array.txt
index dcc52943a5..b0c11f868d 100644
--- a/Documentation/technical/api-sha1-array.txt
+++ b/Documentation/technical/api-oid-array.txt
@@ -1,7 +1,7 @@
-sha1-array API
+oid-array API
 ==
 
-The sha1-array API provides storage and manipulation of sets of SHA-1
+The oid-array API provides storage and manipulation of sets of object
 identifiers. The emphasis is on storage and processing efficiency,
 making them suitable for large lists. Note that the ordering of items is
 not preserved over some operations.
@@ -9,10 +9,10 @@ not preserved over some operations.
 Data Structures
 ---
 
-`struct sha1_array`::
+`struct oid_array`::
 
-   A single array of SHA-1 hashes. This should be initialized by
-   assignment from `SHA1_ARRAY_INIT`.  The `sha1` member contains
+   A single array of object IDs. This should be initialized by
+   assignment from `OID_ARRAY_INIT`.  The `oid` member contains
the actual data. The `nr` member contains the number of items in
the set.  The `alloc` and `sorted` members are used internally,
and should not be needed by API callers.
@@ -20,22 +20,22 @@ Data Structures
 Functions
 -
 
-`sha1_array_append`::
-   Add an item to the set. The sha1 will be placed at the end of
+`oid_array_append`::
+   Add an item to the set. The object ID will be placed at the end of
the array (but note that some operations below may lose this
ordering).
 
-`sha1_array_lookup`::
-   Perform a binary search of the array for a specific sha1.
+`oid_array_lookup`::
+   Perform a binary search of the array for a specific object ID.
If found, returns the offset (in number of elements) of the
-   sha1. If not found, returns a negative integer. If the array is
-   not sorted, this function has the side effect of sorting it.
+   object ID. If not found, returns a negative integer. If the array
+   is not sorted, this function has the side effect of sorting it.
 
-`sha1_array_clear`::
+`oid_array_clear`::
Free all memory associated with the array and return it to the
initial, empty state.
 
-`sha1_array_for_each_unique`::
+`oid_array_for_each_unique`::
Efficiently iterate over each unique element of the list,
executing the callback function for each one. If the array is
not sorted, this function has the side effect of sorting it. If
@@ -47,25 +47,25 @@ Examples
 
 
 -
-int print_callback(const unsigned char sha1[20],
+int print_callback(const struct object_id *oid,
void *data)
 {
-   printf("%s\n", sha1_to_hex(sha1));
+   printf("%s\n", oid_to_hex(oid));
return 0; /* always continue */
 }
 
 void some_func(void)
 {
-   struct sha1_array hashes = SHA1_ARRAY_INIT;
-   unsigned char sha1[20];
+   struct sha1_array hashes = OID_ARRAY_INIT;
+   struct object_id oid;
 
/* Read objects into our set */
-   while (read_object_from_stdin(sha1))
-   sha1_array_append(, sha1);
+   while (read_object_from_stdin(oid.hash))
+   oid_array_append(, );
 
/* Check if some objects are in our set */
-   while (read_object_from_stdin(sha1)) {
-   if (sha1_array_lookup(, sha1) >= 0)
+   while (read_object_from_stdin(oid.hash)) {
+   if (oid_array_lookup(, ) >= 0)
printf("it's in there!\n");
 
/*
@@ -75,6 +75,6 @@ void some_func(void)
 * Instead, this will sort once and then skip duplicates
 * in linear time.
 */
-   sha1_array_for_each_unique(, print_callback, NULL);
+   oid_array_for_each_unique(, print_callback, NULL);
 }
 -


[PATCH 15/20] Make sha1_array_append take a struct object_id *

2017-03-18 Thread brian m. carlson
Convert the callers to pass struct object_id by changing the function
declaration and definition and applying the following semantic patch:

@@
expression E1, E2, E3;
@@
- sha1_array_append(E1, E2[E3].hash)
+ sha1_array_append(E1, E2 + E3)

@@
expression E1, E2;
@@
- sha1_array_append(E1, E2.hash)
+ sha1_array_append(E1, )

@@
expression E1, E2;
@@
- sha1_array_append(E1, E2->hash)
+ sha1_array_append(E1, E2)

Signed-off-by: brian m. carlson 
---
 bisect.c   | 4 ++--
 builtin/cat-file.c | 4 ++--
 builtin/diff.c | 2 +-
 builtin/pack-objects.c | 4 ++--
 builtin/pull.c | 2 +-
 builtin/receive-pack.c | 6 +++---
 combine-diff.c | 2 +-
 connect.c  | 4 ++--
 fetch-pack.c   | 8 
 fsck.c | 2 +-
 parse-options-cb.c | 2 +-
 sha1-array.c   | 4 ++--
 sha1-array.h   | 2 +-
 sha1_name.c| 2 +-
 submodule.c| 6 +++---
 t/helper/test-sha1-array.c | 2 +-
 transport.c| 6 --
 17 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/bisect.c b/bisect.c
index ebaf7b05ba..886e630884 100644
--- a/bisect.c
+++ b/bisect.c
@@ -413,9 +413,9 @@ static int register_ref(const char *refname, const struct 
object_id *oid,
current_bad_oid = xmalloc(sizeof(*current_bad_oid));
oidcpy(current_bad_oid, oid);
} else if (starts_with(refname, good_prefix.buf)) {
-   sha1_array_append(_revs, oid->hash);
+   sha1_array_append(_revs, oid);
} else if (starts_with(refname, "skip-")) {
-   sha1_array_append(_revs, oid->hash);
+   sha1_array_append(_revs, oid);
}
 
strbuf_release(_prefix);
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 8b85cb8cf0..8fbb667170 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -413,7 +413,7 @@ static int batch_loose_object(const struct object_id *oid,
  const char *path,
  void *data)
 {
-   sha1_array_append(data, oid->hash);
+   sha1_array_append(data, oid);
return 0;
 }
 
@@ -422,7 +422,7 @@ static int batch_packed_object(const struct object_id *oid,
   uint32_t pos,
   void *data)
 {
-   sha1_array_append(data, oid->hash);
+   sha1_array_append(data, oid);
return 0;
 }
 
diff --git a/builtin/diff.c b/builtin/diff.c
index 398eee00d5..a5b34eb156 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -193,7 +193,7 @@ static int builtin_diff_combined(struct rev_info *revs,
if (!revs->dense_combined_merges && !revs->combine_merges)
revs->dense_combined_merges = revs->combine_merges = 1;
for (i = 1; i < ents; i++)
-   sha1_array_append(, ent[i].item->oid.hash);
+   sha1_array_append(, [i].item->oid);
diff_tree_combined(ent[0].item->oid.hash, ,
   revs->dense_combined_merges, revs);
sha1_array_clear();
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 16517f2637..dfeacd5c37 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -2739,12 +2739,12 @@ static void record_recent_object(struct object *obj,
 const char *name,
 void *data)
 {
-   sha1_array_append(_objects, obj->oid.hash);
+   sha1_array_append(_objects, >oid);
 }
 
 static void record_recent_commit(struct commit *commit, void *data)
 {
-   sha1_array_append(_objects, commit->object.oid.hash);
+   sha1_array_append(_objects, >object.oid);
 }
 
 static void get_object_list(int ac, const char **av)
diff --git a/builtin/pull.c b/builtin/pull.c
index c007900ab5..183e377147 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -344,7 +344,7 @@ static void get_merge_heads(struct sha1_array *merge_heads)
continue;  /* invalid line: does not start with SHA1 */
if (starts_with(sb.buf + GIT_SHA1_HEXSZ, "\tnot-for-merge\t"))
continue;  /* ref is not-for-merge */
-   sha1_array_append(merge_heads, oid.hash);
+   sha1_array_append(merge_heads, );
}
fclose(fp);
strbuf_release();
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 7dfbb5f46b..4b282ac53e 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -842,7 +842,7 @@ static int update_shallow_ref(struct command *cmd, struct 
shallow_info *si)
if (si->used_shallow[i] &&
(si->used_shallow[i][cmd->index / 32] & mask) &&
!delayed_reachability_test(si, i))
-   sha1_array_append(, si->shallow->oid[i].hash);
+   sha1_array_append(, si->shallow->oid + i);
 
opt.env = 

[PATCH 14/20] sha1-array: convert internal storage for struct sha1_array to object_id

2017-03-18 Thread brian m. carlson
Make the internal storage for struct sha1_array use an array of struct
object_id internally.  Update the users of this struct which inspect its
internals.

Signed-off-by: brian m. carlson 
---
 bisect.c   | 14 +++---
 builtin/pull.c | 22 +++---
 builtin/receive-pack.c |  4 ++--
 combine-diff.c |  6 +++---
 fetch-pack.c   | 12 ++--
 fsck.c |  4 ++--
 remote-curl.c  |  2 +-
 send-pack.c|  2 +-
 sha1-array.c   | 22 +++---
 sha1-array.h   |  2 +-
 shallow.c  | 26 +-
 11 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/bisect.c b/bisect.c
index 21c3e34636..ebaf7b05ba 100644
--- a/bisect.c
+++ b/bisect.c
@@ -457,7 +457,7 @@ static char *join_sha1_array_hex(struct sha1_array *array, 
char delim)
int i;
 
for (i = 0; i < array->nr; i++) {
-   strbuf_addstr(_hexs, sha1_to_hex(array->sha1[i]));
+   strbuf_addstr(_hexs, oid_to_hex(array->oid + i));
if (i + 1 < array->nr)
strbuf_addch(_hexs, delim);
}
@@ -621,7 +621,7 @@ static void bisect_rev_setup(struct rev_info *revs, const 
char *prefix,
argv_array_pushf(_argv, bad_format, oid_to_hex(current_bad_oid));
for (i = 0; i < good_revs.nr; i++)
argv_array_pushf(_argv, good_format,
-sha1_to_hex(good_revs.sha1[i]));
+oid_to_hex(good_revs.oid + i));
argv_array_push(_argv, "--");
if (read_paths)
read_bisect_paths(_argv);
@@ -701,11 +701,11 @@ static int bisect_checkout(const unsigned char 
*bisect_rev, int no_checkout)
return run_command_v_opt(argv_show_branch, RUN_GIT_CMD);
 }
 
-static struct commit *get_commit_reference(const unsigned char *sha1)
+static struct commit *get_commit_reference(const struct object_id *oid)
 {
-   struct commit *r = lookup_commit_reference(sha1);
+   struct commit *r = lookup_commit_reference(oid->hash);
if (!r)
-   die(_("Not a valid commit name %s"), sha1_to_hex(sha1));
+   die(_("Not a valid commit name %s"), oid_to_hex(oid));
return r;
 }
 
@@ -715,9 +715,9 @@ static struct commit **get_bad_and_good_commits(int *rev_nr)
int i, n = 0;
 
ALLOC_ARRAY(rev, 1 + good_revs.nr);
-   rev[n++] = get_commit_reference(current_bad_oid->hash);
+   rev[n++] = get_commit_reference(current_bad_oid);
for (i = 0; i < good_revs.nr; i++)
-   rev[n++] = get_commit_reference(good_revs.sha1[i]);
+   rev[n++] = get_commit_reference(good_revs.oid + i);
*rev_nr = n;
 
return rev;
diff --git a/builtin/pull.c b/builtin/pull.c
index 704ce1f042..c007900ab5 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -514,7 +514,7 @@ static int run_fetch(const char *repo, const char 
**refspecs)
 /**
  * "Pulls into void" by branching off merge_head.
  */
-static int pull_into_void(const unsigned char *merge_head,
+static int pull_into_void(const struct object_id *merge_head,
const struct object_id *curr_head)
 {
/*
@@ -523,10 +523,10 @@ static int pull_into_void(const unsigned char *merge_head,
 * index/worktree changes that the user already made on the unborn
 * branch.
 */
-   if (checkout_fast_forward(EMPTY_TREE_SHA1_BIN, merge_head, 0))
+   if (checkout_fast_forward(EMPTY_TREE_SHA1_BIN, merge_head->hash, 0))
return 1;
 
-   if (update_ref("initial pull", "HEAD", merge_head, curr_head->hash, 0, 
UPDATE_REFS_DIE_ON_ERR))
+   if (update_ref("initial pull", "HEAD", merge_head->hash, 
curr_head->hash, 0, UPDATE_REFS_DIE_ON_ERR))
return 1;
 
return 0;
@@ -693,13 +693,13 @@ static int get_rebase_fork_point(struct object_id 
*fork_point, const char *repo,
  */
 static int get_octopus_merge_base(struct object_id *merge_base,
const struct object_id *curr_head,
-   const unsigned char *merge_head,
+   const struct object_id *merge_head,
const struct object_id *fork_point)
 {
struct commit_list *revs = NULL, *result;
 
commit_list_insert(lookup_commit_reference(curr_head->hash), );
-   commit_list_insert(lookup_commit_reference(merge_head), );
+   commit_list_insert(lookup_commit_reference(merge_head->hash), );
if (!is_null_oid(fork_point))
commit_list_insert(lookup_commit_reference(fork_point->hash), 
);
 
@@ -718,7 +718,7 @@ static int get_octopus_merge_base(struct object_id 
*merge_base,
  * appropriate arguments and returns its exit status.
  */
 static int run_rebase(const struct object_id *curr_head,
-   const unsigned char *merge_head,
+   const struct object_id *merge_head,
const struct 

[PATCH 13/20] builtin/pull: convert to struct object_id

2017-03-18 Thread brian m. carlson
Convert virtually all uses of unsigned char [20] to struct object_id.
Leave all the arguments that come from struct sha1_array, as these will
be converted in a later patch.

Signed-off-by: brian m. carlson 
---
 builtin/pull.c | 72 +-
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/builtin/pull.c b/builtin/pull.c
index a9f7553f30..704ce1f042 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -515,7 +515,7 @@ static int run_fetch(const char *repo, const char 
**refspecs)
  * "Pulls into void" by branching off merge_head.
  */
 static int pull_into_void(const unsigned char *merge_head,
-   const unsigned char *curr_head)
+   const struct object_id *curr_head)
 {
/*
 * Two-way merge: we treat the index as based on an empty tree,
@@ -526,7 +526,7 @@ static int pull_into_void(const unsigned char *merge_head,
if (checkout_fast_forward(EMPTY_TREE_SHA1_BIN, merge_head, 0))
return 1;
 
-   if (update_ref("initial pull", "HEAD", merge_head, curr_head, 0, 
UPDATE_REFS_DIE_ON_ERR))
+   if (update_ref("initial pull", "HEAD", merge_head, curr_head->hash, 0, 
UPDATE_REFS_DIE_ON_ERR))
return 1;
 
return 0;
@@ -647,7 +647,7 @@ static const char *get_tracking_branch(const char *remote, 
const char *refspec)
  * current branch forked from its remote tracking branch. Returns 0 on success,
  * -1 on failure.
  */
-static int get_rebase_fork_point(unsigned char *fork_point, const char *repo,
+static int get_rebase_fork_point(struct object_id *fork_point, const char 
*repo,
const char *refspec)
 {
int ret;
@@ -678,7 +678,7 @@ static int get_rebase_fork_point(unsigned char *fork_point, 
const char *repo,
if (ret)
goto cleanup;
 
-   ret = get_sha1_hex(sb.buf, fork_point);
+   ret = get_oid_hex(sb.buf, fork_point);
if (ret)
goto cleanup;
 
@@ -691,24 +691,24 @@ static int get_rebase_fork_point(unsigned char 
*fork_point, const char *repo,
  * Sets merge_base to the octopus merge base of curr_head, merge_head and
  * fork_point. Returns 0 if a merge base is found, 1 otherwise.
  */
-static int get_octopus_merge_base(unsigned char *merge_base,
-   const unsigned char *curr_head,
+static int get_octopus_merge_base(struct object_id *merge_base,
+   const struct object_id *curr_head,
const unsigned char *merge_head,
-   const unsigned char *fork_point)
+   const struct object_id *fork_point)
 {
struct commit_list *revs = NULL, *result;
 
-   commit_list_insert(lookup_commit_reference(curr_head), );
+   commit_list_insert(lookup_commit_reference(curr_head->hash), );
commit_list_insert(lookup_commit_reference(merge_head), );
-   if (!is_null_sha1(fork_point))
-   commit_list_insert(lookup_commit_reference(fork_point), );
+   if (!is_null_oid(fork_point))
+   commit_list_insert(lookup_commit_reference(fork_point->hash), 
);
 
result = reduce_heads(get_octopus_merge_bases(revs));
free_commit_list(revs);
if (!result)
return 1;
 
-   hashcpy(merge_base, result->item->object.oid.hash);
+   oidcpy(merge_base, >item->object.oid);
return 0;
 }
 
@@ -717,16 +717,16 @@ static int get_octopus_merge_base(unsigned char 
*merge_base,
  * fork point calculated by get_rebase_fork_point(), runs git-rebase with the
  * appropriate arguments and returns its exit status.
  */
-static int run_rebase(const unsigned char *curr_head,
+static int run_rebase(const struct object_id *curr_head,
const unsigned char *merge_head,
-   const unsigned char *fork_point)
+   const struct object_id *fork_point)
 {
int ret;
-   unsigned char oct_merge_base[GIT_SHA1_RAWSZ];
+   struct object_id oct_merge_base;
struct argv_array args = ARGV_ARRAY_INIT;
 
-   if (!get_octopus_merge_base(oct_merge_base, curr_head, merge_head, 
fork_point))
-   if (!is_null_sha1(fork_point) && !hashcmp(oct_merge_base, 
fork_point))
+   if (!get_octopus_merge_base(_merge_base, curr_head, merge_head, 
fork_point))
+   if (!is_null_oid(fork_point) && !oidcmp(_merge_base, 
fork_point))
fork_point = NULL;
 
argv_array_push(, "rebase");
@@ -756,8 +756,8 @@ static int run_rebase(const unsigned char *curr_head,
argv_array_push(, "--onto");
argv_array_push(, sha1_to_hex(merge_head));
 
-   if (fork_point && !is_null_sha1(fork_point))
-   argv_array_push(, sha1_to_hex(fork_point));
+   if (fork_point && !is_null_oid(fork_point))
+   argv_array_push(, oid_to_hex(fork_point));
else
argv_array_push(, sha1_to_hex(merge_head));
 
@@ -770,8 +770,8 @@ int cmd_pull(int 

Re: Shared repositories no longer securable against privilege escalation

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Fri, Mar 17, 2017 at 1:23 AM, Joe Rayhawk  wrote:
> Git has started requiring write access to the root of bare repositories
> in order to create /HEAD.lock. This is a major security problem in
> shared environments as it also entails control over the /config link
> i.e. core.hooksPath. Permission to write objects and update refs should
> be entirely separate from permission to edit hook execution logic.

[Full disclosure: I implemented core.hooksPath]

The core.hooksPath facility doesn't introduce any sort of new security
problems that didn't exist already, and if you're just focusing on the
sort of problems changing core.hooksPath might bring up you're still
vulnerable to those.

If you give me general shell access to some repo where I can write
refs and objects you can't use hooks to sanity check anything I push.
E.g. let's say you have an "update" hook which makes sure I can't push
binaries (malware) to your "master" branch. I can just push that to
some other branch, then log in and run:

echo  > /path/to/bare/repo.git/refs/heads/master

Ah ha! You might say, you'll just make that update hook run for any
branch or reference! That doesn't matter either, if you give me write
access to objects/ and refs/ I can just manually echo the objects I
want there, and then manually update the ref.

If you want to run a shared repository via ssh login where you want to
reliably execute hooks you need to either use something like Gitolite,
as Jakub points out, or e.g. set the user's shell to git-shell or some
similar facility which whitelists the commands the user can run.
Anything else is just security through obscurity.


Re: [PATCH] Inconsistency between git log and git rev-parse for ^HEAD^@

2017-03-18 Thread Junio C Hamano
Andreas Gruenbacher  writes:

> Hello,
>
> the log and rev-parse commands both support the rev^@ syntax which stands for
> all parents of rev.  The log command also supports ^rev^@ to exclude all of 
> the
> parents of rev, but rev-parse does not.  Should this be fixed?
>
> If so, the following patch would be a start.

Hmph, would ^A..B and ^A...B also be turned into B..A and B...A in a
similar way?  I think the latter would not make much sense but ^A..B
might.

In any case, accepting ^rev^@ may make sense nevertheless.



Re: [PATCH 1/2] doc/SubmittingPatches: clarify the casing convention for "area: change..."

2017-03-18 Thread Junio C Hamano
Ævar Arnfjörð Bjarmason  writes:

> ...it makes this subsequent example more succinct and clear, because
> e.g. "githooks.txt" is shorter than "git-cherry-pick.txt", and
> "clarify" is obviously a normal looking word...

Ah, that makes sense.  Thanks.



Re: [PATCH 2/8] tag: Refactor the options handling code to be less bizarro

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Sat, Mar 18, 2017 at 8:27 PM, Junio C Hamano  wrote:
> Ævar Arnfjörð Bjarmason  writes:
>
>> But I thought it was very a very bizarre pattern to set us to cmdmode
>> = 'l' when we're not in that mode at all just to, as can be seen in
>> the diff, get around a slightly more verbose one-time if-check.
>
> When I wrote my response, I viewed that setting as committing to be
> in the "list" mode, not as a workaround.  So checking with !cmdmode
> to make sure that the command line is not asking to create a tag
> makes tons of sense; the new test makes it unreadable from that
> point of view.

Makes sense. Looking at this more carefully there's never any cases
where `create_tag_object && cmdmode == 'l'` is true once we make it
past `usage_with_options`, which was the bug I introduced locally
which made this whole thing a bit confusing for me.

I'll drop this patch from v2.


Re: [PATCH 8/8] tag: Change --point-at to default to HEAD

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Sat, Mar 18, 2017 at 7:54 PM, Junio C Hamano  wrote:
> Ævar Arnfjörð Bjarmason   writes:
>
>> Change the --points-at option to default to HEAD for consistency with
>> its siblings --contains, --merged etc. which default to HEAD. This
>> changes behavior added in commit ae7706b9ac (tag: add --points-at list
>> option, 2012-02-08).
>
> Makes a lot of sense to me.
>
>> +test_expect_success '--points-at is a synonym for --points-at HEAD' '
>> + git tag --points-at >actual &&
>
> Even if "expect" is the same one established earlier, it is easier
> to read and understand individual tests if you explicitly said what
> this one expects.

Makes sense. Queued that change in my WIP v2.


[PATCH] Inconsistency between git log and git rev-parse for ^HEAD^@

2017-03-18 Thread Andreas Gruenbacher
Hello,

the log and rev-parse commands both support the rev^@ syntax which stands for
all parents of rev.  The log command also supports ^rev^@ to exclude all of the
parents of rev, but rev-parse does not.  Should this be fixed?

If so, the following patch would be a start.

Thanks,
Andreas

--

rev-parse: Add support for ^rev^@

Add support for the ^rev^@ syntax to exclude all of the parents of rev.  This
syntax is already supported by git log.

Signed-off-by: Andreas Gruenbacher 
---
 builtin/rev-parse.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 2549643..ab84c49 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -293,7 +293,7 @@ static int try_difference(const char *arg)
return 0;
 }
 
-static int try_parent_shorthands(const char *arg)
+static int try_parent_shorthands(int type, const char *arg)
 {
char *dotdot;
unsigned char sha1[20];
@@ -339,7 +339,7 @@ static int try_parent_shorthands(const char *arg)
}
 
if (include_rev)
-   show_rev(NORMAL, sha1, arg);
+   show_rev(type, sha1, arg);
for (parents = commit->parents, parent_number = 1;
 parents;
 parents = parents->next, parent_number++) {
@@ -350,7 +350,7 @@ static int try_parent_shorthands(const char *arg)
 
if (symbolic)
name = xstrfmt("%s^%d", arg, parent_number);
-   show_rev(include_parents ? NORMAL : REVERSED,
+   show_rev(include_parents ? type : !type,
 parents->item->object.oid.hash, name);
free(name);
}
@@ -896,14 +896,14 @@ int cmd_rev_parse(int argc, const char **argv, const char 
*prefix)
/* Not a flag argument */
if (try_difference(arg))
continue;
-   if (try_parent_shorthands(arg))
-   continue;
name = arg;
type = NORMAL;
if (*arg == '^') {
name++;
type = REVERSED;
}
+   if (try_parent_shorthands(type, name))
+   continue;
if (!get_sha1_with_context(name, flags, sha1, )) {
if (verify)
revs_count++;
-- 
2.7.4



Re: [PATCH 3/8] tag: Change misleading --list documentation

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Sat, Mar 18, 2017 at 7:43 PM, Junio C Hamano  wrote:
> Ævar Arnfjörð Bjarmason   writes:
>
>> However, documenting this as "-l " was never correct, as
>> these both worked before Jeff's change:
>>
>> git tag -l 'v*'
>> git tag 'v*' -l
>
> Actually, we do not particularly care about the latter, and quite
> honestly, I'd prefer we do not advertise and encourage the latter.
> Most Git commands take dashed options first and then non-dashed
> arguments, and so should "git tag".  A more important example to
> show why "-l " that pretends  is an argument to
> the option is wrong is this:

I for one do care about the latter in my CLI use. I.e. I'm fairly used
to GNU-style getopt parsing where if you type "ls foo*" and forget the
-l you don't have to "^Mb-l " to produce "ls -l foo*" as you
would on the BSD's, you just type " -l".

I don't see any reason for why we'd force users to migrate to strict
BSD-like getopt parsing for commands like tag/branch which accept
these form of arguments, although one could argue that it's worth it
for consistency with the likes of git-log might have better reasons to
require it.

I.e. are there cases where we encounter genuine ambiguities in our
option parsing because of this that don't involve the usual suspect of
e.g. pattern that starts with "-" needing " -- " to
resolve the ambiguity?

As for this patch, I don't think accurately documenting an option like
--list in terms of what it actually does is advertising and
encouraging this use. All the examples are still of the form "git tag
-l " not "git tag  -l".

I think the main point of reference documentation like this should be
to accurately and exhaustively document what something actually does.
If we'd like to change it & deprecate some mode of operation in the
future, fine, but surely the first step towards that is to document
what the command does *now*.

You should be able to look at a git command, then read the
documentation, and without having run the command or inspected the
code be confident that you understand what the command will do when
you run it.

Right now that isn't the case with "tag --list" at all, because it's
documented as taking a pattern as an argument, but that isn't how it
works.

> git tag -l --merged X 'v*'
>
> and this one
>
>> git tag --list 'v*rc*' '*2.8*'
>
>> diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
>> index 74fc82a3c0..d36cd51fe2 100755
>> --- a/t/t7004-tag.sh
>> +++ b/t/t7004-tag.sh
>> @@ -118,6 +118,18 @@ test_expect_success 'listing all tags if one exists 
>> should succeed' '
>>   git tag
>>  '
>>
>> +cat >expect <> +mytag
>> +EOF
>> +test_expect_success 'Multiple -l or --list options are equivalent to one -l 
>> option' '
>> + git tag -l -l >actual &&
>> + test_cmp expect actual &&
>> + git tag --list --list >actual &&
>> + test_cmp expect actual &&
>> + git tag --list -l --list >actual &&
>> + test_cmp expect actual
>> +'
>
> OK.  I do not care too deeply about this one, but somebody may want
> to tighten up the command line parsing to detect conflicting or
> duplicated cmdmode as an error in the future, and at that time this
> will require updating.  I am not sure if we want to promise that
> giving multiple -l will keep working.
>
>> +test_expect_success 'tag -l can accept multiple patterns interleaved with 
>> -l or --list options' '
>> + git tag -l "v1*" "v0*" >actual &&
>
> This is good thing to promise that we will keep it working.
>
>> + test_cmp expect actual &&
>> + git tag -l "v1*" --list "v0*" >actual &&
>> + test_cmp expect actual &&
>> + git tag -l "v1*" "v0*" -l --list >actual &&
>> + test_cmp expect actual
>
> I'd prefer we do *not* promise that it will keep working if you give
> pattern and then later any dashed-option like -l to the command by
> having tests like these.

To continue the above, I don't agree with this take on the issue at
all. We should as much as possible aim for full coverage on our tests,
just because something's tested for doesn't implicitly mean that
there's a future promise that the functionality will always work that
way, it's just testing for both intentional & unintentional
regressions when the code is changed.

Then if we decide to e.g. change to stricter parsing or BSD-style
parsing we'll hopefully have an exhaustive list of the cases we're
changing.

It might make sense in cases where we're testing for a feature that
might get deprecated in the future to have some test prefix for that,
i.e. similar to "test_must_fail" but "test_might_get_deprecated" or
whatever.

Although that might just as likely turn out to be a useless catalog of
things we never actually end up changing, see e.g. that TODO test for
the exit code of "git tag -l" which I removed at the start of this
series.


Re: [PATCH v2 1/2] l10n: Introduce framework for localizing man pages

2017-03-18 Thread Junio C Hamano
Jean-Noel Avila  writes:

> Providing git in localized version is a good step for general adoption
> of the tool. But as of now, if one needs to refer to the manual pages,
> they are still confronted to english. The aim is to provide
> documentation to users in their own language.

Please outline how the end result looks like here.  Where are the
localized man pages installed?  Do installers get to choose to build
and install the localization for some but not all languages and if
so how?  etc.

> signed-off-by: Jean-Noel Avila 

s/sign/Sign/;

> -man: man1 man5 man7
> +man: man1 man5 man7 man_l10n

Hmmm, at least in the early days of the topic, I'd prefer that "make
doc" and "make install" I need to run dozens of times a day from the
toplevel not to require po4a.

Thanks.


Re: [PATCH 2/8] tag: Refactor the options handling code to be less bizarro

2017-03-18 Thread Junio C Hamano
Ævar Arnfjörð Bjarmason  writes:

> But I thought it was very a very bizarre pattern to set us to cmdmode
> = 'l' when we're not in that mode at all just to, as can be seen in
> the diff, get around a slightly more verbose one-time if-check.

When I wrote my response, I viewed that setting as committing to be
in the "list" mode, not as a workaround.  So checking with !cmdmode
to make sure that the command line is not asking to create a tag
makes tons of sense; the new test makes it unreadable from that
point of view.


Re: Shared repositories no longer securable against privilege escalation

2017-03-18 Thread Jakub Narębski
W dniu 17.03.2017 o 18:12, Joe Rayhawk pisze:
> Quoting Michael Haggerty (2017-03-17 05:07:36)

>>
>> Thanks for the report. This is indeed a problem for people who want to
>> set restrictive privileges on $GIT_DIR. I'd never thought of that use
>> case, but it makes sense. Is this practice recommended somewhere or
>> required by any Git hosting tools? (I'm curious how prevalent it is.)
> 
> I had to work out the practice for my own management engine; I have
> since deployed it to around eight different mixed-use multi-user
> operations, the most significant of which is Freedesktop.org.
> 
> Without this practice, core.sharedRepository is an enormous liability
> of a feature. I can't speak to whether anyone but me ever noticed, what
> with mixed-use multi-user POSIX environments becoming increasingly rare.

Is there a reason why you rely on file permissions and user groups
to enforce access control, instead of using public-key based solution
such as Gitolite?

-- 
Jakub Narębski



Re: How do I make 'git diff --no-index' follow symlinks?

2017-03-18 Thread Junio C Hamano
Sounds like

https://public-inbox.org/git/2016201958.2175-1-den...@kaarsemaker.net/

to me.  A key message in the thread may be:

https://public-inbox.org/git/alpine.DEB.2.20.1611121106110.3746@virtualbox/


Re: [PATCH] pickaxe: fix segfault with '-S<...> --pickaxe-regex'

2017-03-18 Thread Junio C Hamano
Junio C Hamano  writes:

> Interestingly, the new test fails (with the patch) under prove but
> not when run from the shell (i.e. "cd t && sh t4062-diff-pickaxe.sh").

Sorry, false alarm.


Re: [PATCH 1/2] doc/SubmittingPatches: clarify the casing convention for "area: change..."

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Sat, Mar 18, 2017 at 8:04 PM, Junio C Hamano  wrote:
> Ævar Arnfjörð Bjarmason   writes:
>
>>  prefix the first line with "area: " where the area is a filename or
>>  identifier for the general area of the code being modified, e.g.
>>
>> -  . archive: ustar header checksum is computed unsigned
>> -  . git-cherry-pick.txt: clarify the use of revision range notation
>> +  . doc: clarify distinction between sign-off and pgp-signing
>> +  . githooks.txt: improve the intro section
>
> Sorry, but I fail to spot why this is an improvement (it is not
> making things worse, either).

Because...

>>  If in doubt which identifier to use, run "git log --no-merges" on the
>>  files you are modifying to see the current conventions.
>>
>> +It's customary to start the remainder of the first line after "area: "
>> +with a lower-case letter. E.g. "doc: clarify...", not "doc:
>> +Clarify...", or "githooks.txt: improve...", not "githooks.txt:
>> +Improve...".

...it makes this subsequent example more succinct and clear, because
e.g. "githooks.txt" is shorter than "git-cherry-pick.txt", and
"clarify" is obviously a normal looking word which you'd expect to be
capitalized after a full stop, but it might take a couple of readings
to understand that "unstar" without a hyphen isn't some jargon.


Re: [PATCH 2/8] tag: Refactor the options handling code to be less bizarro

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Sat, Mar 18, 2017 at 7:35 PM, Junio C Hamano  wrote:
> Ævar Arnfjörð Bjarmason   writes:
>
>> diff --git a/builtin/tag.c b/builtin/tag.c
>> index ad29be6923..0bba3fd070 100644
>> --- a/builtin/tag.c
>> +++ b/builtin/tag.c
>> @@ -454,10 +454,10 @@ int cmd_tag(int argc, const char **argv, const char 
>> *prefix)
>>   }
>>   create_tag_object = (opt.sign || annotate || msg.given || msgfile);
>>
>> - if (argc == 0 && !cmdmode)
>> + if (argc == 0 && !cmdmode && !create_tag_object)
>>   cmdmode = 'l';
>
> So with this change, if we cannot infer that we are creating a tag
> object from other options, we leave cmdmode to its original 0.
>
>> - if ((create_tag_object || force) && (cmdmode != 0))
>> + if ((create_tag_object || force) && (cmdmode || (!cmdmode && !argc)))
>>   usage_with_options(git_tag_usage, options);
>
> And then immediately after that, we complain by detecting that we
> know we are creating a tag and a non-zero cmdmode is in effect
> (i.e. 'l', 'd' or 'v', none of which is about creating a tag).  The
> way we used to detect that we are doing something other than tag
> creation was by seeing cmdmode is set to anything.  Because of your
> earlier change, that no longer is true.  You need to separately
> check (!cmdmode && !argc).
>
> By following the logic that way, I can see how this change at this
> step is a no-op, but I have to say that the code with this patch
> looks much more bizarre than the original.
>
> I am not sure why you want to do the first change at this step in
> the first place.  Is it because you'd want to take over (!cmdmode &&
> !argc) condtion to default to 'list'?  With the change in 4/8 and
> 5/8, you are ensuring that cmdmode is set to 'l' for these new cases
> before the code hits the check to call usage_with_options().  And at
> that point, you can use the original "are we creating and !cmdmode
> says we are not?  That's contradiction" logic without making it more
> bizarre with this patch, no?

Nothing about this patch is needed for the rest of the series. I just
tried rebasing it out now and all tests pass & everything works as
expected.

The reason I'm submitting it is because while this works *now* and
there's no cases I can see currently where cmdmode is 'l' after the
current `((create_tag_object || force) && (cmdmode != 0))`, during a
lengthy debugging session when I was hacking on a subsequent patch in
this series it took me a long time to track down a segfault later in
the file because surely it was impossible that I was in cmdmode = 'l'
with only "git tag -a".

Partly that was late night hacking session blindness after having read
the !argc and assuming that the -a would be counted towards argc.

But I thought it was very a very bizarre pattern to set us to cmdmode
= 'l' when we're not in that mode at all just to, as can be seen in
the diff, get around a slightly more verbose one-time if-check.

So I think it's worth it to include this for less confusion in any
subsequent patches to tag.c.


How do I make 'git diff --no-index' follow symlinks?

2017-03-18 Thread Ævar Arnfjörð Bjarmason
I'd like to (ab)use git's nice diff interface and make this work:

git --no-pager diff --no-index <(echo foo) <(echo bar)

It just prints:

-pipe:[203030063]
+pipe:[203030065]

But I want:

$ diff -u0 <(echo foo) <(echo bar)|tail -n 2
-foo
+bar

I went diving through the diff code for a bit, but couldn't find where
it's stat()-ing the two files and deciding it's not going to follow
symlinks.

Just having some option to follow symlinks would make this work.


Re: [PATCH 2/2] doc/SubmittingPatches: show how to get a CLI commit summary

2017-03-18 Thread Junio C Hamano
Ævar Arnfjörð Bjarmason   writes:

>  The "Copy commit summary" command of gitk can be used to obtain this
> -format.
> +format, or this invocation of "git show":
>  
> +git show -s --date=format:%Y-%m-%d --pretty='commit %h ("%s", %ad)' 
> 

I've seen (I think I stole it from Peff) this one recommended often
on the list, which is shorter:

$ git show --date=short -s --pretty='format:%h ("%s", %ad)' 





Re: [PATCH 1/2] doc/SubmittingPatches: clarify the casing convention for "area: change..."

2017-03-18 Thread Junio C Hamano
Ævar Arnfjörð Bjarmason   writes:

>  prefix the first line with "area: " where the area is a filename or
>  identifier for the general area of the code being modified, e.g.
>  
> -  . archive: ustar header checksum is computed unsigned
> -  . git-cherry-pick.txt: clarify the use of revision range notation
> +  . doc: clarify distinction between sign-off and pgp-signing
> +  . githooks.txt: improve the intro section

Sorry, but I fail to spot why this is an improvement (it is not
making things worse, either).

>  If in doubt which identifier to use, run "git log --no-merges" on the
>  files you are modifying to see the current conventions.
>  
> +It's customary to start the remainder of the first line after "area: "
> +with a lower-case letter. E.g. "doc: clarify...", not "doc:
> +Clarify...", or "githooks.txt: improve...", not "githooks.txt:
> +Improve...".



Re: [PATCH] pickaxe: fix segfault with '-S<...> --pickaxe-regex'

2017-03-18 Thread Junio C Hamano
Interestingly, the new test fails (with the patch) under prove but
not when run from the shell (i.e. "cd t && sh t4062-diff-pickaxe.sh").



Re: [PATCH 8/8] tag: Change --point-at to default to HEAD

2017-03-18 Thread Junio C Hamano
Ævar Arnfjörð Bjarmason   writes:

> Change the --points-at option to default to HEAD for consistency with
> its siblings --contains, --merged etc. which default to HEAD. This
> changes behavior added in commit ae7706b9ac (tag: add --points-at list
> option, 2012-02-08).

Makes a lot of sense to me.

> +test_expect_success '--points-at is a synonym for --points-at HEAD' '
> + git tag --points-at >actual &&

Even if "expect" is the same one established earlier, it is easier
to read and understand individual tests if you explicitly said what
this one expects.

Thanks.


Re: Is there a way to have a local version of a header file?

2017-03-18 Thread Jakub Narębski
W dniu 18.03.2017 o 18:08, Ævar Arnfjörð Bjarmason pisze:

> There might be some way I haven't thought of, in particular maybe you
> can use gitattributes to define a custom diff/merge driver that always
> reports no changes, or some ways to (ab)use the index to make git
> ignore any changes to the file.

There is `git update-index --skip-worktree` (originally meant for
sparse checkout), which you can use to kind of ignore changes to
tracked file, in a safe way (though sometimes annoying, when it
prevents stashing changes).

There is also an existing solution of a hook that prevents commiting
files with passwords in them; I forgot the name...

HTH,
-- 
Jakub Narębski



Re: [PATCH 3/8] tag: Change misleading --list documentation

2017-03-18 Thread Junio C Hamano
Ævar Arnfjörð Bjarmason   writes:

> However, documenting this as "-l " was never correct, as
> these both worked before Jeff's change:
>
> git tag -l 'v*'
> git tag 'v*' -l

Actually, we do not particularly care about the latter, and quite
honestly, I'd prefer we do not advertise and encourage the latter.
Most Git commands take dashed options first and then non-dashed
arguments, and so should "git tag".  A more important example to
show why "-l " that pretends  is an argument to
the option is wrong is this:

git tag -l --merged X 'v*'

and this one

> git tag --list 'v*rc*' '*2.8*'

> diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
> index 74fc82a3c0..d36cd51fe2 100755
> --- a/t/t7004-tag.sh
> +++ b/t/t7004-tag.sh
> @@ -118,6 +118,18 @@ test_expect_success 'listing all tags if one exists 
> should succeed' '
>   git tag
>  '
>  
> +cat >expect < +mytag
> +EOF
> +test_expect_success 'Multiple -l or --list options are equivalent to one -l 
> option' '
> + git tag -l -l >actual &&
> + test_cmp expect actual &&
> + git tag --list --list >actual &&
> + test_cmp expect actual &&
> + git tag --list -l --list >actual &&
> + test_cmp expect actual
> +'

OK.  I do not care too deeply about this one, but somebody may want
to tighten up the command line parsing to detect conflicting or
duplicated cmdmode as an error in the future, and at that time this
will require updating.  I am not sure if we want to promise that
giving multiple -l will keep working.

> +test_expect_success 'tag -l can accept multiple patterns interleaved with -l 
> or --list options' '
> + git tag -l "v1*" "v0*" >actual &&

This is good thing to promise that we will keep it working.

> + test_cmp expect actual &&
> + git tag -l "v1*" --list "v0*" >actual &&
> + test_cmp expect actual &&
> + git tag -l "v1*" "v0*" -l --list >actual &&
> + test_cmp expect actual

I'd prefer we do *not* promise that it will keep working if you give
pattern and then later any dashed-option like -l to the command by
having tests like these.

Thanks.


[PATCH 2/2] doc/SubmittingPatches: show how to get a CLI commit summary

2017-03-18 Thread Ævar Arnfjörð Bjarmason
Amend the section which describes how to get a commit summary to show
how do to that with "git show", currently the documentation only shows
how to do that with gitk.

Signed-off-by: Ævar Arnfjörð Bjarmason 
---
 Documentation/SubmittingPatches | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 9ef624ce38..78c8e36a4b 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -134,8 +134,17 @@ with the subject enclosed in a pair of double-quotes, like 
this:
 noticed that ...
 
 The "Copy commit summary" command of gitk can be used to obtain this
-format.
+format, or this invocation of "git show":
 
+git show -s --date=format:%Y-%m-%d --pretty='commit %h ("%s", %ad)' 

+
+To turn that into a handy alias:
+
+git config --global alias.git-commit-summary "show -s 
--date=format:%Y-%m-%d --pretty='commit %h (\"%s\", %ad)'"
+
+And then to get the commit summary:
+
+git git-commit-summary 
 
 (3) Generate your patch using Git tools out of your commits.
 
-- 
2.11.0



Re: [BUG] "git stash -- path" reports wrong unstaged changes

2017-03-18 Thread Thomas Gummerer
On 03/17, Jeff King wrote:
> I used "git stash -- path" for the first time today and happened to
> notice an oddity. If I run:
> 
>   git init -q repo
>   cd repo
>   
>   for i in one two; do
>   echo content >$i
>   git add $i
>   done
>   git commit -qm base
>   
>   for i in one two; do
>   echo change >$i
>   done
>   git stash -- one
> 
> it says:
> 
>   Saved working directory and index state WIP on master: 20cfadf base
>   Unstaged changes after reset:
>   M   one
>   M   two
> 
> Even though "one" no longer has unstaged changes.

Yeah, this is clearly not right.  Thanks for catching this before it
got into any release.

> If I run with GIT_TRACE=1, that message is generated by:
> 
>   git reset -- one
> 
> which makes sense. At that stage we've just reset the index, but the
> working tree file still has modifications. In the non-pathspec case we
> run "git reset --hard", which takes care of the index and the working
> tree.
> 
> It's really "checkout-index" that cleans the working tree, but it
> doesn't have porcelain finery like an "Unstaged changes" message. I
> think the patch below would fix it, but I wonder if we can do it in a
> way that doesn't involve calling diff-files twice.
> 
> -Peff
> 
> ---
> diff --git a/git-stash.sh b/git-stash.sh
> index 9c70662cc..9a4bb503a 100755
> --- a/git-stash.sh
> +++ b/git-stash.sh
> @@ -299,10 +299,15 @@ push_stash () {
>   then
>   if test $# != 0
>   then
> - git reset ${GIT_QUIET:+-q} -- "$@"
> + git reset -q -- "$@"
>   git ls-files -z --modified -- "$@" |
>   git checkout-index -z --force --stdin
>   git clean --force ${GIT_QUIET:+-q} -d -- "$@"
> + if test -z "$GIT_QUIET" && ! git diff-files --quiet
> + then
> + say "$(gettext "Unstaged changes after reset:")"
> + git diff-files --name-status
> + fi
>   else
>   git reset --hard ${GIT_QUIET:+-q}
>   fi

This would mean the user gets something like in your case above:

Unstaged changes after reset:
 M  two

As a user that doesn't know the internal implementation of push_stash,
this would make me wonder why git stash would mention a file that is
not provided as pathspec, but not the one that was provided in the
pathspec argument.

I think one option would be to to just keep quiet about the exact
changes that git stash push makes, similar to what we do in the
--include-untracked and in the -p case.  The other option would be to
find the files that are affected and print them, but that would
probably be a bit too noisy especially in cases such as
git stash push -- docs/*.

Also from reading the code in the -p case, when --keep-index is given,
the git reset there doesn't respect $GIT_QUIET at all, and also
doesn't respect the pathspec argument, which seems like another bug.
I can submit a patch series for those, but I won't get to it before
tomorrow :)


[PATCH 0/2] doc/SubmittingPatches: A couple of minor improvements

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Sat, Mar 18, 2017 at 7:14 PM, Junio C Hamano  wrote:
> I'll retitle s/Remove/remove/ so that "git shortlog --no-merges"
> would look more consistent, though.

I already found a few grammar / phrasing issues with the commit
messages, so I'll just change this on my side for a resend.

But I noticed that this casing rule wasn't documented in
SubmittingPatches, so here's a patch for that, and while I'm at it
another small improvement that I've been meaning to make to it based
on a local alias I have.

Ævar Arnfjörð Bjarmason (2):
  doc/SubmittingPatches: clarify the casing convention for "area:
change..."
  doc/SubmittingPatches: show how to get a CLI commit summary

 Documentation/SubmittingPatches | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

-- 
2.11.0



[PATCH 1/2] doc/SubmittingPatches: clarify the casing convention for "area: change..."

2017-03-18 Thread Ævar Arnfjörð Bjarmason
Amend the section which describes how the first line of the subject
should look like to say that the ":" in "area: " shouldn't be treated
like a full stop for the purposes of letter casing.

Change the two subject examples to make this new paragraph clearer,
i.e. "unstar" is not a common word, and "git-cherry-pick.txt" is a
much longer string than "githooks.txt". Pick two recent commits from
git.git that fit better for the description.

Signed-off-by: Ævar Arnfjörð Bjarmason 
---
 Documentation/SubmittingPatches | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 3faf7eb884..9ef624ce38 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -98,12 +98,17 @@ should skip the full stop.  It is also conventional in most 
cases to
 prefix the first line with "area: " where the area is a filename or
 identifier for the general area of the code being modified, e.g.
 
-  . archive: ustar header checksum is computed unsigned
-  . git-cherry-pick.txt: clarify the use of revision range notation
+  . doc: clarify distinction between sign-off and pgp-signing
+  . githooks.txt: improve the intro section
 
 If in doubt which identifier to use, run "git log --no-merges" on the
 files you are modifying to see the current conventions.
 
+It's customary to start the remainder of the first line after "area: "
+with a lower-case letter. E.g. "doc: clarify...", not "doc:
+Clarify...", or "githooks.txt: improve...", not "githooks.txt:
+Improve...".
+
 The body should provide a meaningful commit message, which:
 
   . explains the problem the change tries to solve, iow, what is wrong
-- 
2.11.0



Re: [PATCH 2/8] tag: Refactor the options handling code to be less bizarro

2017-03-18 Thread Junio C Hamano
Ævar Arnfjörð Bjarmason   writes:

> diff --git a/builtin/tag.c b/builtin/tag.c
> index ad29be6923..0bba3fd070 100644
> --- a/builtin/tag.c
> +++ b/builtin/tag.c
> @@ -454,10 +454,10 @@ int cmd_tag(int argc, const char **argv, const char 
> *prefix)
>   }
>   create_tag_object = (opt.sign || annotate || msg.given || msgfile);
>  
> - if (argc == 0 && !cmdmode)
> + if (argc == 0 && !cmdmode && !create_tag_object)
>   cmdmode = 'l';

So with this change, if we cannot infer that we are creating a tag
object from other options, we leave cmdmode to its original 0.

> - if ((create_tag_object || force) && (cmdmode != 0))
> + if ((create_tag_object || force) && (cmdmode || (!cmdmode && !argc)))
>   usage_with_options(git_tag_usage, options);

And then immediately after that, we complain by detecting that we
know we are creating a tag and a non-zero cmdmode is in effect
(i.e. 'l', 'd' or 'v', none of which is about creating a tag).  The
way we used to detect that we are doing something other than tag
creation was by seeing cmdmode is set to anything.  Because of your
earlier change, that no longer is true.  You need to separately
check (!cmdmode && !argc).

By following the logic that way, I can see how this change at this
step is a no-op, but I have to say that the code with this patch
looks much more bizarre than the original.

I am not sure why you want to do the first change at this step in
the first place.  Is it because you'd want to take over (!cmdmode &&
!argc) condtion to default to 'list'?  With the change in 4/8 and
5/8, you are ensuring that cmdmode is set to 'l' for these new cases
before the code hits the check to call usage_with_options().  And at
that point, you can use the original "are we creating and !cmdmode
says we are not?  That's contradiction" logic without making it more
bizarre with this patch, no?


[PATCHv2] pickaxe: fix segfault with '-S<...> --pickaxe-regex'

2017-03-18 Thread SZEDER Gábor
'git {log,diff,...} -S<...> --pickaxe-regex' can segfault as a result
of out-of-bounds memory reads.

diffcore-pickaxe.c:contains() looks for all matches of the given regex
in a buffer in a loop, advancing the buffer pointer to the end of the
last match in each iteration.  When we switched to REG_STARTEND in
b7d36ffca (regex: use regexec_buf(), 2016-09-21), we started passing
the size of that buffer to the regexp engine, too.  Unfortunately,
this buffer size is never updated on subsequent iterations, and as the
buffer pointer advances on each iteration, this "bufptr+bufsize"
points past the end of the buffer.  This results in segmentation
fault, if that memory can't be accessed.  In case of 'git log' it can
also result in erroneously listed commits, if the memory past the end
of buffer is accessible and happens to contain data matching the
regex.

Reduce the buffer size on each iteration as the buffer pointer is
advanced, thus maintaining the correct end of buffer location.
Furthermore, make sure that the buffer pointer is not dereferenced in
the control flow statements when we already reached the end of the
buffer.

The new test is flaky, I've never seen it fail on my Linux box even
without the fix, but this is expected according to db5dfa3 (regex:
-G feeds a non NUL-terminated string to regexec() and fails,
2016-09-21).  However, it did fail on Travis CI with the first (and
incomplete) version of the fix, and based on that commit message I
would expect the new test without the fix to fail most of the time on
Windows.

Signed-off-by: SZEDER Gábor 
---

Changes since v1:

 diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
 index 03f84b714..341529b5a 100644
 --- a/diffcore-pickaxe.c
 +++ b/diffcore-pickaxe.c
 @@ -81,12 +81,12 @@ static unsigned int contains(mmfile_t *mf, regex_t 
*regexp, kwset_t kws)
regmatch_t regmatch;
int flags = 0;
  
 -  while (*data &&
 +  while (sz && *data &&
   !regexec_buf(regexp, data, sz, 1, , flags)) {
flags |= REG_NOTBOL;
data += regmatch.rm_eo;
sz -= regmatch.rm_eo;
 -  if (*data && regmatch.rm_so == regmatch.rm_eo) {
 +  if (sz && *data && regmatch.rm_so == regmatch.rm_eo) {
data++;
sz--;
}

 diffcore-pickaxe.c  | 7 +--
 t/t4062-diff-pickaxe.sh | 5 +
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index 9795ca1c1..341529b5a 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -81,12 +81,15 @@ static unsigned int contains(mmfile_t *mf, regex_t *regexp, 
kwset_t kws)
regmatch_t regmatch;
int flags = 0;
 
-   while (*data &&
+   while (sz && *data &&
   !regexec_buf(regexp, data, sz, 1, , flags)) {
flags |= REG_NOTBOL;
data += regmatch.rm_eo;
-   if (*data && regmatch.rm_so == regmatch.rm_eo)
+   sz -= regmatch.rm_eo;
+   if (sz && *data && regmatch.rm_so == regmatch.rm_eo) {
data++;
+   sz--;
+   }
cnt++;
}
 
diff --git a/t/t4062-diff-pickaxe.sh b/t/t4062-diff-pickaxe.sh
index f0bf50bda..7c4903f49 100755
--- a/t/t4062-diff-pickaxe.sh
+++ b/t/t4062-diff-pickaxe.sh
@@ -19,4 +19,9 @@ test_expect_success '-G matches' '
test 4096-zeroes.txt = "$(cat out)"
 '
 
+test_expect_success '-S --pickaxe-regex' '
+   git diff --name-only -S0 --pickaxe-regex HEAD^ >out &&
+   verbose test 4096-zeroes.txt = "$(cat out)"
+'
+
 test_done
-- 
2.12.0.377.g15f6ffe90


Re: [PATCH 1/8] tag: Remove a TODO item from the test suite

2017-03-18 Thread Junio C Hamano
Ævar Arnfjörð Bjarmason   writes:

> Change the test for "git tag -l" to not have an associated TODO
> comment saying that it should return non-zero if there's no tags.
>
> This was added in commit ef5a6fb597 ("Add test-script for git-tag",
> 2007-06-28) when the tests for "tag" were initially added, but at this
> point changing this would be inconsistent with how "git tag" is a
> synonym for "git tag -l", and would needlessly break external code
> that relies on this porcelain command.

Makes sense.

I'll retitle s/Remove/remove/ so that "git shortlog --no-merges"
would look more consistent, though.

Thanks.


Re: Is there a way to have a local version of a header file?

2017-03-18 Thread Junio C Hamano
Ævar Arnfjörð Bjarmason  writes:

> There might be some way I haven't thought of, in particular maybe you
> can use gitattributes to define a custom diff/merge driver that always
> reports no changes, or some ways to (ab)use the index to make git
> ignore any changes to the file.

Why does this have to be so difficult?

Ship a config.h.sample file, have a Makefile rule that is forced to
run before any compilation happens that checks if config.h exists
and then created it if missing by copying config.h.sample over, and
then all other source files can include config.h without having to
know anything about config.h.sample's existence.

Did I miss something?


Re: [PATCH v2 12/12] rev-list: expose and document --single-worktree

2017-03-18 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy   writes:

> ---

Missing sign-off.

>  Documentation/rev-list-options.txt | 8 
>  revision.c | 2 ++
>  2 files changed, 10 insertions(+)
>
> diff --git a/Documentation/rev-list-options.txt 
> b/Documentation/rev-list-options.txt
> index a02f7324c0..c71e94b2d0 100644
> --- a/Documentation/rev-list-options.txt
> +++ b/Documentation/rev-list-options.txt
> @@ -179,6 +179,14 @@ explicitly.
>   Pretend as if all objects mentioned by reflogs are listed on the
>   command line as ``.
>  
> +--single-worktree::
> + By default, all working trees will be examined by the

s/working tree/worktree/?

> + following options when there are more than one (see
> + linkgit:git-worktree[1]): `--all`, `--reflog` and
> + `--indexed-objects`.
> + This option forces them to examine the current working tree
> + only.
> +
>  --ignore-missing::
>   Upon seeing an invalid object name in the input, pretend as if
>   the bad input was not given.
> diff --git a/revision.c b/revision.c
> index fcf165bd76..dc32e99c54 100644
> --- a/revision.c
> +++ b/revision.c
> @@ -,6 +,8 @@ static int handle_revision_pseudo_opt(const char 
> *submodule,
>   return error("invalid argument to --no-walk");
>   } else if (!strcmp(arg, "--do-walk")) {
>   revs->no_walk = 0;
> + } else if (!strcmp(arg, "--single-worktree")) {
> + revs->single_worktree = 1;
>   } else {
>   return 0;
>   }


Re: [PATCH v3 1/4] environment.c: fix potential segfault by get_git_common_dir()

2017-03-18 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy   writes:

> setup_git_env() must be called before this function to initialize
> git_common_dir so that it returns a non NULL string. And it must return
> a non NULL string or segfault can happen because all callers expect so.
>
> Normally if somebody has called get_git_dir(), or set_git_dir() then
> setup_git_env() is already called. But if you do setup_git_directory()
> at top dir (which skips set_git_dir) and never call get_git_dir, you'll
> get NULL here.

Hmph, and the solution for the problem not being "so let's make sure
get_git_dir() is called even when the command is started at the top
directory" is because...?

> test-ref-store.c will hit this problem because it's very lightweight,
> just enough initialization to exercise refs code, and get_git_dir() will
> never be called until get_worktrees() is, which uses get_git_common_dir().
> ---

Missing sign-off.



>  environment.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/environment.c b/environment.c
> index 42dc3106d2..2986ee7200 100644
> --- a/environment.c
> +++ b/environment.c
> @@ -214,6 +214,8 @@ const char *get_git_dir(void)
>  
>  const char *get_git_common_dir(void)
>  {
> + if (!git_dir)
> + setup_git_env();
>   return git_common_dir;
>  }


[PATCH v2 2/2] l10n: Add git-add.txt to localized man pages

2017-03-18 Thread Jean-Noel Avila
Signed-off-by: Jean-Noel Avila 
---
 Documentation/po/documentation.fr.po | 1095 ++
 Documentation/po/documentation.pot   |  787 
 2 files changed, 1882 insertions(+)
 create mode 100644 Documentation/po/documentation.fr.po
 create mode 100644 Documentation/po/documentation.pot

diff --git a/Documentation/po/documentation.fr.po 
b/Documentation/po/documentation.fr.po
new file mode 100644
index 0..3017da0c9
--- /dev/null
+++ b/Documentation/po/documentation.fr.po
@@ -0,0 +1,1095 @@
+# French translations for Git Manual Pages.
+# Copyright (C) 2017 Jean-Noël Avila 
+# This file is distributed under the same license as the Git package.
+# Jean-Noël Avila , 2016.
+msgid ""
+msgstr ""
+"Project-Id-Version: git documentation\n"
+"POT-Creation-Date: 2017-03-03 21:18+0100\n"
+"PO-Revision-Date: 2017-03-15 21:42+0100\n"
+"Last-Translator: Jean-Noël Avila \n"
+"Language-Team: Jean-Noël Avila \n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: Title =
+#: git-add.txt:2
+#, no-wrap
+msgid "git-add(1)"
+msgstr "git-add(1)"
+
+#. type: Title -
+#: git-add.txt:5
+#, no-wrap
+msgid "NAME"
+msgstr "NOM"
+
+#
+#. type: Plain text
+#: git-add.txt:7
+msgid "git-add - Add file contents to the index"
+msgstr "git-add - Ajoute le contenu de fichiers à l'index"
+
+#. type: Title -
+#: git-add.txt:9
+#, no-wrap
+msgid "SYNOPSIS"
+msgstr "SYNOPSIS"
+
+#. type: Plain text
+#: git-add.txt:15
+#, no-wrap
+msgid ""
+"'git add' [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | 
-i] [--patch | -p]\n"
+"\t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n"
+"\t  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]\n"
+"\t  [--chmod=(+|-)x] [--] [...]\n"
+msgstr ""
+"'git add' [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | 
-i] [--patch | -p]\n"
+"\t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n"
+"\t  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]\n"
+"\t  [--chmod=(+|-)x] [--] [...]\n"
+
+#. type: Title -
+#: git-add.txt:17
+#, no-wrap
+msgid "DESCRIPTION"
+msgstr "DESCRIPTION"
+
+#
+#. type: Plain text
+#: git-add.txt:24
+msgid ""
+"This command updates the index using the current content found in the "
+"working tree, to prepare the content staged for the next commit.  It "
+"typically adds the current content of existing paths as a whole, but with "
+"some options it can also be used to add content with only part of the "
+"changes made to the working tree files applied, or remove paths that do not "
+"exist in the working tree anymore."
+msgstr ""
+"Cette commande met à jour l'index en utilisant le contenu actuel trouvé dans "
+"la copie de travail, pour préparer le contenu de la prochaine validation. "
+"Typiquement, elle ajoute intégralement le contenu actuel des chemins "
+"existant, mais peut aussi n'ajouter que certaines parties des modifications "
+"au moyen d'options ou soustraire certains chemins qui n'existent plus dans "
+"la copie de travail."
+
+#
+#. type: Plain text
+#: git-add.txt:30
+msgid ""
+"The \"index\" holds a snapshot of the content of the working tree, and it is "
+"this snapshot that is taken as the contents of the next commit.  Thus after "
+"making any changes to the working tree, and before running the commit "
+"command, you must use the `add` command to add any new or modified files to "
+"the index."
+msgstr ""
+"L'« index » contient un instantané du contenu de la copie de travail et "
+"c'est cet instantané qui sera utilisé comme contenu du prochain commit.  "
+"Ainsi, après avoir réalisé des modifications dans la copie de travail, et "
+"avant de lancer la commande commit, vous devez utiliser la commande `add` "
+"pour ajouter tout fichier nouveau ou modifié à l'index."
+
+#
+#. type: Plain text
+#: git-add.txt:35
+msgid ""
+"This command can be performed multiple times before a commit.  It only adds "
+"the content of the specified file(s) at the time the add command is run; if "
+"you want subsequent changes included in the next commit, then you must run "
+"`git add` again to add the new content to the index."
+msgstr ""
+"Cette commande peut être effectuée plusieurs fois avant la validation.  Elle "
+"n'ajoute que le contenu des fichiers spécifiés au moment où la commande "
+"`add` est lancée ; si vous souhaitez inclure des modifications postérieures "
+"à un `add` dans la prochaine validation, vous devez alors lancer `git add` à "
+"nouveau pour ajouter le nouveau contenu à l'index."
+
+#
+#. type: Plain text
+#: git-add.txt:38
+msgid ""
+"The `git status` command can be used to obtain a summary of which files have "
+"changes that are staged for the next commit."
+msgstr ""
+"La commande `git status` permet 

[PATCH v2 1/2] l10n: Introduce framework for localizing man pages

2017-03-18 Thread Jean-Noel Avila
Providing git in localized version is a good step for general adoption
of the tool. But as of now, if one needs to refer to the manual pages,
they are still confronted to english. The aim is to provide
documentation to users in their own language.

signed-off-by: Jean-Noel Avila 
---
 Documentation/Makefile  | 23 +--
 Documentation/po4a.conf |  5 +
 2 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/po4a.conf

diff --git a/Documentation/Makefile b/Documentation/Makefile
index b5be2e2d3..1f71c0b80 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,4 +1,5 @@
 # Guard against environment variables
+MAN1_L10N_TXT =
 MAN1_TXT =
 MAN5_TXT =
 MAN7_TXT =
@@ -10,6 +11,7 @@ OBSOLETE_HTML =
 MAN1_TXT += $(filter-out \
$(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
$(wildcard git-*.txt))
+MAN1_L10N_TXT += $(wildcard po/*/man1/git-*.txt)
 MAN1_TXT += git.txt
 MAN1_TXT += gitk.txt
 MAN1_TXT += gitremote-helpers.txt
@@ -86,6 +88,7 @@ DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
 DOC_MAN1 = $(patsubst %.txt,%.1,$(MAN1_TXT))
 DOC_MAN5 = $(patsubst %.txt,%.5,$(MAN5_TXT))
 DOC_MAN7 = $(patsubst %.txt,%.7,$(MAN7_TXT))
+DOC_MAN1_L10N = $(patsubst %.txt,%.1,$(MAN1_L10N_TXT))
 
 prefix ?= $(HOME)
 bindir ?= $(prefix)/bin
@@ -209,6 +212,7 @@ endif
 
 ifneq ($(findstring $(MAKEFLAGS),s),s)
 ifndef V
+   QUIET_PO4A  = @echo '   ' PO4A $@;
QUIET_ASCIIDOC  = @echo '   ' ASCIIDOC $@;
QUIET_XMLTO = @echo '   ' XMLTO $@;
QUIET_DB2TEXI   = @echo '   ' DB2TEXI $@;
@@ -229,11 +233,20 @@ all: html man
 
 html: $(DOC_HTML)
 
-man: man1 man5 man7
+man: man1 man5 man7 man_l10n
 man1: $(DOC_MAN1)
 man5: $(DOC_MAN5)
 man7: $(DOC_MAN7)
 
+man_l10n: po4a man1_p_l10n
+po4a: po4a.conf
+   $(QUIET_PO4A)po4a po4a.conf
+
+man1_p_l10n: po4a
+   $(MAKE) man1_l10n
+
+man1_l10n: $(DOC_MAN1_L10N)
+
 info: git.info gitman.info
 
 pdf: user-manual.pdf
@@ -247,6 +260,11 @@ install-man: man
$(INSTALL) -m 644 $(DOC_MAN1) $(DESTDIR)$(man1dir)
$(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir)
$(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
+   $(MAKE) install-man-l10n
+
+install-man-l10n: $(DOC_MAN1_L10N)
+   $(INSTALL) -d -m 755 $(DESTDIR)$(mandir)/$(firstword $(subst /man1/, 
,$(subst po/,,$<)))/man1
+   $(INSTALL) -m 644 $< $(DESTDIR)$(mandir)$(subst po,,$<)
 
 install-info: info
$(INSTALL) -d -m 755 $(DESTDIR)$(infodir)
@@ -323,6 +341,7 @@ clean:
$(RM) technical/*.html technical/api-index.txt
$(RM) $(cmds_txt) $(mergetools_txt) *.made
$(RM) manpage-base-url.xsl
+   $(RM) po/*/*.1 po/*/*.txt
 
 $(MAN_HTML): %.html : %.txt asciidoc.conf
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
@@ -339,7 +358,7 @@ manpage-base-url.xsl: manpage-base-url.xsl.in
 
 %.1 %.5 %.7 : %.xml manpage-base-url.xsl
$(QUIET_XMLTO)$(RM) $@ && \
-   $(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
+   $(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) -o $(dir $<) man $<
 
 %.xml : %.txt asciidoc.conf
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
diff --git a/Documentation/po4a.conf b/Documentation/po4a.conf
new file mode 100644
index 0..b6ee8b4a6
--- /dev/null
+++ b/Documentation/po4a.conf
@@ -0,0 +1,5 @@
+[po4a_langs] fr
+[po4a_paths] po/documentation.pot $lang:po/documentation.$lang.po
+[options] opt: " -k 80"
+
+[type: asciidoc] ./git-add.txt $lang:./po/$lang/man1/git-add.txt
-- 
2.12.0



Re: [PATCH v3 0/4] Kill manual ref parsing code in worktree.c

2017-03-18 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy   writes:

> v3 is a rebased version on latest nd/files-backend-git-dir [1]. Since
> that series added a bunch of new refs_* functions, v2's 02/05 and
> 04/05 are removed. The new 01/04 could be an indepedent fix, but at
> test-ref-store.c requires it, so I put it here. More tests are added
> now that we have test-ref-store.c (yay!)

I think the corresponding ones were queued on a separate topic
nd/worktree-kill-parse-ref that is based on nd/files-backend-git-dir
but I do not mind making these 4 patches just part of the latter
topic.

Will send comments on individual patches separately.

Thanks.  

>
> [1] 
> http://public-inbox.org/git/%3c20170318020337.22767-1-pclo...@gmail.com%3E/
>
> Nguyễn Thái Ngọc Duy (4):
>   environment.c: fix potential segfault by get_git_common_dir()
>   refs: introduce get_worktree_ref_store()
>   worktree.c: kill parse_ref() in favor of refs_resolve_ref_unsafe()
>   refs: kill set_worktree_head_symref()
>
>  branch.c   |  15 ++---
>  environment.c  |   2 +
>  refs.c |  32 +++
>  refs.h |  12 +---
>  refs/files-backend.c   |  44 --
>  t/helper/test-ref-store.c  |  19 ++
>  t/t1407-worktree-ref-store.sh (new +x) |  52 +
>  worktree.c | 102 
> +
>  worktree.h |   2 +-
>  9 files changed, 143 insertions(+), 137 deletions(-)
>  create mode 100755 t/t1407-worktree-ref-store.sh


Re: [PATCH] pickaxe: fix segfault with '-S<...> --pickaxe-regex'

2017-03-18 Thread SZEDER Gábor
On Sat, Mar 18, 2017 at 4:12 PM, SZEDER Gábor  wrote:
> Make sure that the buffer size is reduced on each iteration as the
> buffer pointer is advanced, thus maintaining the correct end of buffer
> location.
>
> The new test is flaky, I've never seen it fail on my Linux box, but
> this is expected according to db5dfa331 (regex: -G feeds a
> non NUL-terminated string to regexec() and fails, 2016-09-21).  And
> based on that commit message I would expect the new test without the
> fix to fail reliably on Windows.
>
> Signed-off-by: SZEDER Gábor 
> ---
>
>  diffcore-pickaxe.c  | 5 -
>  t/t4062-diff-pickaxe.sh | 5 +
>  2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
> index 9795ca1c1..03f84b714 100644
> --- a/diffcore-pickaxe.c
> +++ b/diffcore-pickaxe.c
> @@ -85,8 +85,11 @@ static unsigned int contains(mmfile_t *mf, regex_t 
> *regexp, kwset_t kws)
>!regexec_buf(regexp, data, sz, 1, , flags)) {
> flags |= REG_NOTBOL;
> data += regmatch.rm_eo;
> -   if (*data && regmatch.rm_so == regmatch.rm_eo)
> +   sz -= regmatch.rm_eo;
> +   if (*data && regmatch.rm_so == regmatch.rm_eo) {
> data++;
> +   sz--;
> +   }
> cnt++;
> }
>
> diff --git a/t/t4062-diff-pickaxe.sh b/t/t4062-diff-pickaxe.sh
> index f0bf50bda..7c4903f49 100755
> --- a/t/t4062-diff-pickaxe.sh
> +++ b/t/t4062-diff-pickaxe.sh
> @@ -19,4 +19,9 @@ test_expect_success '-G matches' '
> test 4096-zeroes.txt = "$(cat out)"
>  '
>
> +test_expect_success '-S --pickaxe-regex' '
> +   git diff --name-only -S0 --pickaxe-regex HEAD^ >out &&
> +   verbose test 4096-zeroes.txt = "$(cat out)"
> +'
> +
>  test_done

Hang on, this new test does fail because of a segfault _with_ the fix
on Travis 64bit Linux and OSX builds.

Oh, well.


Re: GSoC 2017: application open, deadline = February 9, 2017

2017-03-18 Thread Junio C Hamano
Duy Nguyen  writes:

> Probably too late for GSoc 2017, but another idea for microproject (or
> microprojects) is make use of dir-iterator.h more. For recursive
> directory walking, this would make the code easier to read and
> potentially avoid too deep recursion. There are three or four of them,
> I think.

Throw it on the microproject idea page anyway, as it is likely that
the leftover bits will be migrated to the page created for the next
year and that way we won't forget.


Cash Donation

2017-03-18 Thread Adrian Gillian Bayford
£1.5 Million Has Been Granted To You As A Donation Visit 
www.bbc.co.uk/news/uk-england-19254228 Sendname Address Phone for more info


Re: [PATCH] Documentation/git-worktree: use working tree for trees on the file system

2017-03-18 Thread Junio C Hamano
Stefan Beller  writes:

>> Unfortunately gitglossary(7) doesn't make this clear at all --- it
>> uses the term worktree a few times (and appears to mean "working tree"
>> when it does --- e.g.
>>
>> Pathspecs are used on the command line of [...] and many other
>> commands to limit the scope of operations to some subset of
>> the tree or worktree.
>>
>> ) but never defines it.
>
> So maybe it's time to look for volunteers for a cleanup patch. ;)
> I tried finding the discussion on worktree vs "working tree"
> and did not succeed. :/

A rough rule of thumb.  Anything that was written before 2014 or
back when nobody knew df0b6cfb ("worktree: new place for "git prune
--worktrees"", 2015-06-29) was coming that says "worktree" is using
the term to refer to what we call "working tree" these days.

What Jonathan quoted above came from 3bd2bcfa ("glossary: define
pathspec", 2010-12-15) and certainly predates the one that replaced
contrib/workdir, so we should update it to read "working tree".



Re: [PATCH] receive-pack: simplify run_update_post_hook()

2017-03-18 Thread Junio C Hamano
Jeff King  writes:

> On Fri, Mar 17, 2017 at 11:02:13PM +0100, René Scharfe wrote:
>
>> Instead of counting the arguments to see if there are any and then
>> building the full command use a single loop and add the hook command
>> just before the first argument.  This reduces duplication and overall
>> code size.
>
> Yeah, I agree one loop is nicer.
>
>> -argv_array_push(, hook);
>>  for (cmd = commands; cmd; cmd = cmd->next) {
>>  if (cmd->error_string || cmd->did_not_exist)
>>  continue;
>> +if (!proc.args.argc)
>> +argv_array_push(, hook);
>>  argv_array_push(, cmd->ref_name);
>>  }
>> +if (!proc.args.argc)
>> +return;
>
> It looks at first like the result leaks, because you have to realize
> that the push will modify proc.args.argc. 

Hmph, I needed to read the original twice to imagine how a paranoid
person can fear leaks.  The return condition says "if args array is
empty, just return" and the thing being empty is an enough indication
to think nothing is leaking, at least for me.

Having said that, I'd admit that the "always push hook and then
clean up before returning if it turns out there is nothing to call
the hook for" is what I would have wrote if I were doing this, but
I'm inclined to think that is not because I would have thought of
both versions and picked the better one, but because I wouldn't have
noticed the "optimization opportunity" René spotted here (not that I
think an extra alloc would matter).

I'll queue the patch as-is, at least for now.

Thanks.

> I wonder if:
>
>   argv_array_push(, hook);
>   for (cmd = commands; cmd; cmd = cmd->next) {
>   if (!cmd->error_string && !cmd->did_not_exist)
>   argv_array_push(, cmd->ref_name);
>   }
>
>   if (proc.args.argc == 1) {
>   argv_array_clear();
>   return;
>   }
>
> would be more obvious (at the cost of a pointless malloc in the corner
> case. I can live with it either way.
>
> -Peff


Re: Is there a way to have a local version of a header file?

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Sat, Mar 18, 2017 at 3:58 PM, David Lang  wrote:
> On Sat, 18 Mar 2017, Ævar Arnfjörð Bjarmason wrote:
>
>> On Sat, Mar 18, 2017 at 3:29 PM, David Lang  wrote:
>>>
>>> for an embedded project built inside the Arduino IDE, (alternate firmware
>>> for a home automation project) there is a need to set a number of
>>> parameters
>>> that we really don't want in the main repo (wifi network IDs/passwords)
>>>
>>> right now, we have these things set as #defines in a header file.
>>>
>>> We need to distribute a base version of this file for new people to get
>>> started.
>>>
>>> Is there any way to have git define a file in such a way that if it
>>> doesn't
>>> exist in the worktree it gets populated, but if it does exist it doesn't
>>> get
>>> overwritten? (as I type this, I'm thinking a trigger may work, but we
>>> need
>>> it to work on Linux, Windows and OSX)
>>>
>>> Any thoughts on a sane way to handle this situation?
>>
>>
>> There's no sane way to do what you're describing without renaming the
>> file.
>>
>> But the sanest way to do this is to have a config.h.example
>>
>> Then you have "/config.h" in the .gitignore file.
>>
>> And you tell the users to copy the *.example file to *.h, and your
>> program then includes the *.h file.
>>
>> If you wanted to provide defaults you could just #include the
>> config.h.example first, so #defines in the *.h file would clobber
>> those in the *.example.
>
>
> That's what we currently have (user_config.h and user_config_override.h)
>
> I was hoping to not have the situation where downloading and trying to
> compile will complain about a missing include file (if the users don't copy
> user_config_override_example.h to user_config_override.h) while letting us
> do a .gitignore on user_config_override.h
>
> for many people using this project, this is the first time they have ever
> compiled anything, and we have the typical set of people not reading
> instructions :-/
>
> Darn, I was hoping that the scenario of needing to have a config file
> provided in the repo, while not overwriting local changes to it was common
> enough that there were some tricks available. This is a little harder as the
> running code doesn't have a filesystem so we are limited to what we can do
> in the compiler and git (no makefile even, the Arduino folks consider that
> too complicated, it just slurps up all .ino files in a directory and
> compiles them)

There might be some way I haven't thought of, in particular maybe you
can use gitattributes to define a custom diff/merge driver that always
reports no changes, or some ways to (ab)use the index to make git
ignore any changes to the file.


Re: [PATCH v5 00/10] decoupling url and submodule interest

2017-03-18 Thread Junio C Hamano
Brandon Williams  writes:

> Changes in v5:
>   * Add "NEEDSWORK" comments to indicate where attention is needed once
> per-worktree config is a reality
>   * --no-recurse now works by clearing the string list of paths.
>   * module_list_active() now does post-processing instead of duplicating code.
>
> Brandon Williams (10):
>   submodule--helper: add is-active subcommand
>   submodule status: use submodule--helper is-active
>   submodule sync: skip work for inactive submodules
>   submodule sync: use submodule--helper is-active
>   submodule--helper clone: check for configured submodules using helper
>   submodule: decouple url and submodule interest
>   submodule init: initialize active submodules
>   clone: teach --recurse-submodules to optionally take a pathspec
>   submodule--helper init: set submodule..active
>   submodule add: respect submodule.active and submodule..active

Replaced what has been queued with this and read it over
again. Looked sensible.

Thanks.


[PATCHv2 2/2] tests: make the 'test_pause' helper work in non-verbose mode

2017-03-18 Thread SZEDER Gábor
When the 'test_pause' helper function invokes the shell mid-test, it
explicitly redirects the shell's stdout and stderr to file descriptors
3 and 4, which are the stdout and stderr of the tests (i.e. where they
would be connected anyway without those redirections).  These file
descriptors are only attached to the terminal in verbose mode, hence
the restriction of 'test_pause' to work only with '-v'.

Redirect the shell's stdout and stderr to the test environment's
original stdout and stderr, allowing it to work properly even in
non-verbose mode, and the restriction can be lifted.

Signed-off-by: SZEDER Gábor 
---
 t/test-lib-functions.sh | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 4a50a6104..5ee124332 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -136,17 +136,12 @@ test_tick () {
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
 }
 
-# Stop execution and start a shell. This is useful for debugging tests and
-# only makes sense together with "-v".
+# Stop execution and start a shell. This is useful for debugging tests.
 #
 # Be sure to remove all invocations of this command before submitting.
 
 test_pause () {
-   if test "$verbose" = t; then
-   "$SHELL_PATH" <&6 >&3 2>&4
-   else
-   error >&5 "test_pause requires --verbose"
-   fi
+   "$SHELL_PATH" <&6 >&5 2>&7
 }
 
 # Wrap git in gdb. Adding this to a command can make it easier to
-- 
2.12.0.377.g15f6ffe90



[PATCHv2 1/2] tests: create an interactive gdb session with the 'debug' helper

2017-03-18 Thread SZEDER Gábor
The 'debug' test helper is supposed to facilitate debugging by running
a command of the test suite under gdb.  Unfortunately, its usefulness
is severely limited, because that gdb session is not interactive,
since the test's, and thus gdb's standard input is redirected from
/dev/null (for a good reason, see 781f76b15 (test-lib: redirect stdin
of tests, 2011-12-15)).

Redirect gdb's standard file descriptors from/to the test
environment's stdin, stdout and stderr in the 'debug' helper, thus
creating an interactive gdb session (even in non-verbose mode), which
is much, much more useful.

Signed-off-by: SZEDER Gábor 
---
 t/test-lib-functions.sh | 2 +-
 t/test-lib.sh   | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index bd357704c..4a50a6104 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -154,7 +154,7 @@ test_pause () {
 #
 # Example: "debug git checkout master".
 debug () {
-GIT_TEST_GDB=1 "$@"
+GIT_TEST_GDB=1 "$@" <&6 >&5 2>&7
 }
 
 # Call test_commit with the arguments
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 86d77c16d..23c29bce6 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -342,6 +342,7 @@ fi
 
 exec 5>&1
 exec 6<&0
+exec 7>&2
 if test "$verbose_log" = "t"
 then
exec 3>>"$GIT_TEST_TEE_OUTPUT_FILE" 4>&3
-- 
2.12.0.377.g15f6ffe90



Respond to me immediately!!

2017-03-18 Thread DR.ANTHONY EMMANUEL
Dear how are you, 
First I got your contact from yahoo Terrors search, when am 
searching for a foreigner, please I don’t now if you can keep secret? A word of 
your own as a human-being? As I have gone through your profile.  Well I have a 
deal worth 5.5m$ from the dormant account in the bank where I am working. 
However the fund belong to one Mr J. korovo he die in years ago along with his 
family by plan crash, Please if you can keep secret, I will give you more 
details and the nest thing to do,
  No risk involve, hence I work in the same bank, 
For the expenses will be in my side not you. Till you confirm the fund in your 
account, I will take care of every expense. Also all the documents that will 
back you up must send to you. Meanwhile before I contact you I have done every 
underground work through the documents of the deceases person, I have put or 
attachment his file to our favor. Also with my position every thing works 
successfully.
 
 Contact me for more details please if you really want to know about this 
business also want to get more details please contact me through this my 
alternative email for more detail copy this address 
dr.anthony_emman...@yahoo.fr, I will send you my ID also my working Id and my 
family picture For you to know who your dealing with. Contact me back with 
 Your Full Name, 
Phone No…., 
Receiver Country.., 
Occupation.., 

PLEASE IF REALLY YOUR NEED MORE DETAILS CONTACT ME VIEW MY ALTERNATIVE FOR 
SECURITY REASONS. ALSO MY PHONE NUMBER AS FOLLOW.  
dr.anthony_emman...@yahoo.fr

thanks for your understand please contact me base if you can control this fund 
once it transfer into your account before my family and I will arriver in your 
country for the sharing, 40% for you. 10% for the poorest, rest is for me. 
Give me your Phone number Let me call you so that we can talk one and one

Yours faithfully,

>From DR.ANTHONY EMMANUEL.


Re: [PATCH] tests: create an interactive gdb session with the 'debug' helper

2017-03-18 Thread SZEDER Gábor
On Fri, Mar 17, 2017 at 3:55 PM, Jeff King  wrote:
> On Fri, Mar 17, 2017 at 03:46:46PM +0100, SZEDER Gábor wrote:
>
>> The 'debug' test helper is supposed to facilitate debugging by running
>> a command of the test suite under gdb.  Unfortunately, its usefulness
>> is severely limited, because that gdb session is not interactive,
>> since the test's, and thus gdb's standard input is attached to
>> /dev/null (for a good reason, see 781f76b15 (test-lib: redirect stdin
>> of tests, 2011-12-15)).
>>
>> Re-attach the original standard input in the debug helper, thus
>> creating an interactive gdb session, which is much much more useful.
>
> Yeah, I think I've had to do a similar hack manually. This is an obvious
> improvement. Though...
>
>> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
>> index bd357704c..9567dc986 100644
>> --- a/t/test-lib-functions.sh
>> +++ b/t/test-lib-functions.sh
>> @@ -154,7 +154,7 @@ test_pause () {
>>  #
>>  # Example: "debug git checkout master".
>>  debug () {
>> -  GIT_TEST_GDB=1 "$@"
>> +  GIT_TEST_GDB=1 "$@" <&6
>>  }
>
> Your stderr and stdout may be redirected, too. That's usually not a big
> problem because you'll be using "-v",

Yeah, I didn't consider using this helper in non-verbose mode at all,
and the resulting behaviour is not quite pleasant, indeed: gdb starts
in interactive mode, but as its stdout goes straight to /dev/null the
user has no idea, and gdb does not quit on Ctrl-C.  A possible
solution would be to forbid using the 'debug' helper without '-v',
like in the 'test_pause' helper just above.

However...

> but perhaps this should add:
>
>   >&3 2>&4
>
> to be on the safe side. That covers running without "-v", as well as
> cases where the test script is redirecting output

That wouldn't buy us much.  First, file descriptors 3 and 4 are the
test's stdout and stderr, i.e. any process started within the test
would be connected to those fds anyway without those explicit
redirections.  Second, fds 3 and 4 are redirected to /dev/null in
non-verbose mode, so it would still not work without '-v'.

Perhaps you meant '>&5 2>&7' here (and in the bash example in the
commit message of 781f76b15 (test-lib: redirect stdin of tests,
2011-12-15), for that matter)?  Those redirections do in fact make
'debug' work even without '-v'.  Furthermore, those redirections do
make 'test_pause' work without '-v', too.

So this is what v2 will do, then.

Gábor


[PATCH] pickaxe: fix segfault with '-S<...> --pickaxe-regex'

2017-03-18 Thread SZEDER Gábor
'git {log,diff,...} -S<...> --pickaxe-regex' can segfault as a result
of out-of-bounds memory reads.

diffcore-pickaxe.c:contains() looks for all matches of the given regex
in a buffer in a loop, advancing the buffer pointer to the end of the
last match in each iteration.  When we switched to REG_STARTEND in
b7d36ffca (regex: use regexec_buf(), 2016-09-21), we started passing
the size of that buffer to the regexp engine, too.  Unfortunately,
this buffer size is never updated on subsequent iterations, and as the
buffer pointer advances on each iteration, this "bufptr+bufsize"
points past the end of the buffer.  This results in segmentation
fault, if that memory can't be accessed.  In case of 'git log' it can
also result in erroneously listed commits, if the memory past the end
of buffer is accessible and happens to contain data matching the
regex.

Make sure that the buffer size is reduced on each iteration as the
buffer pointer is advanced, thus maintaining the correct end of buffer
location.

The new test is flaky, I've never seen it fail on my Linux box, but
this is expected according to db5dfa331 (regex: -G feeds a
non NUL-terminated string to regexec() and fails, 2016-09-21).  And
based on that commit message I would expect the new test without the
fix to fail reliably on Windows.

Signed-off-by: SZEDER Gábor 
---

 diffcore-pickaxe.c  | 5 -
 t/t4062-diff-pickaxe.sh | 5 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index 9795ca1c1..03f84b714 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -85,8 +85,11 @@ static unsigned int contains(mmfile_t *mf, regex_t *regexp, 
kwset_t kws)
   !regexec_buf(regexp, data, sz, 1, , flags)) {
flags |= REG_NOTBOL;
data += regmatch.rm_eo;
-   if (*data && regmatch.rm_so == regmatch.rm_eo)
+   sz -= regmatch.rm_eo;
+   if (*data && regmatch.rm_so == regmatch.rm_eo) {
data++;
+   sz--;
+   }
cnt++;
}
 
diff --git a/t/t4062-diff-pickaxe.sh b/t/t4062-diff-pickaxe.sh
index f0bf50bda..7c4903f49 100755
--- a/t/t4062-diff-pickaxe.sh
+++ b/t/t4062-diff-pickaxe.sh
@@ -19,4 +19,9 @@ test_expect_success '-G matches' '
test 4096-zeroes.txt = "$(cat out)"
 '
 
+test_expect_success '-S --pickaxe-regex' '
+   git diff --name-only -S0 --pickaxe-regex HEAD^ >out &&
+   verbose test 4096-zeroes.txt = "$(cat out)"
+'
+
 test_done
-- 
2.12.0.377.g15f6ffe90



Re: Is there a way to have a local version of a header file?

2017-03-18 Thread David Lang

On Sat, 18 Mar 2017, Ævar Arnfjörð Bjarmason wrote:


On Sat, Mar 18, 2017 at 3:29 PM, David Lang  wrote:

for an embedded project built inside the Arduino IDE, (alternate firmware
for a home automation project) there is a need to set a number of parameters
that we really don't want in the main repo (wifi network IDs/passwords)

right now, we have these things set as #defines in a header file.

We need to distribute a base version of this file for new people to get
started.

Is there any way to have git define a file in such a way that if it doesn't
exist in the worktree it gets populated, but if it does exist it doesn't get
overwritten? (as I type this, I'm thinking a trigger may work, but we need
it to work on Linux, Windows and OSX)

Any thoughts on a sane way to handle this situation?


There's no sane way to do what you're describing without renaming the file.

But the sanest way to do this is to have a config.h.example

Then you have "/config.h" in the .gitignore file.

And you tell the users to copy the *.example file to *.h, and your
program then includes the *.h file.

If you wanted to provide defaults you could just #include the
config.h.example first, so #defines in the *.h file would clobber
those in the *.example.


That's what we currently have (user_config.h and user_config_override.h)

I was hoping to not have the situation where downloading and trying to compile 
will complain about a missing include file (if the users don't copy 
user_config_override_example.h to user_config_override.h) while letting us do a 
.gitignore on user_config_override.h


for many people using this project, this is the first time they have ever 
compiled anything, and we have the typical set of people not reading 
instructions :-/


Darn, I was hoping that the scenario of needing to have a config file provided 
in the repo, while not overwriting local changes to it was common enough that 
there were some tricks available. This is a little harder as the running code 
doesn't have a filesystem so we are limited to what we can do in the compiler 
and git (no makefile even, the Arduino folks consider that too complicated, it 
just slurps up all .ino files in a directory and compiles them)


Re: Is there a way to have a local version of a header file?

2017-03-18 Thread Ævar Arnfjörð Bjarmason
On Sat, Mar 18, 2017 at 3:29 PM, David Lang  wrote:
> for an embedded project built inside the Arduino IDE, (alternate firmware
> for a home automation project) there is a need to set a number of parameters
> that we really don't want in the main repo (wifi network IDs/passwords)
>
> right now, we have these things set as #defines in a header file.
>
> We need to distribute a base version of this file for new people to get
> started.
>
> Is there any way to have git define a file in such a way that if it doesn't
> exist in the worktree it gets populated, but if it does exist it doesn't get
> overwritten? (as I type this, I'm thinking a trigger may work, but we need
> it to work on Linux, Windows and OSX)
>
> Any thoughts on a sane way to handle this situation?

There's no sane way to do what you're describing without renaming the file.

But the sanest way to do this is to have a config.h.example

Then you have "/config.h" in the .gitignore file.

And you tell the users to copy the *.example file to *.h, and your
program then includes the *.h file.

If you wanted to provide defaults you could just #include the
config.h.example first, so #defines in the *.h file would clobber
those in the *.example.


Is there a way to have a local version of a header file?

2017-03-18 Thread David Lang
for an embedded project built inside the Arduino IDE, (alternate firmware for a 
home automation project) there is a need to set a number of parameters that we 
really don't want in the main repo (wifi network IDs/passwords)


right now, we have these things set as #defines in a header file.

We need to distribute a base version of this file for new people to get started.

Is there any way to have git define a file in such a way that if it doesn't 
exist in the worktree it gets populated, but if it does exist it doesn't get 
overwritten? (as I type this, I'm thinking a trigger may work, but we need it to 
work on Linux, Windows and OSX)


Any thoughts on a sane way to handle this situation?

David Lang


Re: Commiting files larger than 4 GB on Windows

2017-03-18 Thread Thomas Braun
> Torsten Bögershausen  hat am 17. März 2017 um 06:29
> geschrieben:
> 
> 
> On 15/03/17 22:29, Junio C Hamano wrote:
> > Torsten Bögershausen  writes:
> >
> >> The real "show stopper" is at the end.
> >> ...
> >>
> >> ==
> >> And it seams as if zlib is the limitation here.
> >> Unless we include the zlib source code into Git and redefine uLong,
> >> is there a nice way around this:
> >> ===
> >>
> >>
> >> /usr/include/zconf.h:#  define uLong z_uLong
> >> /usr/include/zconf.h:#  define uLongfz_uLongf
> >> /usr/include/zconf.h:typedef unsigned long  uLong; /* 32 bits or more */
> >> /usr/include/zconf.h:typedef uLong FAR uLongf;
> > Hmph.  Would ef49a7a0 ("zlib: zlib can only process 4GB at a time",
> > 2011-06-10) and e01503b5 ("zlib: allow feeding more than 4GB in one
> > go", 2011-06-10) help us here, though?
> >
> That is good news.
> I tried to replace all "unsigned long" with size_t and got that compiling
> without warnings under Windows 64 bit.
> 
> Compiling this on a 32 bit Linux gave lots of warnings..
> 
> Converting all unsigned long into is probably an overkill.
> Some may stay, some may be converted into off_t, and some size_t.
> 
> Does anybody wants to pick this up?

I'd be interested, altough I can't promise to get it done in the near future.


Assalamu`Alaikum.

2017-03-18 Thread Mohammad Ouattara



Dear Sir/Madam.

Assalamu`Alaikum.

I am Dr mohammad ouattara, I have  ($10.6 Million us dollars) to transfer into 
your account,

I will send you more details about this deal and the procedures to follow when 
I receive a positive response from you, 

Have a great day,

Dr mohammad ouattara.


[PATCH v3 1/4] environment.c: fix potential segfault by get_git_common_dir()

2017-03-18 Thread Nguyễn Thái Ngọc Duy
setup_git_env() must be called before this function to initialize
git_common_dir so that it returns a non NULL string. And it must return
a non NULL string or segfault can happen because all callers expect so.

Normally if somebody has called get_git_dir(), or set_git_dir() then
setup_git_env() is already called. But if you do setup_git_directory()
at top dir (which skips set_git_dir) and never call get_git_dir, you'll
get NULL here.

test-ref-store.c will hit this problem because it's very lightweight,
just enough initialization to exercise refs code, and get_git_dir() will
never be called until get_worktrees() is, which uses get_git_common_dir().
---
 environment.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/environment.c b/environment.c
index 42dc3106d2..2986ee7200 100644
--- a/environment.c
+++ b/environment.c
@@ -214,6 +214,8 @@ const char *get_git_dir(void)
 
 const char *get_git_common_dir(void)
 {
+   if (!git_dir)
+   setup_git_env();
return git_common_dir;
 }
 
-- 
2.11.0.157.gd943d85



[PATCH] gitk: use right colour for remote refs in the "Tags and heads" dialog

2017-03-18 Thread Paul Wise
Makes it easier to see which refs are local and which refs are remote.
Adds consistency with the remote background colour in the graph display.

Signed-off-by: Paul Wise 
---
 gitk-git/gitk | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/gitk-git/gitk b/gitk-git/gitk
index a14d7a16b..14aebc23e 100755
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -3404,6 +3404,8 @@ set rectmask {
 }
 image create bitmap reficon-H -background black -foreground "#00ff00" \
 -data $rectdata -maskdata $rectmask
+image create bitmap reficon-R -background black -foreground "#ffddaa" \
+-data $rectdata -maskdata $rectmask
 image create bitmap reficon-o -background black -foreground "#ff" \
 -data $rectdata -maskdata $rectmask
 
@@ -10022,6 +10024,7 @@ proc sel_reflist {w x y} {
 set n [lindex $ref 0]
 switch -- [lindex $ref 1] {
"H" {selbyid $headids($n)}
+   "R" {selbyid $headids($n)}
"T" {selbyid $tagids($n)}
"o" {selbyid $otherrefids($n)}
 }
@@ -10051,7 +10054,11 @@ proc refill_reflist {} {
 foreach n [array names headids] {
if {[string match $reflistfilter $n]} {
if {[commitinview $headids($n) $curview]} {
-   lappend refs [list $n H]
+   if {[string match "remotes/*" $n]} {
+   lappend refs [list $n R]
+   } else {
+   lappend refs [list $n H]
+   }
} else {
interestedin $headids($n) {run refill_reflist}
}
-- 
2.11.0



[PATCH 0/8] Various changes to the "tag" command

2017-03-18 Thread Ævar Arnfjörð Bjarmason
This series incorporates and replaces all the "tag" patches I have
floating around the list, and adds a lot in the mix which discovered
while working on the initial two patches, but which made sense as
separate patches.

It's based no top of Jeff's gitster/jk/ref-filter-flags-cleanup.

I'm bundling this all together because a lot of these patches touch
the exact same code, and in other cases subsequent patches make use of
test suite improvements I made earlier in the series. So although some
could be split out entirely (e.g. the --point-at patch), I'd like to
just present them all for review together & split out any if there's
strong objections to basing them on top of each other.

I think this series changes addresses all the points brought up by
Junio/Jeff about my previous patches, except there's no extensive
discussion of how the filtering mechanism works in general as pointed
out by Junio in .

I think it makes sense to have that, but in the interest of getting
something out the door I'm not working on that for now.

Ævar Arnfjörð Bjarmason (8):
  tag: Remove a TODO item from the test suite
  tag: Refactor the options handling code to be less bizarro
  tag: Change  misleading --list  documentation
  tag: Implicitly supply --list given another list-like option
  tag: Implicitly supply --list given the -n option
  ref-filter: Add --no-contains option to tag/branch/for-each-ref
  tag: Add tests for --with and --without
  tag: Change --point-at to default to HEAD

 Documentation/git-branch.txt   |  15 ++-
 Documentation/git-for-each-ref.txt |   6 +-
 Documentation/git-tag.txt  |  44 ---
 builtin/branch.c   |   4 +-
 builtin/for-each-ref.c |   3 +-
 builtin/tag.c  |  36 --
 contrib/completion/git-completion.bash |   4 +-
 parse-options.h|   4 +-
 ref-filter.c   |  19 ++-
 ref-filter.h   |   1 +
 t/t3201-branch-contains.sh |  51 +++-
 t/t6302-for-each-ref-filter.sh |  16 +++
 t/t7004-tag.sh | 226 +++--
 13 files changed, 371 insertions(+), 58 deletions(-)

-- 
2.11.0



DON SPENDE

2017-03-18 Thread reiza002i
DON SPENDE


Que la paix de notre Dieu tout-puissant soit à vous

SPENDE VON BAHADUR


Möge der Friede unseres allmächtigen Gottes zu euch sein

Gruß im Namen unseres allmächtigen Gottes Ich wünsche dir und deiner Familie 
glückliche Momente des Lebens jetzt und für immer mehr amen.Mein Name ist Frau 
Bahadur Reza Nobakhti, 69 Jahre alt aus Dubia leben in Abidjan, Cote d'Ivoire, 
Bitte, ich Habe keine formale Beziehung zu dir, sondern wegen meiner 
gegenwärtigen Situation und Umständen bin ich Um mich zu kontaktieren. Ich habe 
an Krebs erkrankt und habe ein kurzes Leben zu verlassen. Ich habe mich 
entschlossen, mein Erbe von 3,5 Millionen Euro an die weniger privilegierten 
bitte zu helfen, mir zu helfen, meinen letzten Wunsch zu erfüllen, bitte 
kontaktieren Sie mich hier .. [reza_b...@yahoo.com]


Bitte kontaktieren Sie mich in meiner persönlichen E-Mail .. 
[reza_b...@yahoo.com]

Ich warte, von dir zu hören

Vielen Dank

Frau Bahadur Reza Nobakhti




[PATCH v3 2/4] refs: introduce get_worktree_ref_store()

2017-03-18 Thread Nguyễn Thái Ngọc Duy
files-backend at this point is still aware of the per-repo/worktree
separation in refs, so it can handle a linked worktree.

Some refs operations are known not working when current files-backend is
used in a linked worktree (e.g. reflog). Tests will be written when
refs_* functions start to be called with worktree backend to verify that
they work as expected.

Note: accessing a worktree of a submodule remains unaddressed. Perhaps
after get_worktrees() can access submodule (or rather a new function
get_submodule_worktrees(), that lists worktrees of a submodule), we can
update this function to work with submodules as well.
---
 refs.c | 32 
 refs.h |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/refs.c b/refs.c
index 77a39f8b17..6695140cfe 100644
--- a/refs.c
+++ b/refs.c
@@ -10,6 +10,7 @@
 #include "object.h"
 #include "tag.h"
 #include "submodule.h"
+#include "worktree.h"
 
 /*
  * List of all available backends
@@ -1593,6 +1594,37 @@ struct ref_store *get_submodule_ref_store(const char 
*submodule)
return refs;
 }
 
+struct ref_store *get_worktree_ref_store(const struct worktree *wt)
+{
+   struct ref_store *refs;
+   unsigned int refs_all_capabilities =
+   REF_STORE_READ | REF_STORE_WRITE |
+   REF_STORE_ODB | REF_STORE_MAIN;
+
+   if (wt->is_current)
+   return get_main_ref_store();
+
+   /*
+* We share the same hash map with submodules for
+* now. submodule paths are always relative (to topdir) while
+* worktree paths are always absolute. No chance of conflict.
+*/
+   refs = lookup_submodule_ref_store(wt->path);
+   if (refs)
+   return refs;
+
+   if (wt->id)
+   refs = ref_store_init(git_common_path("worktrees/%s", wt->id),
+ refs_all_capabilities);
+   else
+   refs = ref_store_init(get_git_common_dir(),
+ refs_all_capabilities);
+
+   if (refs)
+   register_submodule_ref_store(refs, wt->path);
+   return refs;
+}
+
 void base_ref_store_init(struct ref_store *refs,
 const struct ref_storage_be *be)
 {
diff --git a/refs.h b/refs.h
index 49e97d7d5f..6df69a2adb 100644
--- a/refs.h
+++ b/refs.h
@@ -5,6 +5,7 @@ struct object_id;
 struct ref_store;
 struct strbuf;
 struct string_list;
+struct worktree;
 
 /*
  * Resolve a reference, recursively following symbolic refererences.
@@ -655,5 +656,6 @@ struct ref_store *get_main_ref_store(void);
  * submodule==NULL.
  */
 struct ref_store *get_submodule_ref_store(const char *submodule);
+struct ref_store *get_worktree_ref_store(const struct worktree *wt);
 
 #endif /* REFS_H */
-- 
2.11.0.157.gd943d85



[PATCH v3 3/4] worktree.c: kill parse_ref() in favor of refs_resolve_ref_unsafe()

2017-03-18 Thread Nguyễn Thái Ngọc Duy
The manual parsing code is replaced with a call to refs_resolve_ref_unsafe().
The manual parsing code must die because only refs/files-backend.c
should do that.
---
 branch.c   |   3 +-
 t/helper/test-ref-store.c  |  19 ++
 t/t1407-worktree-ref-store.sh (new +x) |  40 +
 worktree.c | 102 +
 worktree.h |   2 +-
 5 files changed, 89 insertions(+), 77 deletions(-)
 create mode 100755 t/t1407-worktree-ref-store.sh

diff --git a/branch.c b/branch.c
index 5c12036b02..0b949b7fb2 100644
--- a/branch.c
+++ b/branch.c
@@ -355,7 +355,8 @@ int replace_each_worktree_head_symref(const char *oldref, 
const char *newref,
for (i = 0; worktrees[i]; i++) {
if (worktrees[i]->is_detached)
continue;
-   if (strcmp(oldref, worktrees[i]->head_ref))
+   if (worktrees[i]->head_ref &&
+   strcmp(oldref, worktrees[i]->head_ref))
continue;
 
if (set_worktree_head_symref(get_worktree_git_dir(worktrees[i]),
diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c
index 57849ee59a..3c926ed85e 100644
--- a/t/helper/test-ref-store.c
+++ b/t/helper/test-ref-store.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "refs.h"
+#include "worktree.h"
 
 static const char *notnull(const char *arg, const char *name)
 {
@@ -32,6 +33,23 @@ static const char **get_store(const char **argv, struct 
ref_store **refs)
strbuf_release();
 
*refs = get_submodule_ref_store(gitdir);
+   } else if (skip_prefix(argv[0], "worktree:", )) {
+   struct worktree **p, **worktrees = get_worktrees(0);
+
+   for (p = worktrees; *p; p++) {
+   struct worktree *wt = *p;
+
+   if (!wt->id) {
+   /* special case for main worktree */
+   if (!strcmp(gitdir, "main"))
+   break;
+   } else if (!strcmp(gitdir, wt->id))
+   break;
+   }
+   if (!*p)
+   die("no such worktree: %s", gitdir);
+
+   *refs = get_worktree_ref_store(*p);
} else
die("unknown backend %s", argv[0]);
 
@@ -261,6 +279,7 @@ int cmd_main(int argc, const char **argv)
const char *func;
struct command *cmd;
 
+   setup_git_directory();
argv = get_store(argv + 1, );
 
func = *argv++;
diff --git a/t/t1407-worktree-ref-store.sh b/t/t1407-worktree-ref-store.sh
new file mode 100755
index 00..04d1e9d177
--- /dev/null
+++ b/t/t1407-worktree-ref-store.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+test_description='test worktree ref store api'
+
+. ./test-lib.sh
+
+RWT="test-ref-store worktree:wt"
+RMAIN="test-ref-store worktree:main"
+
+test_expect_success 'setup' '
+   test_commit first &&
+   git worktree add -b wt-master wt &&
+   (
+   cd wt &&
+   test_commit second
+   )
+'
+
+test_expect_success 'resolve_ref()' '
+   SHA1=`git rev-parse master` &&
+   echo "$SHA1 refs/heads/master 0x0" >expected &&
+   $RWT resolve-ref refs/heads/master 0 >actual &&
+   test_cmp expected actual &&
+   $RMAIN resolve-ref refs/heads/master 0 >actual &&
+   test_cmp expected actual
+'
+
+test_expect_success 'resolve_ref()' '
+   SHA1=`git -C wt rev-parse HEAD` &&
+   echo "$SHA1 refs/heads/wt-master 0x1" >expected &&
+   $RWT resolve-ref HEAD 0 >actual &&
+   test_cmp expected actual &&
+
+   SHA1=`git rev-parse HEAD` &&
+   echo "$SHA1 refs/heads/master 0x1" >expected &&
+   $RMAIN resolve-ref HEAD 0 >actual &&
+   test_cmp expected actual
+'
+
+test_done
diff --git a/worktree.c b/worktree.c
index fa7bc67a50..c1ec334b06 100644
--- a/worktree.c
+++ b/worktree.c
@@ -19,54 +19,25 @@ void free_worktrees(struct worktree **worktrees)
free (worktrees);
 }
 
-/*
- * read 'path_to_ref' into 'ref'.  Also if is_detached is not NULL,
- * set is_detached to 1 (0) if the ref is detached (is not detached).
- *
- * $GIT_COMMON_DIR/$symref (e.g. HEAD) is practically outside $GIT_DIR so
- * for linked worktrees, `resolve_ref_unsafe()` won't work (it uses
- * git_path). Parse the ref ourselves.
- *
- * return -1 if the ref is not a proper ref, 0 otherwise (success)
- */
-static int parse_ref(char *path_to_ref, struct strbuf *ref, int *is_detached)
-{
-   if (is_detached)
-   *is_detached = 0;
-   if (!strbuf_readlink(ref, path_to_ref, 0)) {
-   /* HEAD is symbolic link */
-   if (!starts_with(ref->buf, "refs/") ||
-   check_refname_format(ref->buf, 0))
-   return -1;
-   } else if (strbuf_read_file(ref, path_to_ref, 0) >= 0) {
-

[PATCH v2 07/12] revision.c: use refs_for_each*() instead of for_each_*_submodule()

2017-03-18 Thread Nguyễn Thái Ngọc Duy
---
 revision.c | 48 
 1 file changed, 32 insertions(+), 16 deletions(-)

diff --git a/revision.c b/revision.c
index db8021ed26..da19071960 100644
--- a/revision.c
+++ b/revision.c
@@ -1189,12 +1189,19 @@ void add_ref_exclusion(struct string_list 
**ref_excludes_p, const char *exclude)
string_list_append(*ref_excludes_p, exclude);
 }
 
-static void handle_refs(const char *submodule, struct rev_info *revs, unsigned 
flags,
-   int (*for_each)(const char *, each_ref_fn, void *))
+static void handle_refs(struct ref_store *refs,
+   struct rev_info *revs, unsigned flags,
+   int (*for_each)(struct ref_store *, each_ref_fn, void 
*))
 {
struct all_refs_cb cb;
+
+   if (!refs) {
+   /* this could happen with uninitialized submodules */
+   return;
+   }
+
init_all_refs_cb(, revs, flags);
-   for_each(submodule, handle_one_ref, );
+   for_each(refs, handle_one_ref, );
 }
 
 static void handle_one_reflog_commit(struct object_id *oid, void *cb_data)
@@ -2067,23 +2074,25 @@ void parse_revision_opt(struct rev_info *revs, struct 
parse_opt_ctx_t *ctx,
ctx->argc -= n;
 }
 
-static int for_each_bisect_ref(const char *submodule, each_ref_fn fn, void 
*cb_data, const char *term) {
+static int for_each_bisect_ref(struct ref_store *refs, each_ref_fn fn,
+  void *cb_data, const char *term)
+{
struct strbuf bisect_refs = STRBUF_INIT;
int status;
strbuf_addf(_refs, "refs/bisect/%s", term);
-   status = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, 
cb_data);
+   status = refs_for_each_ref_in(refs, bisect_refs.buf, fn, cb_data);
strbuf_release(_refs);
return status;
 }
 
-static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void 
*cb_data)
+static int for_each_bad_bisect_ref(struct ref_store *refs, each_ref_fn fn, 
void *cb_data)
 {
-   return for_each_bisect_ref(submodule, fn, cb_data, term_bad);
+   return for_each_bisect_ref(refs, fn, cb_data, term_bad);
 }
 
-static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, 
void *cb_data)
+static int for_each_good_bisect_ref(struct ref_store *refs, each_ref_fn fn, 
void *cb_data)
 {
-   return for_each_bisect_ref(submodule, fn, cb_data, term_good);
+   return for_each_bisect_ref(refs, fn, cb_data, term_good);
 }
 
 static int handle_revision_pseudo_opt(const char *submodule,
@@ -2092,8 +2101,14 @@ static int handle_revision_pseudo_opt(const char 
*submodule,
 {
const char *arg = argv[0];
const char *optarg;
+   struct ref_store *refs;
int argcount;
 
+   if (submodule) {
+   refs = get_submodule_ref_store(submodule);
+   } else
+   refs = get_main_ref_store();
+
/*
 * NOTE!
 *
@@ -2105,22 +2120,23 @@ static int handle_revision_pseudo_opt(const char 
*submodule,
 * register it in the list at the top of handle_revision_opt.
 */
if (!strcmp(arg, "--all")) {
-   handle_refs(submodule, revs, *flags, for_each_ref_submodule);
-   handle_refs(submodule, revs, *flags, head_ref_submodule);
+   handle_refs(refs, revs, *flags, refs_for_each_ref);
+   handle_refs(refs, revs, *flags, refs_head_ref);
clear_ref_exclusion(>ref_excludes);
} else if (!strcmp(arg, "--branches")) {
-   handle_refs(submodule, revs, *flags, 
for_each_branch_ref_submodule);
+   handle_refs(refs, revs, *flags, refs_for_each_branch_ref);
clear_ref_exclusion(>ref_excludes);
} else if (!strcmp(arg, "--bisect")) {
read_bisect_terms(_bad, _good);
-   handle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);
-   handle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), 
for_each_good_bisect_ref);
+   handle_refs(refs, revs, *flags, for_each_bad_bisect_ref);
+   handle_refs(refs, revs, *flags ^ (UNINTERESTING | BOTTOM),
+   for_each_good_bisect_ref);
revs->bisect = 1;
} else if (!strcmp(arg, "--tags")) {
-   handle_refs(submodule, revs, *flags, 
for_each_tag_ref_submodule);
+   handle_refs(refs, revs, *flags, refs_for_each_tag_ref);
clear_ref_exclusion(>ref_excludes);
} else if (!strcmp(arg, "--remotes")) {
-   handle_refs(submodule, revs, *flags, 
for_each_remote_ref_submodule);
+   handle_refs(refs, revs, *flags, refs_for_each_remote_ref);
clear_ref_exclusion(>ref_excludes);
} else if ((argcount = parse_long_opt("glob", argv, ))) {
struct all_refs_cb cb;
-- 
2.11.0.157.gd943d85



[PATCH 6/8] ref-filter: Add --no-contains option to tag/branch/for-each-ref

2017-03-18 Thread Ævar Arnfjörð Bjarmason
Change the tag, branch & for-each-ref commands to have a --no-contains
option in addition to their longstanding --contains options.

This allows for finding the last-good rollout tag given a known-bad
. Given a hypothetically bad commit cf5c7253e0 the git version
revert to can be found with this hacky two-liner:

(git tag -l 'v[0-9]*'; git tag -l --contains cf5c7253e0 'v[0-9]*') |
sort | uniq -c | grep -E '^ *1 ' | awk '{print $2}' | tail -n 10

With this new --no-contains the same can be achieved with:

git tag -l --no-contains cf5c7253e0 'v[0-9]*' | sort | tail -n 10

As the filtering machinery is shared between the tag, branch &
for-each-ref commands, implement this for those commands too. A
practical use for this with "branch" is e.g. finding branches which
diverged between v2.8 & v2.10:

git branch --contains v2.8.0 --no-contains v2.10.0

The "describe" command also has a --contains option, but its semantics
are unrelated to what tag/branch/for-each-ref use --contains for. A
--no-contains option for "describe" wouldn't make any sense, other
than being exactly equivalent to not supplying --contains at all,
which would be confusing at best.

Add a --without option to "tag" as an alias for --no-contains, for
consistency with --with and --contains.  The --with option is
undocumented, and possibly the only user of it is
Junio (). But it's
trivial to support, so let's do that.

The additions to the the test suite are inverse copies of the
corresponding --contains tests. With this change --no-contains for
tag, branch & for-each-ref is just as well tested as the existing
--contains option.

In addition to those tests, add a test for "tag" which asserts that
--no-contains won't find tree/blob tags, which is slightly
unintuitive, but consistent with how --contains works & is documented.

Signed-off-by: Ævar Arnfjörð Bjarmason 
---
 Documentation/git-branch.txt   |  15 ++--
 Documentation/git-for-each-ref.txt |   6 +-
 Documentation/git-tag.txt  |   6 +-
 builtin/branch.c   |   4 +-
 builtin/for-each-ref.c |   3 +-
 builtin/tag.c  |   8 ++-
 contrib/completion/git-completion.bash |   4 +-
 parse-options.h|   4 +-
 ref-filter.c   |  19 +++--
 ref-filter.h   |   1 +
 t/t3201-branch-contains.sh |  51 -
 t/t6302-for-each-ref-filter.sh |  16 +
 t/t7004-tag.sh | 128 +++--
 13 files changed, 240 insertions(+), 25 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 092f1bcf9f..5e52fc9b91 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -11,7 +11,7 @@ SYNOPSIS
 'git branch' [--color[=] | --no-color] [-r | -a]
[--list] [-v [--abbrev= | --no-abbrev]]
[--column[=] | --no-column]
-   [(--merged | --no-merged | --contains) []] [--sort=]
+   [(--merged | --no-merged | --contains | --no-contains) []] 
[--sort=]
[--points-at ] [--format=] [...]
 'git branch' [--set-upstream | --track | --no-track] [-l] [-f]  
[]
 'git branch' (--set-upstream-to= | -u ) []
@@ -35,7 +35,7 @@ as branch creation.
 
 With `--contains`, shows only the branches that contain the named commit
 (in other words, the branches whose tip commits are descendants of the
-named commit).  With `--merged`, only branches merged into the named
+named commit), `--no-contains` inverts it. With `--merged`, only branches 
merged into the named
 commit (i.e. the branches whose tip commits are reachable from the named
 commit) will be listed.  With `--no-merged` only branches not merged into
 the named commit will be listed.  If the  argument is missing it
@@ -213,6 +213,10 @@ start-point is either a local or remote-tracking branch.
Only list branches which contain the specified commit (HEAD
if not specified). Implies `--list`.
 
+--no-contains []::
+   Only list branches which don't contain the specified commit
+   (HEAD if not specified). Implies `--list`.
+
 --merged []::
Only list branches whose tips are reachable from the
specified commit (HEAD if not specified). Implies `--list`.
@@ -296,13 +300,16 @@ If you are creating a branch that you want to checkout 
immediately, it is
 easier to use the git checkout command with its `-b` option to create
 a branch and check it out with a single command.
 
-The options `--contains`, `--merged` and `--no-merged` serve three related
-but different purposes:
+The options `--contains`, `--no-contains`, `--merged` and `--no-merged`
+serve four related but different purposes:
 
 - `--contains ` is used to find all branches which will need
   special attention if  were to be rebased or amended, since those
   branches contain the specified .
 
+- `--no-contains ` is the 

[PATCH 3/8] tag: Change misleading --list documentation

2017-03-18 Thread Ævar Arnfjörð Bjarmason
Change the documentation for --list so that it's described as a
toggle, not as an option that takes a  as an argument.

Junio initially documented this in b867c7c23a ("git-tag: -l to list
tags (usability).", 2006-02-17), but later Jeff King changed "tag" to
accept multiple patterns in 588d0e834b ("tag: accept multiple patterns
for --list", 2011-06-20).

However, documenting this as "-l " was never correct, as
these both worked before Jeff's change:

git tag -l 'v*'
git tag 'v*' -l

One would expect an option that was documented like that to only
accept:

git tag --list
git tag --list 'v*rc*'

And after Jeff's change, one that took multiple patterns:

git tag --list 'v*rc*' --list '*2.8*'

But since it's actually a toggle all of these work as well, and
produce identical output to the last example above:

git tag --list 'v*rc*' '*2.8*'
git tag --list 'v*rc*' '*2.8*' --list --list --list
git tag --list 'v*rc*' '*2.8*' --list -l --list -l --list

Now the documentation is more in tune with how the "branch" command
describes its --list option since commit cddd127b9a ("branch:
introduce --list option", 2011-08-28).

Change the test suite to assert that these invocations work for the
cases that weren't already being tested for.

Signed-off-by: Ævar Arnfjörð Bjarmason 
---
 Documentation/git-tag.txt | 16 +---
 t/t7004-tag.sh| 21 +
 2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 525737a5d8..848e8c1b73 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -87,13 +87,15 @@ OPTIONS
If no number is given to `-n`, only the first line is printed.
If the tag is not annotated, the commit message is displayed instead.
 
--l ::
---list ::
-   List tags with names that match the given pattern (or all if no
-   pattern is given).  Running "git tag" without arguments also
-   lists all tags. The pattern is a shell wildcard (i.e., matched
-   using fnmatch(3)).  Multiple patterns may be given; if any of
-   them matches, the tag is shown.
+-l::
+--list::
+   Activate the list mode. `git tag ` would try to create a
+   tag, use `git tag --list ` to list matching branches, (or
+   all if no pattern is given).
++
+Running "git tag" without arguments also lists all tags. The pattern
+is a shell wildcard (i.e., matched using fnmatch(3)). Multiple
+patterns may be given; if any of them matches, the tag is shown.
 
 --sort=::
Sort based on the key given.  Prefix `-` to sort in
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 74fc82a3c0..d36cd51fe2 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -118,6 +118,18 @@ test_expect_success 'listing all tags if one exists should 
succeed' '
git tag
 '
 
+cat >expect actual &&
+   test_cmp expect actual &&
+   git tag --list -l --list >actual &&
+   test_cmp expect actual
+'
+
 test_expect_success 'listing all tags if one exists should output that tag' '
test $(git tag -l) = mytag &&
test $(git tag) = mytag
@@ -336,6 +348,15 @@ test_expect_success 'tag -l can accept multiple patterns' '
test_cmp expect actual
 '
 
+test_expect_success 'tag -l can accept multiple patterns interleaved with -l 
or --list options' '
+   git tag -l "v1*" "v0*" >actual &&
+   test_cmp expect actual &&
+   git tag -l "v1*" --list "v0*" >actual &&
+   test_cmp expect actual &&
+   git tag -l "v1*" "v0*" -l --list >actual &&
+   test_cmp expect actual
+'
+
 test_expect_success 'listing tags in column' '
COLUMNS=40 git tag -l --column=row >actual &&
cat >expected <<\EOF &&
-- 
2.11.0



[PATCH 7/8] tag: Add tests for --with and --without

2017-03-18 Thread Ævar Arnfjörð Bjarmason
Change the test suite to test for these options. Before this change
there were no tests for this at all. This change doesn't exhaustively
test for them as well as their --contains and --no-contains aliases,
but at least it's something.

Signed-off-by: Ævar Arnfjörð Bjarmason 
---
 t/t7004-tag.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 428e21c369..f7ff4e034b 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -1592,7 +1592,7 @@ test_expect_success 'mixing incompatibles modes and 
options is forbidden' '
test_must_fail git tag --contains --no-contains
 '
 
-for option in --contains --no-contains --merged --no-merged --points-at
+for option in --contains --with --no-contains --without --merged --no-merged 
--points-at
 do
test_expect_success "mixing incompatible modes with $option is 
forbidden" "
test_must_fail git tag -d $option HEAD &&
-- 
2.11.0



[PATCH 4/8] tag: Implicitly supply --list given another list-like option

2017-03-18 Thread Ævar Arnfjörð Bjarmason
Change the "tag" command to implicitly turn on its --list mode when
provided with a list-like option such as --contains, --points-at etc.

This is for consistency with how "branch" works. When "branch" is
given a list-like option, such as --contains, it implicitly provides
--list. Before this change "tag" would error out on those sorts of
invocations. I.e. while both of these worked for "branch":

git branch --contains v2.8.0 
git branch --list --contains v2.8.0 

Only the latter form worked for "tag":

git tag --contains v2.8.0 '*rc*'
git tag --list --contains v2.8.0 '*rc*'

Now "tag", like "branch" will implicitly supply --list in when a
list-like option is provided, and no other conflicting non-list
options (such as -d) are present on the command-line.

Spelunking through the history via:

git log --reverse -p -G'only allowed with' -- '*builtin*tag*c'

Reveals that there was no good reason for not allowing this in the
first place. The --contains option added in 32c35cfb1e ("git-tag: Add
--contains option", 2009-01-26) made this an error, and all the other
subsequent list-like options that were added copied its pattern of
making this usage an error.

The only tests that break as a result of this change are tests that
were explicitly checking that this "branch-like" usage wasn't
permitted. Change those failing tests to check that this invocation
mode is permitted, add extra tests for the list-like options we
weren't testing, and add tests to ensure that e.g. we don't toggle the
--list in the presence of other conflicting non-list options.

With this change errors messages such as "--contains option is only
allowed with -l" don't make sense anymore, since options like
--contain turn on -l. Instead we error out when list-like options such
as --contain are used in conjunction with conflicting options such as
-d or -v.

This change does not consider "-n" a list-like option, even though
that might be logical. Permitting it would allow:

git tag -n 100

As a synonym for:

git tag -n --list 100

Which, while not technically ambiguous as the option must already be
provided as -n rather than -n , would be confusing.

Signed-off-by: Ævar Arnfjörð Bjarmason 
---
 Documentation/git-tag.txt | 10 +++---
 builtin/tag.c | 25 +++--
 t/t7004-tag.sh| 39 +++
 3 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 848e8c1b73..2acd3b6beb 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -96,6 +96,10 @@ OPTIONS
 Running "git tag" without arguments also lists all tags. The pattern
 is a shell wildcard (i.e., matched using fnmatch(3)). Multiple
 patterns may be given; if any of them matches, the tag is shown.
++
+This option is implicitly supplied if any other list-like option such
+as `--contains` is provided. See the documentation for each of those
+options for details.
 
 --sort=::
Sort based on the key given.  Prefix `-` to sort in
@@ -124,10 +128,10 @@ This option is only applicable when listing tags without 
annotation lines.
 
 --contains []::
Only list tags which contain the specified commit (HEAD if not
-   specified).
+   specified). Implies `--list`.
 
 --points-at ::
-   Only list tags of the given object.
+   Only list tags of the given object. Implies `--list`.
 
 -m ::
 --message=::
@@ -178,7 +182,7 @@ This option is only applicable when listing tags without 
annotation lines.
 --[no-]merged []::
Only list tags whose tips are reachable, or not reachable
if `--no-merged` is used, from the specified commit (`HEAD`
-   if not specified).
+   if not specified). Implies `--list`.
 
 CONFIGURATION
 -
diff --git a/builtin/tag.c b/builtin/tag.c
index 0bba3fd070..3483636e59 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -454,8 +454,12 @@ int cmd_tag(int argc, const char **argv, const char 
*prefix)
}
create_tag_object = (opt.sign || annotate || msg.given || msgfile);
 
-   if (argc == 0 && !cmdmode && !create_tag_object)
-   cmdmode = 'l';
+   if (!cmdmode && !create_tag_object) {
+   if (argc == 0)
+   cmdmode = 'l';
+   else if (filter.with_commit || filter.points_at.nr || 
filter.merge_commit)
+   cmdmode = 'l';
+   }
 
if ((create_tag_object || force) && (cmdmode || (!cmdmode && !argc)))
usage_with_options(git_tag_usage, options);
@@ -483,15 +487,16 @@ int cmd_tag(int argc, const char **argv, const char 
*prefix)
if (column_active(colopts))
stop_column_filter();
return ret;
+   } else {
+   if (filter.lines != -1)
+   die(_("-n option is only allowed in list mode."));
+   if (filter.with_commit)
+  

[PATCH 8/8] tag: Change --point-at to default to HEAD

2017-03-18 Thread Ævar Arnfjörð Bjarmason
Change the --points-at option to default to HEAD for consistency with
its siblings --contains, --merged etc. which default to HEAD. This
changes behavior added in commit ae7706b9ac (tag: add --points-at list
option, 2012-02-08).

Signed-off-by: Ævar Arnfjörð Bjarmason 
---
 Documentation/git-tag.txt | 3 ++-
 builtin/tag.c | 3 ++-
 t/t7004-tag.sh| 8 +++-
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index d0b506f120..1d66348b6a 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -136,7 +136,8 @@ This option is only applicable when listing tags without 
annotation lines.
not specified). Implies `--list`.
 
 --points-at ::
-   Only list tags of the given object. Implies `--list`.
+   Only list tags of the given object (HEAD if not
+   specified). Implies `--list`.
 
 -m ::
 --message=::
diff --git a/builtin/tag.c b/builtin/tag.c
index f91ae171b7..300f831fb1 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -433,7 +433,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 N_("field name to sort on"), 
_opt_ref_sorting),
{
OPTION_CALLBACK, 0, "points-at", _at, 
N_("object"),
-   N_("print only tags of the object"), 0, 
parse_opt_object_name
+   N_("print only tags of the object"), 
PARSE_OPT_LASTARG_DEFAULT,
+   parse_opt_object_name, (intptr_t) "HEAD"
},
OPT_STRING(  0 , "format", , N_("format"), N_("format to 
use for the output")),
OPT_BOOL('i', "ignore-case", , N_("sorting and filtering 
are case insensitive")),
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index f7ff4e034b..112d96b4ce 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -1601,7 +1601,8 @@ do
"
test_expect_success "Doing 'git tag --list-like $option  
 is permitted" "
git tag -n $option HEAD HEAD &&
-   git tag $option HEAD HEAD
+   git tag $option HEAD HEAD &&
+   git tag $option
"
 done
 
@@ -1613,6 +1614,11 @@ test_expect_success '--points-at can be used in non-list 
mode' '
test_cmp expect actual
 '
 
+test_expect_success '--points-at is a synonym for --points-at HEAD' '
+   git tag --points-at >actual &&
+   test_cmp expect actual
+'
+
 test_expect_success '--points-at finds lightweight tags' '
echo v4.0 >expect &&
git tag --points-at v4.0 >actual &&
-- 
2.11.0



  1   2   >