Re: [PATCH 1/8] tag: Remove a TODO item from the test suite
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?
On Sat, 18 Mar 2017, Junio C Hamano wrote: David Langwrites: 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?
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 Hamanowrote: > 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
Junio C Hamanowrites: > 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
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
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
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
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
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
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?
David Langwrites: >> 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?
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
On Sat, Mar 18, 2017 at 11:23 PM, Dennis Kaarsemakerwrote: > 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
Le samedi 18 mars 2017, 12:41:22 CET Junio C Hamano a écrit : > Jean-Noel Avilawrites: > > 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
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?
On Sat, 18 Mar 2017, Junio C Hamano wrote: Ævar Arnfjörð Bjarmasonwrites: 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
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
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
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
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
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
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
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
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
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
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
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^@
On Sat, Mar 18, 2017 at 9:18 PM, Junio C Hamanowrote: > 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
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
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
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
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
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
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 *
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
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
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
On Fri, Mar 17, 2017 at 1:23 AM, Joe Rayhawkwrote: > 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^@
Andreas Gruenbacherwrites: > 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..."
Ævar Arnfjörð Bjarmasonwrites: > ...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
On Sat, Mar 18, 2017 at 8:27 PM, Junio C Hamanowrote: > Æ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
On Sat, Mar 18, 2017 at 7:54 PM, Junio C Hamanowrote: > Æ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^@
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
On Sat, Mar 18, 2017 at 7:43 PM, Junio C Hamanowrote: > Æ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
Jean-Noel Avilawrites: > 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
Ævar Arnfjörð Bjarmasonwrites: > 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
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?
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'
Junio C Hamanowrites: > 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..."
On Sat, Mar 18, 2017 at 8:04 PM, Junio C Hamanowrote: > Æ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
On Sat, Mar 18, 2017 at 7:35 PM, Junio C Hamanowrote: > Æ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?
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
Ævar Arnfjörð Bjarmasonwrites: > 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..."
Ævar Arnfjörð Bjarmasonwrites: > 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'
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
Ævar Arnfjörð Bjarmasonwrites: > 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?
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
Ævar Arnfjörð Bjarmasonwrites: > 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
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
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
On Sat, Mar 18, 2017 at 7:14 PM, Junio C Hamanowrote: > 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..."
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
Ævar Arnfjörð Bjarmasonwrites: > 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'
'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
Ævar Arnfjörð Bjarmasonwrites: > 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?
Ævar Arnfjörð Bjarmasonwrites: > 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
Nguyễn Thái Ngọc Duywrites: > --- 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()
Nguyễn Thái Ngọc Duywrites: > 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
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
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
Nguyễn Thái Ngọc Duywrites: > 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'
On Sat, Mar 18, 2017 at 4:12 PM, SZEDER Gáborwrote: > 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
Duy Nguyenwrites: > 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
£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
Stefan Bellerwrites: >> 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()
Jeff Kingwrites: > 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?
On Sat, Mar 18, 2017 at 3:58 PM, David Langwrote: > 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
Brandon Williamswrites: > 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
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
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!!
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
On Fri, Mar 17, 2017 at 3:55 PM, Jeff Kingwrote: > 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'
'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?
On Sat, 18 Mar 2017, Ævar Arnfjörð Bjarmason wrote: On Sat, Mar 18, 2017 at 3:29 PM, David Langwrote: 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?
On Sat, Mar 18, 2017 at 3:29 PM, David Langwrote: > 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?
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
> Torsten Bögershausenhat 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.
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()
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
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
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
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()
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()
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()
--- 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
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
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
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
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
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