summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2018-10-12split-index: smudge and add racily clean cache entries to split indexLibravatar SZEDER Gábor4-8/+46
Ever since the split index feature was introduced [1], refreshing a split index is prone to a variant of the classic racy git problem. Consider the following sequence of commands updating the split index when the shared index contains a racily clean cache entry, i.e. an entry whose cached stat data matches with the corresponding file in the worktree and the cached mtime matches that of the index: echo "cached content" >file git update-index --split-index --add file echo "dirty worktree" >file # size stays the same! # ... wait ... git update-index --add other-file Normally, when a non-split index is updated, then do_write_index() (the function responsible for writing all kinds of indexes, "regular", split, and shared) recognizes racily clean cache entries, and writes them with smudged stat data, i.e. with file size set to 0. When subsequent git commands read the index, they will notice that the smudged stat data doesn't match with the file in the worktree, and then go on to check the file's content and notice its dirtiness. In the above example, however, in the second 'git update-index' prepare_to_write_split_index() decides which cache entries stored only in the shared index should be replaced in the new split index. Alas, this function never looks out for racily clean cache entries, and since the file's stat data in the worktree hasn't changed since the shared index was written, it won't be replaced in the new split index. Consequently, do_write_index() doesn't even get this racily clean cache entry, and can't smudge its stat data. Subsequent git commands will then see that the index has more recent mtime than the file and that the (not smudged) cached stat data still matches with the file in the worktree, and, ultimately, will erroneously consider the file clean. Modify prepare_to_write_split_index() to recognize racily clean cache entries, and mark them to be added to the split index. Note that there are two places where it should check raciness: first those cache entries that are only stored in the shared index, and then those that have been copied by unpack_trees() from the shared index while it constructed a new index. This way do_write_index() will get these racily clean cache entries as well, and will then write them with smudged stat data to the new split index. This change makes all tests in 't1701-racy-split-index.sh' pass, so flip the two 'test_expect_failure' tests to success. Also add the '#' (as in nr. of trial) to those tests' description that were omitted when the tests expected failure. Note that after this change if the index is split when it contains a racily clean cache entry, then a smudged cache entry will be written both to the new shared and to the new split indexes. This doesn't affect regular git commands: as far as they are concerned this is just an entry in the split index replacing an outdated entry in the shared index. It did affect a few tests in 't1700-split-index.sh', though, because they actually check which entries are stored in the split index; a previous patch in this series has already made the necessary adjustments in 't1700'. And racily clean cache entries and index splitting are rare enough to not worry about the resulting duplicated smudged cache entries, and the additional complexity required to prevent them is not worth it. Several tests failed occasionally when the test suite was run with 'GIT_TEST_SPLIT_INDEX=yes'. Here are those that I managed to trace back to this racy split index problem, starting with those failing more frequently, with a link to a failing Travis CI build job for each. The highlighted line [2] shows when the racy file was written, which is not always in the failing test but in a preceeding setup test. t3903-stash.sh: https://travis-ci.org/git/git/jobs/385542084#L5858 t4024-diff-optimize-common.sh: https://travis-ci.org/git/git/jobs/386531969#L3174 t4015-diff-whitespace.sh: https://travis-ci.org/git/git/jobs/360797600#L8215 t2200-add-update.sh: https://travis-ci.org/git/git/jobs/382543426#L3051 t0090-cache-tree.sh: https://travis-ci.org/git/git/jobs/416583010#L3679 There might be others, e.g. perhaps 't1000-read-tree-m-3way.sh' and others using 'lib-read-tree-m-3way.sh', but I couldn't confirm yet. [1] In the branch leading to the merge commit v2.1.0-rc0~45 (Merge branch 'nd/split-index', 2014-07-16). [2] Note that those highlighted lines are in the 'after failure' fold, and your browser might unhelpfully fold it up before you could take a good look. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-12split-index: don't compare cached data of entries already marked for split indexLibravatar SZEDER Gábor1-17/+72
When unpack_trees() constructs a new index, it copies cache entries from the original index [1]. prepare_to_write_split_index() has to deal with this, and it has a dedicated code path for copied entries that are present in the shared index, where it compares the cached data in the corresponding copied and original entries. If the cached data matches, then they are considered the same; if it differs, then the copied entry will be marked for inclusion as a replacement entry in the just about to be written split index by setting the CE_UPDATE_IN_BASE flag. However, a cache entry already has its CE_UPDATE_IN_BASE flag set upon reading the split index, if the entry already has a replacement entry there, or upon refreshing the cached stat data, if the corresponding file was modified. The state of this flag is then preserved when unpack_trees() copies a cache entry from the shared index. So modify prepare_to_write_split_index() to check the copied cache entries' CE_UPDATE_IN_BASE flag first, and skip the thorough comparison of cached data if the flag is already set. Those couple of lines comparing the cached data would then have too many levels of indentation, so extract them into a helper function. Note that comparing the cached data in copied and original entries in the shared index might actually be entirely unnecessary. In theory all code paths refreshing the cached stat data of an entry in the shared index should set the CE_UPDATE_IN_BASE flag in that entry, and unpack_trees() should preserve this flag when copying cache entries. This means that the cached data is only ever changed if the CE_UPDATE_IN_BASE flag is set as well. Our test suite seems to confirm this: instrumenting the conditions in question and running the test suite repeatedly with 'GIT_TEST_SPLIT_INDEX=yes' showed that the cached data in a copied entry differs from the data in the shared entry only if its CE_UPDATE_IN_BASE flag is indeed set. In practice, however, our test suite doesn't have 100% coverage, GIT_TEST_SPLIT_INDEX is inherently random, and I certainly can't claim to possess complete understanding of what goes on in unpack_trees()... Therefore I kept the comparison of the cached data when CE_UPDATE_IN_BASE is not set, just in case that an unnoticed or future code path were to accidentally miss setting this flag upon refreshing the cached stat data or unpack_trees() were to drop this flag while copying a cache entry. [1] Note that when unpack_trees() constructs the new index and decides that a cache entry should now refer to different content than what was recorded in the original index (e.g. 'git read-tree -m HEAD^'), then that can't really be considered a copy of the original, but rather the creation of a new entry. Notably and pertinent to the split index feature, such a new entry doesn't have a reference to the original's shared index entry anymore, i.e. its 'index' field is set to 0. Consequently, such an entry is treated by prepare_to_write_split_index() as an entry not present in the shared index and it will be added to the new split index, while the original entry will be marked as deleted, and neither the above discussion nor the changes in this patch apply to them. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-12split-index: count the number of deleted entriesLibravatar SZEDER Gábor1-1/+1
'struct split_index' contains the field 'nr_deletions', whose name with the 'nr_' prefix suggests that it contains the number of deleted cache entries. However, barring its initialization to 0, this field is only ever set to 1, indicating that there is at least one deleted entry, but not the number of deleted entries. Luckily, this doesn't cause any issues (other than confusing the reader, that is), because the only place reading this field uses it in the same sense, i.e.: 'if (si->nr_deletions)'. To avoid confusion, we could either rename this field to something like 'has_deletions' to make its name match its role, or make it a counter of deleted cache entries to match its name. Let's make it a counter, to keep it in sync with the related field 'nr_replacements', which does contain the number of replaced cache entries. This will also give developers debugging the split index code easy access to the number of deleted cache entries. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-12t1700-split-index: date back files to avoid racy situationsLibravatar SZEDER Gábor1-21/+28
't1700-split-index.sh' checks that the index was split correctly under various circumstances and that all the different ways to turn the split index feature on and off work correctly. To do so, most of its tests use 'test-tool dump-split-index' to see which files have their cache entries in the split index. All these tests assume that all cache entries are written to the shared index (called "base" throughout these tests) when a new shared index is created. This is an implementation detail: most git commands (basically all except 'git update-index') don't care or know at all about split index or whether a cache entry is stored in the split or shared index. As demonstrated in the previous patch, refreshing a split index is prone to a variant of the classic racy git issue. The next patch will fix this issue, but while doing so it will also slightly change this behaviour: only cache entries with mtime in the past will be written only to the newly created shared index, but racily clean cache entries will be written to the new split index (with smudged stat data). While this upcoming change won't at all affect any git commands, it will violate the above mentioned assumption of 't1700's tests. Since these tests create or modify files and create or refresh the split index in rapid succession, there are plenty of racily clean cache entries to be dealt with, which will then be written to the new split indexes, and, ultimately, will cause several tests in 't1700' to fail. Let's prepare 't1700-split-index.sh' for this upcoming change and modify its tests to avoid racily clean files by backdating the mtime of any file modifications (and since a lot of tests create or modify files, encapsulate it into a helper function). Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-12split-index: add tests to demonstrate the racy split index problemLibravatar SZEDER Gábor1-0/+218
Ever since the split index feature was introduced [1], refreshing a split index is prone to a variant of the classic racy git problem. There are a couple of unrelated tests in the test suite that occasionally fail when run with 'GIT_TEST_SPLIT_INDEX=yes', but 't1700-split-index.sh', the only test script focusing solely on split index, has never noticed this issue, because it only cares about how the index is split under various circumstances and all the different ways to turn the split index feature on and off. Add a dedicated test script 't1701-racy-split-index.sh' to exercise the split index feature in racy situations as well; kind of a "t0010-racy-git.sh for split index" but with modern style (the tests do everything in &&-chained list of commands in 'test_expect_...' blocks, and use 'test_cmp' for more informative output on failure). The tests cover the following sequences of index splitting, updating, and racy file modifications, with the last two cases demonstrating the racy split index problem: 1. Split the index while adding a racily clean file: echo "cached content" >file git update-index --split-index --add file echo "dirty worktree" >file # size stays the same This case already works properly. Even though the cache entry's stat data matches with the modifid file in the worktree, subsequent git commands will notice that the (split) index and the file have the same mtime, and then will go on to check the file's content and notice its dirtiness. 2. Add a racily clean file to an already split index: git update-index --split-index echo "cached content" >file git update-index --add file echo "dirty worktree" >file This case already works properly. After the second 'git update-index' writes the newly added file's cache entry to the new split index, it basically works in the same way as case #1. 3. Split the index when it (i.e. the not yet splitted index) contains a racily clean cache entry, i.e. an entry whose cached stat data matches with the corresponding file in the worktree and the cached mtime matches that of the index: echo "cached content" >file git update-index --add file echo "dirty worktree" >file # ... wait ... git update-index --split-index --add other-file This case already works properly. The shared index is written by do_write_index(), i.e. the same function that is responsible for writing "regular" and split indexes as well. This function cleverly notices the racily clean cache entry, and writes the entry to the new shared index with smudged stat data, i.e. file size set to 0. When subsequent git commands read the index, they will notice that the smudged stat data doesn't match with the file in the worktree, and then go on to check the file's content and notice its dirtiness. 4. Update the split index when it contains a racily clean cache entry: git update-index --split-index echo "cached content" >file git update-index --add file echo "dirty worktree" >file # ... wait ... git update-index --add other-file This case already works properly. After the second 'git update-index' the newly added file's cache entry is only stored in the split index. If a cache entry is present in the split index (even if it is a replacement of an outdated entry in the shared index), then it will always be included in the new split index on subsequent split index updates (until the file is removed or a new shared index is written), independently from whether the entry is racily clean or not. When do_write_index() writes the new split index, it notices the racily clean cache entry, and smudges its stat date. Subsequent git commands reading the index will notice the smudged stat data and then go on to check the file's content and notice its dirtiness. 5. Update the split index when a racily clean cache entry is stored only in the shared index: echo "cached content" >file git update-index --split-index --add file echo "dirty worktree" >file # ... wait ... git update-index --add other-file This case fails due to the racy split index problem. In the second 'git update-index' prepare_to_write_split_index() decides, among other things, which cache entries stored only in the shared index should be replaced in the new split index. Alas, this function never looks out for racily clean cache entries, and since the file's stat data in the worktree hasn't changed since the shared index was written, the entry won't be replaced in the new split index. Consequently, do_write_index() doesn't even get this racily clean cache entry, and can't smudge its stat data. Subsequent git commands will then see that the index has more recent mtime than the file and that the (not smudged) cached stat data still matches with the file in the worktree, and, ultimately, will erroneously consider the file clean. 6. Update the split index after unpack_trees() copied a racily clean cache entry from the shared index: echo "cached content" >file git update-index --split-index --add file echo "dirty worktree" >file # ... wait ... git read-tree -m HEAD This case fails due to the racy split index problem. This basically fails for the same reason as case #5 above, but there is one important difference, which warrants the dedicated test. While that second 'git update-index' in case #5 updates index_state in place, in this case 'git read-tree -m' calls unpack_trees(), which throws out the entire index, and constructs a new one from the (potentially updated) copies of the original's cache entries. Consequently, when prepare_to_write_split_index() gets to work on this reconstructed index, it takes a different code path than in case #5 when deciding which cache entries in the shared index should be replaced. The result is the same, though: the racily clean cache entry goes unnoticed, it isn't added to the split index with smudged stat data, and subsequent git commands will then erroneously consider the file clean. Note that in the last two 'test_expect_failure' cases I omitted the '#' (as in nr. of trial) from the tests' description on purpose for now, as it breakes the TAP output [2]; it will be added at the end of the series, when those two tests will be flipped to 'test_expect_success'. [1] In the branch leading to the merge commit v2.1.0-rc0~45 (Merge branch 'nd/split-index', 2014-07-16). [2] In the TAP output a '#' should separate the test's description from the TODO directive emitted by 'test_expect_failure'. The additional '#' in "#$trial" interferes with this, the test harness won't recognize the TODO directive, and will report that those tests failed unexpectedly. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-28t1700-split-index: document why FSMONITOR is disabled in this test scriptLibravatar SZEDER Gábor1-0/+3
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-10Git 2.19Libravatar Junio C Hamano2-9/+1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-10Merge tag 'l10n-2.19.0-rnd2' of git://github.com/git-l10n/git-poLibravatar Junio C Hamano9-25222/+41448
l10n for Git 2.19.0 round 2 * tag 'l10n-2.19.0-rnd2' of git://github.com/git-l10n/git-po: l10n: zh_CN: for git v2.19.0 l10n round 1 to 2 l10n: bg.po: Updated Bulgarian translation (3958t) l10n: vi.po(3958t): updated Vietnamese translation v2.19.0 round 2 l10n: es.po v2.19.0 round 2 l10n: fr.po v2.19.0 rnd 2 l10n: fr.po v2.19.0 rnd 1 l10n: fr: fix a message seen in git bisect l10n: sv.po: Update Swedish translation (3958t0f0u) l10n: git.pot: v2.19.0 round 2 (3 new, 5 removed) l10n: ru.po: update Russian translation l10n: git.pot: v2.19.0 round 1 (382 new, 30 removed) l10n: de.po: translate 108 new messages l10n: zh_CN: review for git 2.18.0 l10n: sv.po: Update Swedish translation(3608t0f0u)
2018-09-10Merge branch 'jn/submodule-core-worktree-revert'Libravatar Junio C Hamano6-55/+2
* jn/submodule-core-worktree-revert: Revert "Merge branch 'sb/submodule-core-worktree'"
2018-09-10Merge branch 'mk/http-backend-content-length'Libravatar Junio C Hamano2-1/+12
The earlier attempt barfed when given a CONTENT_LENGTH that is set to an empty string. RFC 3875 is fairly clear that in this case we should not read any message body, but we've been reading through to the EOF in previous versions (which did not even pay attention to the environment variable), so keep that behaviour for now in this late update. * mk/http-backend-content-length: http-backend: allow empty CONTENT_LENGTH
2018-09-09l10n: zh_CN: for git v2.19.0 l10n round 1 to 2Libravatar Jiang Xin1-2821/+4584
Translate 382 new messages (3958t0f0u) for git 2.19.0. Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2018-09-09Merge branch 'master' of git://github.com/alshopov/git-poLibravatar Jiang Xin1-2750/+4607
* 'master' of git://github.com/alshopov/git-po: l10n: bg.po: Updated Bulgarian translation (3958t)
2018-09-09l10n: bg.po: Updated Bulgarian translation (3958t)Libravatar Alexander Shopov1-2750/+4607
Signed-off-by: Alexander Shopov <ash@kambanaria.org>
2018-09-07Revert "Merge branch 'sb/submodule-core-worktree'"Libravatar Jonathan Nieder6-55/+2
This reverts commit 7e25437d35a70791b345872af202eabfb3e1a8bc, reversing changes made to 00624d608cc69bd62801c93e74d1ea7a7ddd6598. v2.19.0-rc0~165^2~1 (submodule: ensure core.worktree is set after update, 2018-06-18) assumes an "absorbed" submodule layout, where the submodule's Git directory is in the superproject's .git/modules/ directory and .git in the submodule worktree is a .git file pointing there. In particular, it uses $GIT_DIR/modules/$name to find the submodule to find out whether it already has core.worktree set, and it uses connect_work_tree_and_git_dir if not, resulting in fatal: could not open sub/.git for writing The context behind that patch: v2.19.0-rc0~165^2~2 (submodule: unset core.worktree if no working tree is present, 2018-06-12) unsets core.worktree when running commands like "git checkout --recurse-submodules" to switch to a branch without the submodule. If a user then uses "git checkout --no-recurse-submodules" to switch back to a branch with the submodule and runs "git submodule update", this patch is needed to ensure that commands using the submodule directly are aware of the path to the worktree. It is late in the release cycle, so revert the whole 3-patch series. We can try again later for 2.20. Reported-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Helped-by: Stefan Beller <sbeller@google.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-07http-backend: allow empty CONTENT_LENGTHLibravatar Max Kirillov2-1/+12
According to RFC3875, empty environment variable is equivalent to unset, and for CONTENT_LENGTH it should mean zero body to read. However, unset CONTENT_LENGTH is also used for chunked encoding to indicate reading until EOF. At least, the test "large fetch-pack requests can be split across POSTs" from t5551 starts faliing, if unset or empty CONTENT_LENGTH is treated as zero length body. So keep the existing behavior as much as possible. Add a test for the case. Reported-By: Jelmer Vernooij <jelmer@jelmer.uk> Signed-off-by: Max Kirillov <max@max630.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-07l10n: vi.po(3958t): updated Vietnamese translation v2.19.0 round 2Libravatar Tran Ngoc Quan1-2800/+4576
Signed-off-by: Tran Ngoc Quan <vnwildman@gmail.com>
2018-09-06l10n: es.po v2.19.0 round 2Libravatar Christopher Diaz Riveros1-2753/+4571
Signed-off-by: Christopher Diaz Riveros <chrisadr@gentoo.org>
2018-09-06Merge branch 'fr_2.19.0_rnd1' of git://github.com/jnavila/gitLibravatar Jiang Xin1-2786/+4588
* 'fr_2.19.0_rnd1' of git://github.com/jnavila/git: l10n: fr.po v2.19.0 rnd 2 l10n: fr.po v2.19.0 rnd 1 l10n: fr: fix a message seen in git bisect
2018-09-05l10n: fr.po v2.19.0 rnd 2Libravatar Jean-Noël Avila1-283/+328
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
2018-09-05l10n: fr.po v2.19.0 rnd 1Libravatar Jean-Noël Avila1-2718/+4475
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
2018-09-05l10n: fr: fix a message seen in git bisectLibravatar Raphaël Hertzog1-2/+2
"cette" can be only be used before a word (like in "cette bouteille" for "this bottle"), but here "this" refers to the current step and we have to use "ceci" in French. Signed-off-by: Raphaël Hertzog <hertzog@debian.org>
2018-09-04l10n: sv.po: Update Swedish translation (3958t0f0u)Libravatar Peter Krefting1-2800/+4569
Signed-off-by: Peter Krefting <peter@softwolves.pp.se>
2018-09-04Git 2.19-rc2Libravatar Junio C Hamano1-0/+23
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-04Merge branch 'es/chain-lint-more'Libravatar Junio C Hamano5-4/+18
The test linter code has learned that the end of here-doc mark "EOF" can be quoted in a double-quote pair, not just in a single-quote pair. * es/chain-lint-more: chainlint: match "quoted" here-doc tags
2018-09-04Merge branch 'ab/portable-more'Libravatar Junio C Hamano10-44/+53
Portability fix. * ab/portable-more: tests: fix non-portable iconv invocation tests: fix non-portable "${var:-"str"}" construct tests: fix and add lint for non-portable grep --file tests: fix version-specific portability issue in Perl JSON tests: use shorter labels in chainlint.sed for AIX sed tests: fix comment syntax in chainlint.sed for AIX sed tests: fix and add lint for non-portable seq tests: fix and add lint for non-portable head -c N
2018-09-04Merge branch 'es/freebsd-iconv-portability'Libravatar Junio C Hamano1-1/+11
Build fix. * es/freebsd-iconv-portability: config.mak.uname: resolve FreeBSD iconv-related compilation warning
2018-09-04Merge branch 'ds/commit-graph-lockfile-fix'Libravatar Junio C Hamano1-1/+4
"git merge-base" in 2.19-rc1 has performance regression when the (experimental) commit-graph feature is in use, which has been mitigated. * ds/commit-graph-lockfile-fix: commit: don't use generation numbers if not needed
2018-09-04Merge branch 'en/directory-renames-nothanks'Libravatar Junio C Hamano4-6/+124
Recent addition of "directory rename" heuristics to the merge-recursive backend makes the command susceptible to false positives and false negatives. In the context of "git am -3", which does not know about surrounding unmodified paths and thus cannot inform the merge machinery about the full trees involved, this risk is particularly severe. As such, the heuristic is disabled for "git am -3" to keep the machinery "more stupid but predictable". * en/directory-renames-nothanks: am: avoid directory rename detection when calling recursive merge machinery merge-recursive: add ability to turn off directory rename detection t3401: add another directory rename testcase for rebase and am
2018-09-04Merge branch 'pw/rebase-i-author-script-fix'Libravatar Junio C Hamano2-12/+53
Recent "git rebase -i" update started to write bogusly formatted author-script, with a matching broken reading code. These are fixed. * pw/rebase-i-author-script-fix: sequencer: fix quoting in write_author_script sequencer: handle errors from read_author_ident()
2018-09-04l10n: git.pot: v2.19.0 round 2 (3 new, 5 removed)Libravatar Jiang Xin1-255/+247
Generate po/git.pot from v2.19.0-rc1 for git v2.19.0 l10n round 2. Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2018-09-04Merge branch 'master' of git://github.com/git-l10n/git-poLibravatar Jiang Xin5-8458/+13907
* 'master' of git://github.com/git-l10n/git-po: l10n: ru.po: update Russian translation l10n: git.pot: v2.19.0 round 1 (382 new, 30 removed) l10n: de.po: translate 108 new messages l10n: zh_CN: review for git 2.18.0 l10n: sv.po: Update Swedish translation(3608t0f0u)
2018-08-31config.mak.uname: resolve FreeBSD iconv-related compilation warningLibravatar Eric Sunshine1-1/+11
OLD_ICONV has long been needed by FreeBSD so config.mak.uname defines it unconditionally. However, recent versions do not need it, and its presence results in compilation warnings. Resolve this issue by defining OLD_ICONV only for older FreeBSD versions. Specifically, revision r281550[1], which is part of FreeBSD 11, removed the need for OLD_ICONV, and r282275[2] back-ported that change to 10.2. Versions prior to 10.2 do need it. [1] https://github.com/freebsd/freebsd/commit/b0813ee288f64f677a2cebf7815754b027a8215b [2] https://github.com/freebsd/freebsd/commit/b709ec868adb5170d09bc5a66b18d0e0d5987ab6 [es: commit message; tweak version check to distinguish 10.x versions] Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-30commit: don't use generation numbers if not neededLibravatar Derrick Stolee1-1/+4
In 3afc679b "commit: use generations in paint_down_to_common()", the queue in paint_down_to_common() was changed to use a priority order based on generation number before commit date. This served two purposes: 1. When generation numbers are present, the walk guarantees correct topological relationships, regardless of clock skew in commit dates. 2. It enables short-circuiting the walk when the min_generation parameter is added in d7c1ec3e "commit: add short-circuit to paint_down_to_common()". This short-circuit helps commands like 'git branch --contains' from needing to walk to a merge base when we know the result is false. The commit message for 3afc679b includes the following sentence: This change does not affect the number of commits that are walked during the execution of paint_down_to_common(), only the order that those commits are inspected. This statement is incorrect. Because it changes the order in which the commits are inspected, it changes the order they are added to the queue, and hence can change the number of loops before the queue_has_nonstale() method returns true. This change makes a concrete difference depending on the topology of the commit graph. For instance, computing the merge-base between consecutive versions of the Linux kernel has no effect for versions after v4.9, but 'git merge-base v4.8 v4.9' presents a performance regression: v2.18.0: 0.122s v2.19.0-rc1: 0.547s HEAD: 0.127s To determine that this was simply an ordering issue, I inserted a counter within the while loop of paint_down_to_common() and found that the loop runs 167,468 times in v2.18.0 and 635,579 times in v2.19.0-rc1. The topology of this case can be described in a simplified way here: v4.9 | \ | \ v4.8 \ | \ \ | \ | ... A B | / / | / / |/__/ C Here, the "..." means "a very long line of commits". By generation number, A and B have generation one more than C. However, A and B have commit date higher than most of the commits reachable from v4.8. When the walk reaches v4.8, we realize that it has PARENT1 and PARENT2 flags, so everything it can reach is marked as STALE, including A. B has only the PARENT1 flag, so is not STALE. When paint_down_to_common() is run using compare_commits_by_commit_date, A and B are removed from the queue early and C is inserted into the queue. At this point, C and the rest of the queue entries are marked as STALE. The loop then terminates. When paint_down_to_common() is run using compare_commits_by_gen_then_commit_date, B is removed from the queue only after the many commits reachable from v4.8 are explored. This causes the loop to run longer. The reason for this regression is simple: the queue order is intended to not explore a commit until everything that _could_ reach that commit is explored. From the information gathered by the original ordering, we have no guarantee that there is not a commit D reachable from v4.8 that can also reach B. We gained absolute correctness in exchange for a performance regression. The performance regression is probably the worse option, since these incorrect results in paint_down_to_common() are rare. The topology required for the performance regression are less rare, but still require multiple merge commits where the parents differ greatly in generation number. In our example above, the commit A is as important as the commit B to demonstrate the problem, since otherwise the commit C will sit in the queue as non-stale just as long in both orders. The solution provided uses the min_generation parameter to decide if we should use generation numbers in our ordering. When min_generation is equal to zero, it means that the caller has no known cutoff for the walk, so we should rely on our commit-date heuristic as before; this is the case with merge_bases_many(). When min_generation is non-zero, then the caller knows a valuable cutoff for the short-circuit mechanism; this is the case with remove_redundant() and in_merge_bases_many(). Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-30am: avoid directory rename detection when calling recursive merge machineryLibravatar Elijah Newren2-2/+3
Let's say you have the following three trees, where Base is from one commit behind either master or branch: Base : bar_v1, foo/{file1, file2, file3} branch: bar_v2, foo/{file1, file2}, goo/file3 master: bar_v3, foo/{file1, file2, file3} Using git-am (or am-based rebase) to apply the changes from branch onto master results in the following tree: Result: bar_merged, goo/{file1, file2, file3} This is not what users want; they did not rename foo/ -> goo/, they only renamed one file within that directory. The reason this happens is am constructs fake trees (via build_fake_ancestor()) of the following form: Base_bfa : bar_v1, foo/file3 branch_bfa: bar_v2, goo/file3 Combining these two trees with master's tree: master: bar_v3, foo/{file1, file2, file3}, You can see that merge_recursive_generic() would see branch_bfa as renaming foo/ -> goo/, and master as just adding both foo/file1 and foo/file2. As such, it ends up with goo/{file1, file2, file3} The core problem is that am does not have access to the original trees; it can only construct trees using the blobs involved in the patch. As such, it is not safe to perform directory rename detection within am -3. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-30merge-recursive: add ability to turn off directory rename detectionLibravatar Elijah Newren2-5/+14
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-30t3401: add another directory rename testcase for rebase and amLibravatar Elijah Newren1-1/+109
Similar to commit 16346883ab ("t3401: add directory rename testcases for rebase and am", 2018-06-27), add another testcase for directory rename detection. This new testcase differs in that it showcases a situation where no directory rename was performed, but which some backends incorrectly detect. As with the other testcase, run this in conjunction with each of the types of rebases: git-rebase--interactive git-rebase--am git-rebase--merge and also use the same testcase for git am --3way Reported-by: Nikolay Kasyanov <corrmage@gmail.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-29chainlint: match "quoted" here-doc tagsLibravatar Eric Sunshine5-4/+18
A here-doc tag can be quoted ('EOF'/"EOF") or escaped (\EOF) to suppress interpolation within the body. chainlint recognizes single-quoted and escaped tags, but does not know about double-quoted tags. For completeness, teach it to recognize double-quoted tags, as well. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-29tests: fix non-portable iconv invocationLibravatar Ævar Arnfjörð Bjarmason1-1/+5
The iconv that comes with a FreeBSD 11.2-RELEASE-p2 box I have access to doesn't support the SHIFT-JIS encoding. Guard a test added in e92d62253 ("convert: add round trip check based on 'core.checkRoundtripEncoding'", 2018-04-15) first released with Git v2.18.0 with a prerequisite that checks for its availability. The iconv command is in POSIX, and we have numerous tests unconditionally relying on its ability to convert ASCII, UTF-8 and UTF-16, but unconditionally relying on the presence of more obscure encodings isn't portable. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-29tests: fix non-portable "${var:-"str"}" constructLibravatar Ævar Arnfjörð Bjarmason1-1/+1
On both AIX 7200-00-01-1543 and FreeBSD 11.2-RELEASE-p2 the "${var:-"str"}" syntax means something different than what it does under the bash or dash shells. Both will consider the start of the new unescaped quotes to be a new argument to test_expect_success, resulting in the following error: error: bug in the test script: 'git diff-tree initial # magic is (not' does not look like a prereq Fix this by removing the redundant quotes. There's no need for them, and the resulting code works under all the aforementioned shells. This fixes a regression in c2f1d3989 ("t4013: test new output from diff --abbrev --raw", 2017-12-03) first released with Git v2.16.0. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-28Git 2.19-rc1Libravatar Junio C Hamano1-1/+1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-28l10n: ru.po: update Russian translationLibravatar Dimitriy Ryazantcev1-3496/+6652
Signed-off-by: Dimitriy Ryazantcev <dimitriy.ryazantcev@gmail.com>
2018-08-27Getting ready for -rc1Libravatar Junio C Hamano1-1/+34
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-27Merge branch 'ja/i18n-message-fixes'Libravatar Junio C Hamano3-3/+3
Messages fix. * ja/i18n-message-fixes: i18n: fix mistakes in translated strings
2018-08-27Merge branch 'ds/commit-graph-fsck'Libravatar Junio C Hamano1-6/+11
Finishing touches to doc. * ds/commit-graph-fsck: config: fix commit-graph related config docs
2018-08-27Merge branch 'js/range-diff'Libravatar Junio C Hamano1-1/+1
Finishing touched to help string. * js/range-diff: range-diff: update stale summary of --no-dual-color
2018-08-27Merge branch 'sg/test-rebase-editor-fix'Libravatar Junio C Hamano1-3/+3
Test fix. * sg/test-rebase-editor-fix: t/lib-rebase.sh: support explicit 'pick' commands in 'fake_editor.sh'
2018-08-27Merge branch 'jk/hashcmp-optim-for-2.19'Libravatar Junio C Hamano1-0/+10
Partially revert the support for multiple hash functions to regain hash comparison performance; we'd think of a way to do this better in the next cycle. * jk/hashcmp-optim-for-2.19: hashcmp: assert constant hash size
2018-08-27Merge branch 'ab/test-must-be-empty-for-master'Libravatar Junio C Hamano1-1/+1
Test fixes. * ab/test-must-be-empty-for-master: t6018-rev-list-glob: fix 'empty stdin' test
2018-08-27Merge branch 'sg/t3420-autostash-fix'Libravatar Junio C Hamano1-4/+4
Test fixes. * sg/t3420-autostash-fix: t3420-rebase-autostash: don't try to grep non-existing files
2018-08-27Merge branch 'sg/t3903-missing-fix'Libravatar Junio C Hamano1-1/+1
Test fixes. * sg/t3903-missing-fix: t3903-stash: don't try to grep non-existing file