From 3444ec2eb2be58c285d2bf04f39e6e9ea5eda9a2 Mon Sep 17 00:00:00 2001 From: William Baker Date: Fri, 11 Oct 2019 13:11:23 -0700 Subject: [PATCH 01/18] fsmonitor: don't fill bitmap with entries to be removed While doing some testing with fsmonitor enabled I found that git commands would segfault after staging and unstaging an untracked file. Looking at the crash it appeared that fsmonitor_ewah_callback was attempting to adjust bits beyond the bounds of the index cache. Digging into how this could happen it became clear that the fsmonitor extension must have been written with more bits than there were entries in the index. The root cause ended up being that fill_fsmonitor_bitmap was populating fsmonitor_dirty with bits for all entries in the index, even those that had been marked for removal. To solve this problem fill_fsmonitor_bitmap has been updated to skip entries with the the CE_REMOVE flag set. With this change the bits written for the fsmonitor extension will be consistent with the index entries written by do_write_index. Additionally, BUG checks have been added to detect if the number of bits in fsmonitor_dirty should ever exceed the number of entries in the index again. Another option that was considered was moving the call to fill_fsmonitor_bitmap closer to where the index is written (and where the fsmonitor extension itself is written). However, that did not work as the fsmonitor_dirty bitmap must be filled before the index is split during writing. Signed-off-by: William Baker Signed-off-by: Junio C Hamano --- fsmonitor.c | 29 ++++++++++++++++++++++++----- t/t7519-status-fsmonitor.sh | 17 +++++++++++++++++ t/t7519/fsmonitor-env | 24 ++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 5 deletions(-) create mode 100755 t/t7519/fsmonitor-env diff --git a/fsmonitor.c b/fsmonitor.c index 231e83a94d..1f4aa1b150 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -14,8 +14,13 @@ struct trace_key trace_fsmonitor = TRACE_KEY_INIT(FSMONITOR); static void fsmonitor_ewah_callback(size_t pos, void *is) { struct index_state *istate = (struct index_state *)is; - struct cache_entry *ce = istate->cache[pos]; + struct cache_entry *ce; + if (pos >= istate->cache_nr) + BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" >= %u)", + (uintmax_t)pos, istate->cache_nr); + + ce = istate->cache[pos]; ce->ce_flags &= ~CE_FSMONITOR_VALID; } @@ -50,17 +55,24 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data, } istate->fsmonitor_dirty = fsmonitor_dirty; + if (istate->fsmonitor_dirty->bit_size > istate->cache_nr) + BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)", + (uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr); + trace_printf_key(&trace_fsmonitor, "read fsmonitor extension successful"); return 0; } void fill_fsmonitor_bitmap(struct index_state *istate) { - unsigned int i; + unsigned int i, skipped = 0; istate->fsmonitor_dirty = ewah_new(); - for (i = 0; i < istate->cache_nr; i++) - if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID)) - ewah_set(istate->fsmonitor_dirty, i); + for (i = 0; i < istate->cache_nr; i++) { + if (istate->cache[i]->ce_flags & CE_REMOVE) + skipped++; + else if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID)) + ewah_set(istate->fsmonitor_dirty, i - skipped); + } } void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate) @@ -71,6 +83,10 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate) uint32_t ewah_size = 0; int fixup = 0; + if (istate->fsmonitor_dirty->bit_size > istate->cache_nr) + BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)", + (uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr); + put_be32(&hdr_version, INDEX_EXTENSION_VERSION); strbuf_add(sb, &hdr_version, sizeof(uint32_t)); @@ -236,6 +252,9 @@ void tweak_fsmonitor(struct index_state *istate) } /* Mark all previously saved entries as dirty */ + if (istate->fsmonitor_dirty->bit_size > istate->cache_nr) + BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)", + (uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr); ewah_each_bit(istate->fsmonitor_dirty, fsmonitor_ewah_callback, istate); /* Now mark the untracked cache for fsmonitor usage */ diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh index 81a375fa0f..d8df990972 100755 --- a/t/t7519-status-fsmonitor.sh +++ b/t/t7519-status-fsmonitor.sh @@ -354,4 +354,21 @@ test_expect_success 'discard_index() also discards fsmonitor info' ' test_cmp expect actual ' +# Test staging/unstaging files that appear at the end of the index. Test +# file names begin with 'z' so that they are sorted to the end of the index. +test_expect_success 'status succeeds after staging/unstaging ' ' + test_create_repo fsmonitor-stage-unstage && + ( + cd fsmonitor-stage-unstage && + test_commit initial && + git update-index --fsmonitor && + removed=$(test_seq 1 100 | sed "s/^/z/") && + touch $removed && + git add $removed && + git config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-env" && + FSMONITOR_LIST="$removed" git restore -S $removed && + FSMONITOR_LIST="$removed" git status + ) +' + test_done diff --git a/t/t7519/fsmonitor-env b/t/t7519/fsmonitor-env new file mode 100755 index 0000000000..8f1f7ab164 --- /dev/null +++ b/t/t7519/fsmonitor-env @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An test hook script to integrate with git to test fsmonitor. +# +# The hook is passed a version (currently 1) and a time in nanoseconds +# formatted as a string and outputs to stdout all files that have been +# modified since the given time. Paths must be relative to the root of +# the working tree and separated by a single NUL. +# +#echo "$0 $*" >&2 + +if test "$#" -ne 2 +then + echo "$0: exactly 2 arguments expected" >&2 + exit 2 +fi + +if test "$1" != 1 +then + echo "Unsupported core.fsmonitor hook version." >&2 + exit 1 +fi + +printf '%s\n' $FSMONITOR_LIST From 3b3c79f6c9cdd3fc6f5231e2d8c53ee732cfc771 Mon Sep 17 00:00:00 2001 From: Norman Rasmussen Date: Tue, 15 Oct 2019 03:31:26 +0000 Subject: [PATCH 02/18] diff-highlight: fix a whitespace nit This changes the indent from "" to "" so that the statement lines up with the rest of the block. Signed-off-by: Norman Rasmussen Acked-by: Jeff King Signed-off-by: Junio C Hamano --- contrib/diff-highlight/DiffHighlight.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/diff-highlight/DiffHighlight.pm b/contrib/diff-highlight/DiffHighlight.pm index 7440aa1c46..e2589922a6 100644 --- a/contrib/diff-highlight/DiffHighlight.pm +++ b/contrib/diff-highlight/DiffHighlight.pm @@ -72,7 +72,7 @@ sub handle_line { (?:$COLOR?\|$COLOR?[ ])* # zero or more trailing "|" [ ]* # trailing whitespace for merges /x) { - my $graph_prefix = $&; + my $graph_prefix = $&; # We must flush before setting graph indent, since the # new commit may be indented differently from what we From 6f1194246a514ba093a11dde73aabe4c0da5526f Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Wed, 16 Oct 2019 23:45:34 +0000 Subject: [PATCH 03/18] remote-curl: pass on atomic capability to remote side When pushing more than one reference with the --atomic option, the server is supposed to perform a single atomic transaction to update the references, leaving them either all to succeed or all to fail. This works fine when pushing locally or over SSH, but when pushing over HTTP, we fail to pass the atomic capability to the remote side. In fact, we have not reported this capability to any remote helpers during the life of the feature. Now normally, things happen to work nevertheless, since we actually check for most types of failures, such as non-fast-forward updates, on the client side, and just abort the entire attempt. However, if the server side reports a problem, such as the inability to lock a ref, the transaction isn't atomic, because we haven't passed the appropriate capability over and the remote side has no way of knowing that we wanted atomic behavior. Fix this by passing the option from the transport code through to remote helpers, and from the HTTP remote helper down to send-pack. With this change, we can detect if the server side rejects the push and report back appropriately. Note the difference in the messages: the remote side reports "atomic transaction failed", while our own checking rejects pushes with the message "atomic push failed". Document the atomic option in the remote helper documentation, so other implementers can implement it if they like. Signed-off-by: brian m. carlson Signed-off-by: Junio C Hamano --- Documentation/gitremote-helpers.txt | 5 ++++ remote-curl.c | 13 +++++++++- t/t5541-http-push-smart.sh | 40 +++++++++++++++++++++++++++-- transport-helper.c | 4 +++ transport.h | 3 +++ 5 files changed, 62 insertions(+), 3 deletions(-) diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt index 43f80c8068..03b3a6883f 100644 --- a/Documentation/gitremote-helpers.txt +++ b/Documentation/gitremote-helpers.txt @@ -505,6 +505,11 @@ set by Git if the remote helper has the 'option' capability. Indicate that only the objects wanted need to be fetched, not their dependents. +'option atomic' {'true'|'false'}:: + When pushing, request the remote server to update refs in a single atomic + transaction. If successful, all refs will be updated, or none will. If the + remote side does not support this capability, the push will fail. + SEE ALSO -------- linkgit:git-remote[1] diff --git a/remote-curl.c b/remote-curl.c index 051f26629d..5232ed84b6 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -40,7 +40,8 @@ struct options { push_cert : 2, deepen_relative : 1, from_promisor : 1, - no_dependents : 1; + no_dependents : 1, + atomic : 1; }; static struct options options; static struct string_list cas_options = STRING_LIST_INIT_DUP; @@ -148,6 +149,14 @@ static int set_option(const char *name, const char *value) else return -1; return 0; + } else if (!strcmp(name, "atomic")) { + if (!strcmp(value, "true")) + options.atomic = 1; + else if (!strcmp(value, "false")) + options.atomic = 0; + else + return -1; + return 0; } else if (!strcmp(name, "push-option")) { if (*value != '"') string_list_append(&options.push_options, value); @@ -1196,6 +1205,8 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs) argv_array_push(&args, "--signed=yes"); else if (options.push_cert == SEND_PACK_PUSH_CERT_IF_ASKED) argv_array_push(&args, "--signed=if-asked"); + if (options.atomic) + argv_array_push(&args, "--atomic"); if (options.verbosity == 0) argv_array_push(&args, "--quiet"); else if (options.verbosity > 1) diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index b86ddb60f2..3aec962cd8 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -184,11 +184,12 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat test_config -C "$d" http.receivepack true && up="$HTTPD_URL"/smart/atomic-branches.git && - # Tell "$up" about two branches for now + # Tell "$up" about three branches for now test_commit atomic1 && test_commit atomic2 && git branch collateral && - git push "$up" master collateral && + git branch other && + git push "$up" master collateral other && # collateral is a valid push, but should be failed by atomic push git checkout collateral && @@ -226,6 +227,41 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output ' +test_expect_success 'push --atomic fails on server-side errors' ' + # Use previously set up repository + d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git && + test_config -C "$d" http.receivepack true && + up="$HTTPD_URL"/smart/atomic-branches.git && + + # break ref updates for other on the remote site + mkdir "$d/refs/heads/other.lock" && + + # add the new commit to other + git branch -f other collateral && + + # --atomic should cause entire push to be rejected + test_must_fail git push --atomic "$up" atomic other 2>output && + + # the new branch should not have been created upstream + test_must_fail git -C "$d" show-ref --verify refs/heads/atomic && + + # upstream should still reflect atomic2, the last thing we pushed + # successfully + git rev-parse atomic2 >expected && + # ...to other. + git -C "$d" rev-parse refs/heads/other >actual && + test_cmp expected actual && + + # the new branch should not have been created upstream + test_must_fail git -C "$d" show-ref --verify refs/heads/atomic && + + # the failed refs should be indicated to the user + grep "^ ! .*rejected.* other -> other .*atomic transaction failed" output && + + # the collateral failure refs should be indicated to the user + grep "^ ! .*rejected.* atomic -> atomic .*atomic transaction failed" output +' + test_expect_success 'push --all can push to empty repo' ' d=$HTTPD_DOCUMENT_ROOT_PATH/empty-all.git && git init --bare "$d" && diff --git a/transport-helper.c b/transport-helper.c index 6b05a88faf..1ecaa9101a 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -840,6 +840,10 @@ static void set_common_push_options(struct transport *transport, die(_("helper %s does not support --signed=if-asked"), name); } + if (flags & TRANSPORT_PUSH_ATOMIC) + if (set_helper_option(transport, TRANS_OPT_ATOMIC, "true") != 0) + die(_("helper %s does not support --atomic"), name); + if (flags & TRANSPORT_PUSH_OPTIONS) { struct string_list_item *item; for_each_string_list_item(item, transport->push_options) diff --git a/transport.h b/transport.h index 0b5f7806f6..e0131daab9 100644 --- a/transport.h +++ b/transport.h @@ -208,6 +208,9 @@ void transport_check_allowed(const char *type); /* Filter objects for partial clone and fetch */ #define TRANS_OPT_LIST_OBJECTS_FILTER "filter" +/* Request atomic (all-or-nothing) updates when pushing */ +#define TRANS_OPT_ATOMIC "atomic" + /** * Returns 0 if the option was used, non-zero otherwise. Prints a * message to stderr if the option is not used. From 57d4660468ef2674bb6afc2c5814d4b397a5eda9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Wed, 16 Oct 2019 12:10:22 +0000 Subject: [PATCH 04/18] grep: make PCRE1 aware of custom allocator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 63e7e9d8b6 ("git-grep: Learn PCRE", 2011-05-09) didn't include a way to override the system alocator, and so it is incompatible with USE_NED_ALLOCATOR as reported by Dscho[1] (in similar code from PCRE2) Note that nedmalloc, as well as other custom allocators like jemalloc and mi-malloc, can be configured at runtime (via `LD_PRELOAD`), therefore we cannot know at compile time whether a custom allocator is used or not. Make the minimum change possible to ensure this combination is supported by extending `grep_init()` to set the PCRE1 specific functions to Git's idea of `malloc()` and `free()` and therefore making sure all allocations are done inside PCRE1 with the same allocator than the rest of Git. This change has negligible performance impact: PCRE needs to allocate memory once per program run for the character table and for each pattern compilation. These are both rare events compared to matching patterns against lines. Actual measurements[2] show that the impact is lost in the noise. [1] https://public-inbox.org/git/pull.306.git.gitgitgadget@gmail.com [2] https://public-inbox.org/git/7f42007f-911b-c570-17f6-1c6af0429586@web.de Signed-off-by: Carlo Marcelo Arenas Belón Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- grep.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/grep.c b/grep.c index cd952ef5d3..db6e0d895f 100644 --- a/grep.c +++ b/grep.c @@ -150,12 +150,20 @@ int grep_config(const char *var, const char *value, void *cb) * Initialize one instance of grep_opt and copy the * default values from the template we read the configuration * information in an earlier call to git_config(grep_config). + * + * If using PCRE, make sure that the library is configured + * to use the same allocator as Git (e.g. nedmalloc on Windows). */ void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix) { struct grep_opt *def = &grep_defaults; int i; +#ifdef USE_LIBPCRE1 + pcre_malloc = malloc; + pcre_free = free; +#endif + memset(opt, 0, sizeof(*opt)); opt->repo = repo; opt->prefix = prefix; From 513f2b0bbd47015640723a10210c527839e8946a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Wed, 16 Oct 2019 12:10:23 +0000 Subject: [PATCH 05/18] grep: make PCRE2 aware of custom allocator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 94da9193a6 (grep: add support for PCRE v2, 2017-06-01) didn't include a way to override the system allocator, and so it is incompatible with custom allocators (e.g. nedmalloc). This problem became obvious when we tried to plug a memory leak by `free()`ing a data structure allocated by PCRE2, triggering a segfault in Windows (where we use nedmalloc by default). PCRE2 requires the use of a general context to override the allocator and therefore, there is a lot more code needed than in PCRE1, including a couple of wrapper functions. Extend the grep API with a "destructor" that could be called to cleanup any objects that were created and used globally. Update `builtin/grep.c` to use that new API, but any other future users should make sure to have matching `grep_init()`/`grep_destroy()` calls if they are using the pattern matching functionality. Move some of the logic that was before done per thread (in the workers) into an earlier phase to avoid degrading performance, but as the use of PCRE2 with custom allocators is better understood it is expected more of its functions will be instructed to use the custom allocator as well as was done in the original code[1] this work was based on. [1] https://public-inbox.org/git/3397e6797f872aedd18c6d795f4976e1c579514b.1565005867.git.gitgitgadget@gmail.com/ Reported-by: Johannes Schindelin Signed-off-by: Carlo Marcelo Arenas Belón Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin/grep.c | 1 + grep.c | 34 +++++++++++++++++++++++++++++++++- grep.h | 1 + 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/builtin/grep.c b/builtin/grep.c index 560051784e..e49c20df60 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -1145,5 +1145,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix) run_pager(&opt, prefix); clear_pathspec(&pathspec); free_grep_patterns(&opt); + grep_destroy(); return !hit; } diff --git a/grep.c b/grep.c index db6e0d895f..296edbb56f 100644 --- a/grep.c +++ b/grep.c @@ -16,6 +16,20 @@ static int grep_source_is_binary(struct grep_source *gs, static struct grep_opt grep_defaults; +#ifdef USE_LIBPCRE2 +static pcre2_general_context *pcre2_global_context; + +static void *pcre2_malloc(PCRE2_SIZE size, MAYBE_UNUSED void *memory_data) +{ + return malloc(size); +} + +static void pcre2_free(void *pointer, MAYBE_UNUSED void *memory_data) +{ + return free(pointer); +} +#endif + static const char *color_grep_slots[] = { [GREP_COLOR_CONTEXT] = "context", [GREP_COLOR_FILENAME] = "filename", @@ -153,12 +167,20 @@ int grep_config(const char *var, const char *value, void *cb) * * If using PCRE, make sure that the library is configured * to use the same allocator as Git (e.g. nedmalloc on Windows). + * + * Any allocated memory needs to be released in grep_destroy(). */ void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix) { struct grep_opt *def = &grep_defaults; int i; +#if defined(USE_LIBPCRE2) + if (!pcre2_global_context) + pcre2_global_context = pcre2_general_context_create( + pcre2_malloc, pcre2_free, NULL); +#endif + #ifdef USE_LIBPCRE1 pcre_malloc = malloc; pcre_free = free; @@ -186,6 +208,13 @@ void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix color_set(opt->colors[i], def->colors[i]); } +void grep_destroy(void) +{ +#ifdef USE_LIBPCRE2 + pcre2_general_context_free(pcre2_global_context); +#endif +} + static void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt) { /* @@ -505,9 +534,12 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt p->pcre2_compile_context = NULL; + /* pcre2_global_context is initialized in append_grep_pattern */ if (opt->ignore_case) { if (has_non_ascii(p->pattern)) { - character_tables = pcre2_maketables(NULL); + if (!pcre2_global_context) + BUG("pcre2_global_context uninitialized"); + character_tables = pcre2_maketables(pcre2_global_context); p->pcre2_compile_context = pcre2_compile_context_create(NULL); pcre2_set_character_tables(p->pcre2_compile_context, character_tables); } diff --git a/grep.h b/grep.h index 1875880f37..526c2db9ef 100644 --- a/grep.h +++ b/grep.h @@ -189,6 +189,7 @@ struct grep_opt { void init_grep_defaults(struct repository *); int grep_config(const char *var, const char *value, void *); void grep_init(struct grep_opt *, struct repository *repo, const char *prefix); +void grep_destroy(void); void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt); void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t); From 10da030ab757c38a01507bf18e2484698000b791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Wed, 16 Oct 2019 12:10:24 +0000 Subject: [PATCH 06/18] grep: avoid leak of chartables in PCRE2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 94da9193a6 ("grep: add support for PCRE v2", 2017-06-01) introduced a small memory leak visible with valgrind in t7813. Complete the creation of a PCRE2 specific variable that was missing from the original change and free the generated table just like it is done for PCRE1. Signed-off-by: Carlo Marcelo Arenas Belón Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- grep.c | 7 ++++--- grep.h | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/grep.c b/grep.c index 296edbb56f..9556d13dc1 100644 --- a/grep.c +++ b/grep.c @@ -525,7 +525,6 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt PCRE2_UCHAR errbuf[256]; PCRE2_SIZE erroffset; int options = PCRE2_MULTILINE; - const uint8_t *character_tables = NULL; int jitret; int patinforet; size_t jitsizearg; @@ -539,9 +538,10 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt if (has_non_ascii(p->pattern)) { if (!pcre2_global_context) BUG("pcre2_global_context uninitialized"); - character_tables = pcre2_maketables(pcre2_global_context); + p->pcre2_tables = pcre2_maketables(pcre2_global_context); p->pcre2_compile_context = pcre2_compile_context_create(NULL); - pcre2_set_character_tables(p->pcre2_compile_context, character_tables); + pcre2_set_character_tables(p->pcre2_compile_context, + p->pcre2_tables); } options |= PCRE2_CASELESS; } @@ -645,6 +645,7 @@ static void free_pcre2_pattern(struct grep_pat *p) pcre2_match_data_free(p->pcre2_match_data); pcre2_jit_stack_free(p->pcre2_jit_stack); pcre2_match_context_free(p->pcre2_match_context); + free((void *)p->pcre2_tables); } #else /* !USE_LIBPCRE2 */ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt) diff --git a/grep.h b/grep.h index 526c2db9ef..533165c21a 100644 --- a/grep.h +++ b/grep.h @@ -96,6 +96,7 @@ struct grep_pat { pcre2_compile_context *pcre2_compile_context; pcre2_match_context *pcre2_match_context; pcre2_jit_stack *pcre2_jit_stack; + const uint8_t *pcre2_tables; uint32_t pcre2_jit_on; kwset_t kws; unsigned fixed:1; From 176f5adfdb01abeede867a305c427cf8b2f48c0e Mon Sep 17 00:00:00 2001 From: Maxim Belsky Date: Fri, 11 Oct 2019 10:54:28 -0700 Subject: [PATCH 07/18] completion: clarify installation instruction for zsh The original comment does not describe type of ~/.zsh/_git explicitly and zsh does not warn or fail if a user create it as a dictionary. So unexperienced users could be misled by the original comment. There is a small update to clarify it. Helped-by: Johannes Schindelin Helped-by: Junio C Hamano Signed-off-by: Maxim Belsky Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.zsh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh index 886bf95d1f..eef4eff53d 100644 --- a/contrib/completion/git-completion.zsh +++ b/contrib/completion/git-completion.zsh @@ -11,8 +11,9 @@ # # zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh # -# The recommended way to install this script is to copy to '~/.zsh/_git', and -# then add the following to your ~/.zshrc file: +# The recommended way to install this script is to make a copy of it in +# ~/.zsh/ directory as ~/.zsh/git-completion.zsh and then add the following +# to your ~/.zshrc file: # # fpath=(~/.zsh $fpath) From 2b6f6ea1bd47f83889c306886e2540faf67efad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Sun, 20 Oct 2019 01:37:06 +0200 Subject: [PATCH 08/18] test-progress: fix test failures on big-endian systems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In 't0500-progress-display.sh' all tests running 'test-tool progress --total=' fail on big-endian systems, e.g. like this: + test-tool progress --total=3 Working hard [...] + test_i18ncmp expect out --- expect 2019-10-18 23:07:54.765523916 +0000 +++ out 2019-10-18 23:07:54.773523916 +0000 @@ -1,4 +1,2 @@ -Working hard: 33% (1/3) -Working hard: 66% (2/3) -Working hard: 100% (3/3) -Working hard: 100% (3/3), done. +Working hard: 0% (1/12884901888) +Working hard: 0% (3/12884901888), done. The reason for that bogus value is that '--total's parameter is parsed via parse-options's OPT_INTEGER into a uint64_t variable [1], so the two bits of 3 end up in the "wrong" bytes on big-endian systems (12884901888 = 0x300000000). Change the type of that variable from uint64_t to int, to match what parse-options expects; in the tests of the progress output we won't use values that don't fit into an int anyway. [1] start_progress() expects the total number as an uint64_t, that's why I chose the same type when declaring the variable holding the value given on the command line. Signed-off-by: SZEDER Gábor [jpag: Debian unstable/ppc64 (big-endian)] Tested-By: John Paul Adrian Glaubitz [tz: Fedora s390x (big-endian)] Tested-By: Todd Zullinger Signed-off-by: Junio C Hamano --- t/helper/test-progress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/helper/test-progress.c b/t/helper/test-progress.c index 4e9f7fafdf..42b96cb103 100644 --- a/t/helper/test-progress.c +++ b/t/helper/test-progress.c @@ -29,7 +29,7 @@ void progress_test_force_update(void); int cmd__progress(int argc, const char **argv) { - uint64_t total = 0; + int total = 0; const char *title; struct strbuf line = STRBUF_INIT; struct progress *progress; From 8da56a484800023a545d7a7c022473f5aa9e720f Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sun, 20 Oct 2019 11:52:30 -0700 Subject: [PATCH 09/18] userdiff: fix some corner cases in dts regex While reviewing some dts diffs recently I noticed that the hunk header logic was failing to find the containing node. This is because the regex doesn't consider properties that may span multiple lines, i.e. property = , ; and it got hung up on comments inside nodes that look like the root node because they start with '/*'. Add tests for these cases and update the regex to find them. Maybe detecting the root node is too complicated but forcing it to be a backslash with any amount of whitespace up to an open bracket seemed OK. I tried to detect that a comment is in-between the two parts but I wasn't happy so I just dropped it. Cc: Rob Herring Cc: Frank Rowand Signed-off-by: Stephen Boyd Reviewed-by: Johannes Sixt Signed-off-by: Junio C Hamano --- t/t4018/dts-nodes-boolean-prop | 9 +++++++++ t/t4018/dts-nodes-multiline-prop | 13 +++++++++++++ t/t4018/dts-root | 2 +- t/t4018/dts-root-comment | 8 ++++++++ userdiff.c | 3 ++- 5 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 t/t4018/dts-nodes-boolean-prop create mode 100644 t/t4018/dts-nodes-multiline-prop create mode 100644 t/t4018/dts-root-comment diff --git a/t/t4018/dts-nodes-boolean-prop b/t/t4018/dts-nodes-boolean-prop new file mode 100644 index 0000000000..afc6b5b404 --- /dev/null +++ b/t/t4018/dts-nodes-boolean-prop @@ -0,0 +1,9 @@ +/ { + label_1: node1@ff00 { + RIGHT@deadf00,4000 { + boolean-prop1; + + ChangeMe; + }; + }; +}; diff --git a/t/t4018/dts-nodes-multiline-prop b/t/t4018/dts-nodes-multiline-prop new file mode 100644 index 0000000000..072d58b69d --- /dev/null +++ b/t/t4018/dts-nodes-multiline-prop @@ -0,0 +1,13 @@ +/ { + label_1: node1@ff00 { + RIGHT@deadf00,4000 { + multilineprop = <3>, + <4>, + <5>, + <6>, + <7>; + + ChangeMe = <0xffeedd00>; + }; + }; +}; diff --git a/t/t4018/dts-root b/t/t4018/dts-root index 2ef9e6ffaa..4353b8220c 100644 --- a/t/t4018/dts-root +++ b/t/t4018/dts-root @@ -1,4 +1,4 @@ -/RIGHT { /* Technically just supposed to be a slash */ +/ { RIGHT /* Technically just supposed to be a slash and brace */ #size-cells = <1>; ChangeMe = <0xffeedd00>; diff --git a/t/t4018/dts-root-comment b/t/t4018/dts-root-comment new file mode 100644 index 0000000000..333a625c70 --- /dev/null +++ b/t/t4018/dts-root-comment @@ -0,0 +1,8 @@ +/ { RIGHT /* Technically just supposed to be a slash and brace */ + #size-cells = <1>; + + /* This comment should be ignored */ + + some-property = <40+2>; + ChangeMe = <0xffeedd00>; +}; diff --git a/userdiff.c b/userdiff.c index 86e3244e15..e187d356f6 100644 --- a/userdiff.c +++ b/userdiff.c @@ -25,8 +25,9 @@ IPATTERN("ada", "|=>|\\.\\.|\\*\\*|:=|/=|>=|<=|<<|>>|<>"), PATTERNS("dts", "!;\n" + "!=\n" /* lines beginning with a word optionally preceded by '&' or the root */ - "^[ \t]*((/|&?[a-zA-Z_]).*)", + "^[ \t]*((/[ \t]*\\{|&?[a-zA-Z_]).*)", /* -- */ /* Property names and math operators */ "[a-zA-Z0-9,._+?#-]+" From 711cd6d15cf9394d1aa0f78c68a7a39b3bb23509 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 21 Oct 2019 19:59:57 +0000 Subject: [PATCH 10/18] ci(visual-studio): use strict compile flags, and optimization To make full use of the work that went into the Visual Studio build & test jobs in our CI/PR builds, let's turn on strict compiler flags. This will give us the benefit of Visual C's compiler warnings (which, at times, seem to catch things that GCC does not catch, and vice versa). While at it, also turn on optimization; It does not make sense to produce binaries with debug information, and we can use any ounce of speed that we get (because the test suite is particularly slow on Windows, thanks to the need to run inside a Unix shell, which requires us to use the POSIX emulation layer provided by MSYS2). Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 875e63cac1..0c28e00026 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -157,7 +157,7 @@ jobs: displayName: 'Download git-sdk-64-minimal' - powershell: | & git-sdk-64-minimal\usr\bin\bash.exe -lc @" - make vcxproj + make NDEBUG=1 DEVELOPER=1 vcxproj "@ if (!$?) { exit(1) } displayName: Generate Visual Studio Solution From 399c23c046fc40cc3637d7e3688dcbe31b27a030 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 21 Oct 2019 19:59:58 +0000 Subject: [PATCH 11/18] ci(visual-studio): actually run the tests in parallel Originally, the CI/PR builds that build and test using Visual Studio were implemented imitating `linux-clang`, i.e. still using the `Makefile`-based build infrastructure. Later (but still before the patches made their way into git.git's `master`), however, this was changed to generate Visual Studio project files and build the binaries using `MSBuild`, as this reflects more accurately how Visual Studio users would want to build Git (internally, Visual Studio uses `MSBuild`, or at least something very similar). During that transition, we needed to implement a new way to run the test suite in parallel, as Visual Studio users typically will only have a Git Bash available (which does not ship with `make` nor with support for `prove`): we simply implemented a new test helper to run the test suite. This helper even knows how to run the tests in parallel, but due to a mistake on this developer's part, it was never turned on in the CI/PR builds. This results in 2x-3x longer run times of the test phase. Let's use the `--jobs=10` option to fix this. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0c28e00026..17a942e213 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -255,7 +255,7 @@ jobs: cd t && PATH=\"`$PWD/helper:`$PATH\" && - test-tool.exe run-command testsuite -V -x --write-junit-xml \ + test-tool.exe run-command testsuite --jobs=10 -V -x --write-junit-xml \ `$(test-tool.exe path-utils slice-tests \ `$SYSTEM_JOBPOSITIONINPHASE `$SYSTEM_TOTALJOBSINPHASE t[0-9]*.sh) "@ From 19c29e538e48ed50286339b0fdd5e62111a724db Mon Sep 17 00:00:00 2001 From: Bert Wesarg Date: Mon, 21 Oct 2019 15:23:42 +0200 Subject: [PATCH 12/18] t4014: make output-directory tests self-contained MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As noted by Gábor in [1], the new tests in edefc31873 ("format-patch: create leading components of output directory", 2019-10-11) cannot be run independently. Fix this. [1] https://public-inbox.org/git/20191011144650.GM29845@szeder.dev/ Signed-off-by: Bert Wesarg Signed-off-by: Junio C Hamano --- t/t4014-format-patch.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index c455181e1d..93a1656f29 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1615,17 +1615,20 @@ test_expect_success 'format-patch -o with no leading directories' ' ' test_expect_success 'format-patch -o with leading existing directories' ' - git format-patch -o patches/side master..side && + rm -rf existing-dir && + mkdir existing-dir && + git format-patch -o existing-dir/patches master..side && count=$(git rev-list --count master..side) && - ls patches/side >list && + ls existing-dir/patches >list && test_line_count = $count list ' test_expect_success 'format-patch -o with leading non-existing directories' ' - rm -fr patches && - git format-patch -o patches/side master..side && + rm -rf non-existing-dir && + git format-patch -o non-existing-dir/patches master..side && count=$(git rev-list --count master..side) && - ls patches/side >list && + test_path_is_dir non-existing-dir && + ls non-existing-dir/patches >list && test_line_count = $count list ' From a8e2c0eadc1a7abe7afdd138a6536dbf402e3c60 Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Tue, 22 Oct 2019 02:57:01 -0700 Subject: [PATCH 13/18] t7419: change test_must_fail to ! for grep According to t/README, test_must_fail() should only be used to test for failure in Git commands. Replace the invocations of `test_must_fail grep` with `! grep`. Signed-off-by: Denton Liu Signed-off-by: Junio C Hamano --- t/t7419-submodule-set-branch.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/t/t7419-submodule-set-branch.sh b/t/t7419-submodule-set-branch.sh index c4b370ea85..fd25f786a3 100755 --- a/t/t7419-submodule-set-branch.sh +++ b/t/t7419-submodule-set-branch.sh @@ -34,7 +34,7 @@ test_expect_success 'submodule config cache setup' ' test_expect_success 'ensure submodule branch is unset' ' (cd super && - test_must_fail grep branch .gitmodules + ! grep branch .gitmodules ) ' @@ -54,7 +54,7 @@ test_expect_success 'test submodule set-branch --branch' ' test_expect_success 'test submodule set-branch --default' ' (cd super && git submodule set-branch --default submodule && - test_must_fail grep branch .gitmodules && + ! grep branch .gitmodules && git submodule update --remote && cat <<-\EOF >expect && a @@ -80,7 +80,7 @@ test_expect_success 'test submodule set-branch -b' ' test_expect_success 'test submodule set-branch -d' ' (cd super && git submodule set-branch -d submodule && - test_must_fail grep branch .gitmodules && + ! grep branch .gitmodules && git submodule update --remote && cat <<-\EOF >expect && a From 0eb3671ed96f74b79e54a1101746882bafe50070 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 23 Oct 2019 00:19:38 +0000 Subject: [PATCH 14/18] ci(osx): use new location of the `perforce` cask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Azure Pipelines builds are failing for macOS due to a change in the location of the perforce cask. The command outputs the following error: + brew install caskroom/cask/perforce Error: caskroom/cask was moved. Tap homebrew/cask-cask instead. So let's try to call `brew cask install perforce` first (which is what that error message suggests, in a most round-about way). Prior to 672f51cb we used to install the 'perforce' package with 'brew install perforce' (note: no 'cask' in there). The justification for 672f51cb was that the command 'brew install perforce' simply stopped working, after Homebrew folks decided that it's better to move the 'perforce' package to a "cask". Their justification for this move was that 'brew install perforce' "can fail due to a checksum mismatch ...", and casks can be installed without checksum verification. And indeed, both 'brew cask install perforce' and 'brew install caskroom/cask/perforce' printed something along the lines of: ==> No checksum defined for Cask perforce, skipping verification It is unclear why 672f51cb used 'brew install caskroom/cask/perforce' instead of 'brew cask install perforce'. It appears (by running both commands on old Travis CI macOS images) that both commands worked all the same already back then. In any case, as the error message at the top of this commit message shows, 'brew install caskroom/cask/perforce' has stopped working recently, but 'brew cask install perforce' still does, so let's use that. CI servers are typically fresh virtual machines, but not always. To accommodate for that, let's try harder if `brew cask install perforce` fails, by specifically pulling the latest `master` of the `homebrew-cask` repository. This will still fail, of course, when `homebrew-cask` falls behind Perforce's release schedule. But once it is updated, we can now simply re-run the failed jobs and they will pick up that update. As for updating `homebrew-cask`: the beginnings of automating this in https://dev.azure.com/gitgitgadget/git/_build?definitionId=11&_a=summary will be finished once the next Perforce upgrade comes around. Helped-by: SZEDER Gábor Signed-off-by: Johannes Schindelin Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- ci/install-dependencies.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index 85a9d6b15c..ce149ed39c 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -40,6 +40,11 @@ osx-clang|osx-gcc) test -z "$BREW_INSTALL_PACKAGES" || brew install $BREW_INSTALL_PACKAGES brew link --force gettext + brew cask install perforce || { + # Update the definitions and try again + git -C "$(brew --repository)"/Library/Taps/homebrew/homebrew-cask pull && + brew cask install perforce + } || brew install caskroom/cask/perforce case "$jobname" in osx-gcc) From d81542e6f3632d1a6185a4e629fade0641f9688b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 23 Oct 2019 14:42:27 +0900 Subject: [PATCH 15/18] Eleventh batch The tenth was at -rc0 ;-) Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.24.0.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/RelNotes/2.24.0.txt b/Documentation/RelNotes/2.24.0.txt index 4b442a9157..125169d0da 100644 --- a/Documentation/RelNotes/2.24.0.txt +++ b/Documentation/RelNotes/2.24.0.txt @@ -75,6 +75,9 @@ UI, Workflows & Features submodules, but this did not apply to "git fetch --multiple" that fetches from multiple remote repositories. It now does. + * The installation instruction for zsh completion script (in + contrib/) has been a bit improved. + Performance, Internal Implementation, Development Support etc. @@ -337,6 +340,10 @@ Fixes since v2.23 corrected. (merge 556895d0c8 jj/stash-reset-only-toplevel later to maint). + * The atomic push over smart HTTP transport did not work, which has + been corrected. + (merge 6f1194246a bc/smart-http-atomic-push later to maint). + * Other code cleanup, docfix, build fix, etc. (merge d1387d3895 en/fast-import-merge-doc later to maint). (merge 1c24a54ea4 bm/repository-layout-typofix later to maint). @@ -385,3 +392,6 @@ Fixes since v2.23 (merge 5cc6a4be11 rs/http-push-simplify later to maint). (merge a81e42d235 rs/column-use-utf8-strnwidth later to maint). (merge 062a309d36 rs/remote-curl-use-argv-array later to maint). + (merge 3b3c79f6c9 nr/diff-highlight-indent-fix later to maint). + (merge 3444ec2eb2 wb/fsmonitor-bitmap-fix later to maint). + (merge 10da030ab7 cb/pcre2-chartables-leakfix later to maint). From 7d4733c5019c9dab78583cb1a17a9d83370c2b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Thu, 24 Oct 2019 02:20:40 +0200 Subject: [PATCH 16/18] ci: fix GCC install in the Travis CI GCC OSX job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A few days ago Travis CI updated their existing OSX images, including the Homebrew database in the xcode10.1 OSX image that we use. Since then installing dependencies in the 'osx-gcc' job fails when it tries to link gcc@8: + brew link gcc@8 Error: No such keg: /usr/local/Cellar/gcc@8 GCC8 is still installed but not linked to '/usr/local' in the updated image, as it was before this update, but now we have to link it by running 'brew link gcc'. So let's do that then, and fall back to linking gcc@8 if it doesn't, just to be sure. Our builds on Azure Pipelines are unaffected by this issue. The OSX image over there doesn't contain the gcc@8 package, so we have to 'brew install' it, which already takes care of linking it to '/usr/local'. After that the 'brew link gcc' command added by this patch fails, but the ||-chained fallback 'brew link gcc@8' command succeeds with an "already linked" warning. Signed-off-by: SZEDER Gábor Signed-off-by: Junio C Hamano --- ci/install-dependencies.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index 85a9d6b15c..b54ccb4b52 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -43,6 +43,7 @@ osx-clang|osx-gcc) brew install caskroom/cask/perforce case "$jobname" in osx-gcc) + brew link gcc || brew link gcc@8 ;; esac From c11e9966cb7a2e6b1069df43796815d119cf2d7f Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Wed, 23 Oct 2019 20:38:57 +0000 Subject: [PATCH 17/18] repo-settings: read an int for index.version Several config options were combined into a repo_settings struct in ds/feature-macros, including a move of the "index.version" config setting in 7211b9e (repo-settings: consolidate some config settings, 2019-08-13). Unfortunately, that file looked like a lot of boilerplate and what is clearly a factor of copy-paste overload, the config setting is parsed with repo_config_ge_bool() instead of repo_config_get_int(). This means that a setting "index.version=4" would not register correctly and would revert to the default version of 3. I caught this while incorporating v2.24.0-rc0 into the VFS for Git codebase, where we really care that the index is in version 4. This was not caught by the codebase because the version checks placed in t1600-index.sh did not test the "basic" scenario enough. Here, we modify the test to include these normal settings to not be overridden by features.manyFiles or GIT_INDEX_VERSION. While the "default" version is 3, this is demoted to version 2 in do_write_index() when not necessary. Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- repo-settings.c | 2 +- t/t1600-index.sh | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/repo-settings.c b/repo-settings.c index 3779b85c17..3fed31ecf9 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -22,7 +22,7 @@ void prepare_repo_settings(struct repository *r) UPDATE_DEFAULT_BOOL(r->settings.core_commit_graph, 1); UPDATE_DEFAULT_BOOL(r->settings.gc_write_commit_graph, 1); - if (!repo_config_get_bool(r, "index.version", &value)) + if (!repo_config_get_int(r, "index.version", &value)) r->settings.index_version = value; if (!repo_config_get_maybe_bool(r, "core.untrackedcache", &value)) { if (value == 0) diff --git a/t/t1600-index.sh b/t/t1600-index.sh index c77721b580..b7c31aa86a 100755 --- a/t/t1600-index.sh +++ b/t/t1600-index.sh @@ -87,6 +87,10 @@ test_index_version () { } test_expect_success 'index version config precedence' ' + test_index_version 0 false 0 2 && + test_index_version 2 false 0 2 && + test_index_version 3 false 0 2 && + test_index_version 4 false 0 4 && test_index_version 2 false 4 4 && test_index_version 2 true 0 2 && test_index_version 0 true 0 4 && From 566a1439f6f56c2171b8853ddbca0ad3f5098770 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 24 Oct 2019 13:33:49 +0900 Subject: [PATCH 18/18] Git 2.24-rc1 Signed-off-by: Junio C Hamano --- GIT-VERSION-GEN | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 64543ede28..31d6df5b4c 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.24.0-rc0 +DEF_VER=v2.24.0-rc1 LF=' '