From: Elijah Newren <newren@gmail.com>
To: git@vger.kernel.org
Cc: sbeller@google.com, szeder.dev@gmail.com, j6t@kdbg.org,
jrnieder@gmail.com, peff@peff.net, git@matthieu-moy.fr,
Elijah Newren <newren@gmail.com>
Subject: [PATCHv6 00/31] Add directory rename detection to git
Date: Fri, 5 Jan 2018 12:26:40 -0800 [thread overview]
Message-ID: <20180105202711.24311-1-newren@gmail.com> (raw)
This patchset introduces directory rename detection to merge-recursive. See
https://public-inbox.org/git/20171110190550.27059-1-newren@gmail.com/
for the first series (including design considerations, etc.), and follow-up
series can be found at
https://public-inbox.org/git/20171120220209.15111-1-newren@gmail.com/
https://public-inbox.org/git/20171121080059.32304-1-newren@gmail.com/
https://public-inbox.org/git/20171129014237.32570-1-newren@gmail.com/
https://public-inbox.org/git/20171228041352.27880-1-newren@gmail.com/
Changes since v5 (full tbdiff follows below):
* Split the first three (independent) patches off into a separate series.[1]
Semantically, they are separate and could go in either order, but built
with this one depending on the other series to avoid context region
conflicts.
[1] https://public-inbox.org/git/20180105202001.24218-1-newren@gmail.com/
* Testsuite:
* Replaced plain 'test' with functions that'd provide more
feedback on failure; e.g. test_line_count, test_path_is_missing,
test_path_is_file (Thanks to SZEDER Gábor for the suggestions)
* Backslash escaped '^' character when found in middle of string
being passed to test_i18ngrep (Thanks to Johannes Sixt), and
avoided some shell globbing that somehow tripped up some old
windows build
Elijah Newren (31):
directory rename detection: basic testcases
directory rename detection: directory splitting testcases
directory rename detection: testcases to avoid taking detection too
far
directory rename detection: partially renamed directory
testcase/discussion
directory rename detection: files/directories in the way of some
renames
directory rename detection: testcases checking which side did the
rename
directory rename detection: more involved edge/corner testcases
directory rename detection: testcases exploring possibly suboptimal
merges
directory rename detection: miscellaneous testcases to complete
coverage
directory rename detection: tests for handling overwriting untracked
files
directory rename detection: tests for handling overwriting dirty files
merge-recursive: move the get_renames() function
merge-recursive: introduce new functions to handle rename logic
merge-recursive: fix leaks of allocated renames and diff_filepairs
merge-recursive: make !o->detect_rename codepath more obvious
merge-recursive: split out code for determining diff_filepairs
merge-recursive: add a new hashmap for storing directory renames
merge-recursive: make a helper function for cleanup for handle_renames
merge-recursive: add get_directory_renames()
merge-recursive: check for directory level conflicts
merge-recursive: add a new hashmap for storing file collisions
merge-recursive: add computation of collisions due to dir rename &
merging
merge-recursive: check for file level conflicts then get new name
merge-recursive: when comparing files, don't include trees
merge-recursive: apply necessary modifications for directory renames
merge-recursive: avoid clobbering untracked files with directory
renames
merge-recursive: fix overwriting dirty files involved in renames
merge-recursive: fix remaining directory rename + dirty overwrite
cases
directory rename detection: new testcases showcasing a pair of bugs
merge-recursive: avoid spurious rename/rename conflict from dir
renames
merge-recursive: ensure we write updates for directory-renamed file
merge-recursive.c | 1212 ++++++++++-
merge-recursive.h | 17 +
strbuf.c | 16 +
strbuf.h | 16 +
t/t3501-revert-cherry-pick.sh | 2 +-
t/t6043-merge-rename-directories.sh | 3966 +++++++++++++++++++++++++++++++++++
t/t7607-merge-overwrite.sh | 2 +-
unpack-trees.c | 4 +-
unpack-trees.h | 4 +
9 files changed, 5124 insertions(+), 115 deletions(-)
create mode 100755 t/t6043-merge-rename-directories.sh
1: d95d5fffe < --: ------- Tighten and correct a few testcases for merging and cherry-picking
2: b177dccc2 < --: ------- merge-recursive: fix logic ordering issue
3: fe3de710e < --: ------- merge-recursive: add explanation for src_entry and dst_entry
4: 19b82b795 ! 1: 2fd0812b7 directory rename detection: basic testcases
@@ -88,18 +88,23 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e/f &&
+ git rev-parse >expect \
+ O:z/b O:z/c B:z/d B:z/e/f &&
+ test_cmp expect actual &&
-+ test "$(git hash-object y/d)" = $(git rev-parse B:z/d) &&
++
++ git hash-object y/d >actual &&
++ git rev-parse B:z/d >expect &&
++ test_cmp expect actual &&
++
+ test_must_fail git rev-parse HEAD:z/d &&
+ test_must_fail git rev-parse HEAD:z/e/f &&
-+ test ! -d z/d &&
-+ test ! -d z/e/f
++ test_path_is_missing z/d &&
++ test_path_is_missing z/e/f
+ )
+'
+
@@ -150,7 +155,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e &&
@@ -207,7 +213,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:y/d &&
@@ -216,7 +223,7 @@
+ test_cmp expect actual &&
+ test_must_fail git rev-parse HEAD:x/d &&
+ test_must_fail git rev-parse HEAD:z/d &&
-+ test ! -f z/d
++ test_path_is_missing z/d
+ )
+'
+
@@ -276,9 +283,12 @@
+ test_must_fail git merge -s recursive B^0 >out &&
+ test_i18ngrep "CONFLICT (rename/rename)" out &&
+
-+ test 8 -eq $(git ls-files -s | wc -l) &&
-+ test 2 -eq $(git ls-files -u | wc -l) &&
-+ test 3 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 8 out &&
++ git ls-files -u >out &&
++ test_line_count = 2 out &&
++ git ls-files -o >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ :0:x/b :0:x/c :0:x/d :0:x/e :0:x/m :0:x/n &&
@@ -293,9 +303,9 @@
+ A:y/wham B:z/wham &&
+ test_cmp expect actual &&
+
-+ test ! -f x/wham &&
-+ test -f x/wham~HEAD &&
-+ test -f x/wham~B^0 &&
++ test_path_is_missing x/wham &&
++ test_path_is_file x/wham~HEAD &&
++ test_path_is_file x/wham~B^0 &&
+
+ git hash-object >actual \
+ x/wham~HEAD x/wham~B^0 &&
@@ -350,7 +360,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ HEAD:y/newb HEAD:y/newc HEAD:y/d &&
@@ -415,14 +426,15 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 6 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 6 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:x/d HEAD:x/e HEAD:x/f HEAD:x/g &&
+ git rev-parse >expect \
+ O:z/b O:z/c O:z/d O:z/e O:z/f A:z/g &&
+ test_cmp expect actual &&
-+ test ! -f z/g &&
++ test_path_is_missing z/g &&
+ test_must_fail git rev-parse HEAD:z/g
+ )
+'
5: 831640a89 ! 2: 5c697afd4 directory rename detection: directory splitting testcases
@@ -67,17 +67,20 @@
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out &&
++ test_i18ngrep "CONFLICT.*directory rename split" out &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:w/c :0:z/d &&
+ git rev-parse >expect \
+ O:z/b O:z/c B:z/d &&
-+ test_cmp expect actual &&
-+ test_i18ngrep "CONFLICT.*directory rename split" out
++ test_cmp expect actual
+ )
+'
+
@@ -127,9 +130,12 @@
+
+ git merge -s recursive B^0 >out &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:w/c :0:x/d &&
6: bff72c92b ! 3: 2b9346df1 directory rename detection: testcases to avoid taking detection too far
@@ -68,7 +68,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:x/d &&
@@ -131,10 +132,15 @@
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out &&
++ test_i18ngrep CONFLICT.*rename/rename.*z/d.*x/d.*w/d out &&
++ test_i18ngrep ! CONFLICT.*rename/rename.*y/d &&
+
-+ test 5 -eq $(git ls-files -s | wc -l) &&
-+ test 3 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 5 out &&
++ git ls-files -u >out &&
++ test_line_count = 3 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:y/c :1:z/d :2:x/d :3:w/d &&
@@ -142,15 +148,12 @@
+ O:z/b O:z/c O:z/d O:z/d O:z/d &&
+ test_cmp expect actual &&
+
-+ test ! -f z/d &&
++ test_path_is_missing z/d &&
+ git hash-object >actual \
+ x/d w/d &&
+ git rev-parse >expect \
+ O:z/d O:z/d &&
-+ test_cmp expect actual &&
-+
-+ test_i18ngrep CONFLICT.*rename/rename.*z/d.*x/d.*w/d out &&
-+ test_i18ngrep ! CONFLICT.*rename/rename.*y/d
++ test_cmp expect actual
+ )
+'
+
7: 7ee62a9da ! 4: 791201822 directory rename detection: partially renamed directory testcase/discussion
@@ -93,9 +93,12 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 5 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 0 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 5 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:y/d HEAD:z/e HEAD:z/f &&
8: d5d028780 ! 5: 6fc6028a7 directory rename detection: files/directories in the way of some renames
@@ -74,20 +74,20 @@
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out &&
-+
-+ test 6 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
-+
-+ git rev-parse >actual \
-+ :0:y/b :0:y/c :0:y/d :0:y/e :0:z/e &&
-+ git rev-parse >expect \
-+ O:z/b O:z/c O:y/d A:y/e A:z/e &&
-+ test_cmp expect actual &&
-+
-+ test $(git rev-parse :0:y/f) = $(git rev-parse A:z/f) &&
-+
-+ test_i18ngrep "CONFLICT.*implicit dir rename" out
++ test_i18ngrep "CONFLICT.*implicit dir rename" out &&
++
++ git ls-files -s >out &&
++ test_line_count = 6 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
++
++ git rev-parse >actual \
++ :0:y/b :0:y/c :0:y/d :0:y/e :0:z/e :0:y/f &&
++ git rev-parse >expect \
++ O:z/b O:z/c O:y/d A:y/e A:z/e A:z/f &&
++ test_cmp expect actual
+ )
+'
+
@@ -150,9 +150,12 @@
+ test_must_fail git merge -s recursive B^0 >out &&
+ test_i18ngrep "CONFLICT (add/add).* y/d" out &&
+
-+ test 5 -eq $(git ls-files -s | wc -l) &&
-+ test 2 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 5 out &&
++ git ls-files -u >out &&
++ test_line_count = 2 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:y/c :0:y/e :2:y/d :3:y/d &&
@@ -161,7 +164,7 @@
+ test_cmp expect actual &&
+
+ test_must_fail git rev-parse :1:y/d &&
-+ test -f y/d
++ test_path_is_file y/d
+ )
+'
+
@@ -228,9 +231,12 @@
+ test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*z/d" out &&
+ test_i18ngrep "CONFLICT (add/add).* y/d" out &&
+
-+ test 9 -eq $(git ls-files -s | wc -l) &&
-+ test 6 -eq $(git ls-files -u | wc -l) &&
-+ test 3 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 9 out &&
++ git ls-files -u >out &&
++ test_line_count = 6 out &&
++ git ls-files -o >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:y/c :0:y/e &&
@@ -246,14 +252,13 @@
+ test_cmp expect actual &&
+
+ git hash-object >actual \
-+ w/d~HEAD w/d~B^0 &&
-+ git rev-parse >expect \
-+ O:x/d B:w/d &&
-+ test_cmp expect actual &&
-+ test ! -f x/d &&
-+ test -f y/d &&
-+ grep -q "<<<<" y/d && # conflict markers should be present
-+ test $(git hash-object z/d) = $(git rev-parse O:x/d)
++ w/d~HEAD w/d~B^0 z/d &&
++ git rev-parse >expect \
++ O:x/d B:w/d O:x/d &&
++ test_cmp expect actual &&
++ test_path_is_missing x/d &&
++ test_path_is_file y/d &&
++ grep -q "<<<<" y/d # conflict markers should be present
+ )
+'
+
@@ -309,9 +314,12 @@
+ test_must_fail git merge -s recursive B^0 >out &&
+ test_i18ngrep "CONFLICT (file/directory).*y/d" out &&
+
-+ test 6 -eq $(git ls-files -s | wc -l) &&
-+ test 1 -eq $(git ls-files -u | wc -l) &&
-+ test 2 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 6 out &&
++ git ls-files -u >out &&
++ test_line_count = 1 out &&
++ git ls-files -o >out &&
++ test_line_count = 2 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:y/c :0:z/d :0:y/f :2:y/d :0:y/d/e &&
@@ -319,7 +327,9 @@
+ O:z/b O:z/c B:z/d B:z/f A:y/d B:y/d/e &&
+ test_cmp expect actual &&
+
-+ test $(git hash-object y/d~HEAD) = $(git rev-parse A:y/d)
++ git hash-object y/d~HEAD >actual &&
++ git rev-parse A:y/d >expect &&
++ test_cmp expect actual
+ )
+'
+
9: 5b0f4fbdb ! 6: 317d54cfc directory rename detection: testcases checking which side did the rename
@@ -74,9 +74,12 @@
+ test_must_fail git merge -s recursive B^0 >out &&
+ test_i18ngrep "CONFLICT (rename/delete).*z/c.*y/c" out &&
+
-+ test 2 -eq $(git ls-files -s | wc -l) &&
-+ test 1 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 2 out &&
++ git ls-files -u >out &&
++ test_line_count = 1 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ :0:y/b :3:y/c &&
@@ -135,9 +138,12 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 0 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:z/d &&
@@ -194,9 +200,12 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 0 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:z/d &&
@@ -253,9 +262,12 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 0 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:z/d &&
@@ -313,9 +325,12 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 0 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:y/d HEAD:z/d &&
10: 1c539cfb6 ! 7: afb942c5d directory rename detection: more involved edge/corner testcases
@@ -87,16 +87,17 @@
+ test_i18ngrep "CONFLICT (rename/rename).*z/b.*y/b.*w/b" out &&
+ test_i18ngrep "CONFLICT (rename/rename).*z/c.*y/c.*x/c" out &&
+
-+ test 7 -eq $(git ls-files -s | wc -l) &&
-+ test 6 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
-+
-+ test $(git rev-parse :0:y/d) = $(git rev-parse B:z/d) &&
++ git ls-files -s >out &&
++ test_line_count = 7 out &&
++ git ls-files -u >out &&
++ test_line_count = 6 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
-+ :1:z/b :2:y/b :3:w/b :1:z/c :2:y/c :3:x/c &&
-+ git rev-parse >expect \
-+ O:z/b O:z/b O:z/b O:z/c O:z/c O:z/c &&
++ :1:z/b :2:y/b :3:w/b :1:z/c :2:y/c :3:x/c :0:y/d &&
++ git rev-parse >expect \
++ O:z/b O:z/b O:z/b O:z/c O:z/c O:z/c B:z/d &&
+ test_cmp expect actual &&
+
+ git hash-object >actual \
@@ -157,9 +158,12 @@
+ test_must_fail git merge -s recursive B^0 >out &&
+ test_i18ngrep "CONFLICT (rename/rename)" out &&
+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
-+ test 2 -eq $(git ls-files -u | wc -l) &&
-+ test 3 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
++ git ls-files -u >out &&
++ test_line_count = 2 out &&
++ git ls-files -o >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:y/c :2:y/d :3:y/d &&
@@ -167,9 +171,9 @@
+ O:z/b O:z/c O:w/d O:x/d &&
+ test_cmp expect actual &&
+
-+ test ! -f y/d &&
-+ test -f y/d~HEAD &&
-+ test -f y/d~B^0 &&
++ test_path_is_missing y/d &&
++ test_path_is_file y/d~HEAD &&
++ test_path_is_file y/d~B^0 &&
+
+ git hash-object >actual \
+ y/d~HEAD y/d~B^0 &&
@@ -230,9 +234,12 @@
+ test_must_fail git merge -s recursive B^0 >out &&
+ test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*y/d" out &&
+
-+ test 5 -eq $(git ls-files -s | wc -l) &&
-+ test 3 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 5 out &&
++ git ls-files -u >out &&
++ test_line_count = 3 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:y/c :1:x/d :2:w/d :3:y/d &&
@@ -291,9 +298,12 @@
+ test_must_fail git merge -s recursive B^0 >out &&
+ test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 1 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 1 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:y/c :3:y/d &&
@@ -378,9 +388,12 @@
+ test_must_fail git merge -s recursive B^0 >out &&
+ test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
+
-+ test 5 -eq $(git ls-files -s | wc -l) &&
-+ test 1 -eq $(git ls-files -u | wc -l) &&
-+ test 2 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 5 out &&
++ git ls-files -u >out &&
++ test_line_count = 1 out &&
++ git ls-files -o >out &&
++ test_line_count = 2 out &&
+
+ git rev-parse >actual \
+ :0:x/d/f :0:y/d/g :0:y/b :0:y/c :3:y/d &&
@@ -388,7 +401,9 @@
+ A:x/d/f A:y/d/g O:z/b O:z/c O:x/d &&
+ test_cmp expect actual &&
+
-+ test $(git hash-object y/d~B^0) = $(git rev-parse O:x/d)
++ git hash-object y/d~B^0 >actual &&
++ git rev-parse O:x/d >expect &&
++ test_cmp expect actual
+ )
+'
+
11: 4238c6484 ! 8: 157559cea directory rename detection: testcases exploring possibly suboptimal merges
@@ -82,9 +82,12 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 6 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 0 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 6 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:y/a HEAD:y/b HEAD:y/e HEAD:y/f HEAD:z/c HEAD:z/d &&
@@ -157,9 +160,12 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 6 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 0 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 6 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:y/a HEAD:y/b HEAD:z/a HEAD:z/b HEAD:x/e HEAD:y/e &&
@@ -222,9 +228,12 @@
+ test_must_fail git merge -s recursive B^0 >out &&
+ test_i18ngrep "CONFLICT (rename/delete).* z/d.*y/d" out &&
+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
-+ test 1 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
++ git ls-files -u >out &&
++ test_line_count = 1 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ :0:y/b :0:y/c :0:y/e :3:y/d &&
@@ -235,7 +244,7 @@
+ test_must_fail git rev-parse :1:y/d &&
+ test_must_fail git rev-parse :2:y/d &&
+ git ls-files -s y/d | grep ^100755 &&
-+ test -f y/d
++ test_path_is_file y/d
+ )
+'
+
@@ -305,7 +314,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:y/e &&
@@ -378,17 +388,20 @@
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
-+
-+ test 7 -eq $(git ls-files -s | wc -l) &&
-+ test 6 -eq $(git ls-files -u | wc -l) &&
-+ test 2 -eq $(git ls-files -o | wc -l) &&
-+
-+ test $(git rev-parse :0:y/d) = $(git rev-parse B:z/d) &&
++ test_i18ngrep CONFLICT.*rename/rename.*z/c.*y/c.*w/c out &&
++ test_i18ngrep CONFLICT.*rename/rename.*z/b.*y/b.*w/b out &&
++
++ git ls-files -s >out &&
++ test_line_count = 7 out &&
++ git ls-files -u >out &&
++ test_line_count = 6 out &&
++ git ls-files -o >out &&
++ test_line_count = 2 out &&
+
+ git rev-parse >actual \
-+ :1:z/b :2:y/b :3:w/b :1:z/c :2:y/c :3:w/c &&
-+ git rev-parse >expect \
-+ O:z/b O:z/b O:z/b O:z/c O:z/c O:z/c &&
++ :1:z/b :2:y/b :3:w/b :1:z/c :2:y/c :3:w/c :0:y/d &&
++ git rev-parse >expect \
++ O:z/b O:z/b O:z/b O:z/c O:z/c O:z/c B:z/d &&
+ test_cmp expect actual &&
+
+ git hash-object >actual \
@@ -397,11 +410,8 @@
+ O:z/b O:z/b O:z/c O:z/c &&
+ test_cmp expect actual &&
+
-+ test ! -f z/b &&
-+ test ! -f z/c &&
-+
-+ test_i18ngrep CONFLICT.*rename/rename.*z/c.*y/c.*w/c out &&
-+ test_i18ngrep CONFLICT.*rename/rename.*z/b.*y/b.*w/b out
++ test_path_is_missing z/b &&
++ test_path_is_missing z/c
+ )
+'
+
12: 48a546a06 ! 9: e9f563a34 directory rename detection: miscellaneous testcases to complete coverage
@@ -95,9 +95,12 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 7 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 0 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 7 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:y/i &&
@@ -162,9 +165,11 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
+
+ test_seq 0 11 >expected &&
++ test_cmp expected y/d &&
+ git add expected &&
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:y/d &&
@@ -173,12 +178,11 @@
+ test_cmp expect actual &&
+ test_must_fail git rev-parse HEAD:x/d &&
+ test_must_fail git rev-parse HEAD:z/d &&
-+ test ! -f z/d &&
++ test_path_is_missing z/d &&
+
+ test $(git rev-parse HEAD:y/d) != $(git rev-parse O:x/d) &&
+ test $(git rev-parse HEAD:y/d) != $(git rev-parse A:x/d) &&
-+ test $(git rev-parse HEAD:y/d) != $(git rev-parse B:z/d) &&
-+ test_cmp expected y/d
++ test $(git rev-parse HEAD:y/d) != $(git rev-parse B:z/d)
+ )
+'
+
@@ -252,8 +256,10 @@
+ git merge -s recursive B^0 >out &&
+ test_i18ngrep "WARNING: Avoiding applying x -> z rename to x/f" out &&
+
-+ test 6 -eq $(git ls-files -s | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 6 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e HEAD:x/f HEAD:x/g &&
@@ -341,8 +347,10 @@
+ test_i18ngrep "WARNING: Avoiding applying x -> w rename to x/b" out &&
+ test_i18ngrep "WARNING: Avoiding applying w -> v rename to w/c" out &&
+
-+ test 7 -eq $(git ls-files -s | wc -l) &&
-+ test 1 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 7 out &&
++ git ls-files -o >out &&
++ test_line_count = 1 out &&
+
+ git rev-parse >actual \
+ HEAD:z/t HEAD:y/a HEAD:x/b HEAD:w/c HEAD:u/d HEAD:u/e HEAD:u/f &&
@@ -418,9 +426,12 @@
+ grep -q dir3/yo error_line &&
+ grep -q dirN/yo error_line &&
+
-+ test 16 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 2 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 16 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 2 out &&
+
+ git rev-parse >actual \
+ :0:combined/a :0:combined/b :0:combined/c \
@@ -488,7 +499,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
+
+ git rev-parse >actual \
+ HEAD:priority/a/foo HEAD:priority/b/bar HEAD:priority/b/baz HEAD:priority/c &&
@@ -548,7 +560,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
+
+ git rev-parse >actual \
+ HEAD:priority/alpha/foo HEAD:priority/beta/bar HEAD:priority/beta/baz HEAD:priority/c &&
13: bc8a45699 ! 10: 0c6630551 directory rename detection: tests for handling overwriting untracked files
@@ -68,12 +68,20 @@
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_i18ngrep "The following untracked working tree files would be overwritten by merge" err &&
+
-+ test 1 -eq $(git ls-files -s | wc -l) &&
-+ test 4 -eq $(git ls-files -o | wc -l) &&
-+
-+ test "very" = "$(cat z/c)" &&
-+ test "important" = "$(cat z/d)" &&
-+ test $(git rev-parse HEAD:z/b) = $(git rev-parse O:z/b)
++ git ls-files -s >out &&
++ test_line_count = 1 out &&
++ git ls-files -o >out &&
++ test_line_count = 4 out &&
++
++ echo very >expect &&
++ test_cmp expect z/c &&
++
++ echo important >expect &&
++ test_cmp expect z/d &&
++
++ git rev-parse HEAD:z/b >actual &&
++ git rev-parse O:z/b >expect &&
++ test_cmp expect actual
+ )
+'
+
@@ -126,23 +134,30 @@
+ echo contents >y/e &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
-+ test_i18ngrep "CONFLICT (rename/delete).*Version B^0 of y/d left in tree at y/d~B^0" out &&
-+ test_i18ngrep "Error: Refusing to lose untracked file at y/e; writing to y/e~B^0 instead" out &&
-+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 2 -eq $(git ls-files -u | wc -l) &&
-+ test 5 -eq $(git ls-files -o | wc -l) &&
-+
-+ test $(git rev-parse :0:y/b) = $(git rev-parse O:z/b) &&
-+ test "very" = "$(cat y/c)" &&
-+
-+ test "important" = "$(cat y/d)" &&
-+ test "important" != "$(git rev-parse :3:y/d)" &&
-+ test $(git rev-parse :3:y/d) = $(git rev-parse O:z/c) &&
-+
-+ test "contents" = "$(cat y/e)" &&
-+ test "contents" != "$(git rev-parse :3:y/e)" &&
-+ test $(git rev-parse :3:y/e) = $(git rev-parse B:z/e)
++ test_i18ngrep "CONFLICT (rename/delete).*Version B\^0 of y/d left in tree at y/d~B\^0" out &&
++ test_i18ngrep "Error: Refusing to lose untracked file at y/e; writing to y/e~B\^0 instead" out &&
++
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 2 out &&
++ git ls-files -o >out &&
++ test_line_count = 5 out &&
++
++ git rev-parse >actual \
++ :0:y/b :3:y/d :3:y/e &&
++ git rev-parse >expect \
++ O:z/b O:z/c B:z/e &&
++ test_cmp expect actual &&
++
++ echo very >expect &&
++ test_cmp expect y/c &&
++
++ echo important >expect &&
++ test_cmp expect y/d &&
++
++ echo contents >expect &&
++ test_cmp expect y/e
+ )
+'
+
@@ -196,11 +211,14 @@
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_i18ngrep "CONFLICT (rename/rename)" out &&
-+ test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~B^0 instead" out &&
-+
-+ test 6 -eq $(git ls-files -s | wc -l) &&
-+ test 3 -eq $(git ls-files -u | wc -l) &&
-+ test 3 -eq $(git ls-files -o | wc -l) &&
++ test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~B\^0 instead" out &&
++
++ git ls-files -s >out &&
++ test_line_count = 6 out &&
++ git ls-files -u >out &&
++ test_line_count = 3 out &&
++ git ls-files -o >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ :0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :3:y/c &&
@@ -208,9 +226,12 @@
+ O:z/a O:z/b O:x/d O:x/c O:x/c O:x/c &&
+ test_cmp expect actual &&
+
-+ test "important" = "$(cat y/c)" &&
-+ test "important" != "$(git rev-parse :3:y/c)" &&
-+ test $(git hash-object y/c~B^0) = $(git rev-parse O:x/c)
++ git hash-object y/c~B^0 >actual &&
++ git rev-parse O:x/c >expect &&
++ test_cmp expect actual &&
++
++ echo important >expect &&
++ test_cmp expect y/c
+ )
+'
+
@@ -267,9 +288,12 @@
+ test_i18ngrep "CONFLICT (rename/rename)" out &&
+ test_i18ngrep "Refusing to lose untracked file at y/wham" out &&
+
-+ test 6 -eq $(git ls-files -s | wc -l) &&
-+ test 2 -eq $(git ls-files -u | wc -l) &&
-+ test 4 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 6 out &&
++ git ls-files -u >out &&
++ test_line_count = 2 out &&
++ git ls-files -o >out &&
++ test_line_count = 4 out &&
+
+ git rev-parse >actual \
+ :0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&
@@ -279,7 +303,9 @@
+
+ test_must_fail git rev-parse :1:y/wham &&
+
-+ test "important" = "$(cat y/wham)" &&
++ echo important >expect &&
++ test_cmp expect y/wham &&
++
+ git hash-object >actual \
+ y/wham~B^0 y/wham~HEAD &&
+ git rev-parse >expect \
@@ -334,9 +360,12 @@
+ git merge -s recursive B^0 >out 2>err &&
+ test_i18ngrep ! "following untracked working tree files would be overwritten by merge" err &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 3 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ :0:y/a :0:y/b :0:y/c &&
@@ -344,7 +373,8 @@
+ O:z/a O:z/b B:z/c &&
+ test_cmp expect actual &&
+
-+ test "random" = "$(cat z/c)"
++ echo random >expect &&
++ test_cmp expect z/c
+ )
+'
+
14: a94077d10 ! 11: 16cd375e1 directory rename detection: tests for handling overwriting dirty files
@@ -75,10 +75,14 @@
+
+ test_seq 1 10 >expected &&
+ echo stuff >>expected &&
-+
-+ test 2 -eq $(git ls-files -s | wc -l) &&
-+ test 1 -eq $(git ls-files -u | wc -l) &&
-+ test 4 -eq $(git ls-files -o | wc -l) &&
++ test_cmp expected z/c &&
++
++ git ls-files -s >out &&
++ test_line_count = 2 out &&
++ git ls-files -u >out &&
++ test_line_count = 1 out &&
++ git ls-files -o >out &&
++ test_line_count = 4 out &&
+
+ git rev-parse >actual \
+ :0:z/a :2:z/c &&
@@ -86,8 +90,9 @@
+ O:z/a B:z/b &&
+ test_cmp expect actual &&
+
-+ test "$(git hash-object z/c~HEAD)" = $(git rev-parse B:z/b) &&
-+ test_cmp expected z/c
++ git hash-object z/c~HEAD >actual &&
++ git rev-parse B:z/b >expect &&
++ test_cmp expect actual
+ )
+'
+
@@ -140,14 +145,19 @@
+ git merge -s recursive B^0 >out 2>err &&
+ test_i18ngrep "Refusing to lose dirty file at z/c" out &&
+
-+ grep -q stuff */* &&
++ grep -q stuff z/c &&
+ test_seq 1 10 >expected &&
+ echo stuff >>expected &&
-+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 0 -eq $(git ls-files -m | wc -l) &&
-+ test 4 -eq $(git ls-files -o | wc -l) &&
++ test_cmp expected z/c &&
++
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -m >out &&
++ test_line_count = 0 out &&
++ git ls-files -o >out &&
++ test_line_count = 4 out &&
+
+ git rev-parse >actual \
+ :0:x/b :0:y/a :0:y/c &&
@@ -155,8 +165,9 @@
+ O:x/b O:z/a B:x/c &&
+ test_cmp expect actual &&
+
-+ test "$(git hash-object y/c)" = $(git rev-parse B:x/c) &&
-+ test_cmp expected z/c
++ git hash-object y/c >actual &&
++ git rev-parse B:x/c >expect &&
++ test_cmp expect actual
+ )
+'
+
@@ -209,17 +220,19 @@
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_i18ngrep "following files would be overwritten by merge" err &&
+
-+ grep -q stuff */* &&
++ grep -q stuff y/c &&
+ test_seq 1 10 >expected &&
+ echo stuff >>expected &&
-+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
-+ test 0 -eq $(git ls-files -u | wc -l) &&
-+ test 1 -eq $(git ls-files -m | wc -l) &&
-+ test 3 -eq $(git ls-files -o | wc -l) &&
-+
-+ test $(git rev-parse HEAD) = $(git rev-parse A) &&
-+ test_cmp expected y/c
++ test_cmp expected y/c &&
++
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
++ git ls-files -u >out &&
++ test_line_count = 0 out &&
++ git ls-files -m >out &&
++ test_line_count = 1 out &&
++ git ls-files -o >out &&
++ test_line_count = 3 out
+ )
+'
+
@@ -274,13 +287,17 @@
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_i18ngrep "Refusing to lose dirty file at z/c" out &&
+
-+ grep -q stuff */* &&
++ grep -q stuff z/c &&
+ test_seq 1 10 >expected &&
+ echo stuff >>expected &&
-+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
-+ test 1 -eq $(git ls-files -u | wc -l) &&
-+ test 5 -eq $(git ls-files -o | wc -l) &&
++ test_cmp expected z/c
++
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
++ git ls-files -u >out &&
++ test_line_count = 1 out &&
++ git ls-files -o >out &&
++ test_line_count = 5 out &&
+
+ git rev-parse >actual \
+ :0:x/b :0:y/a :0:y/c/d :3:y/c &&
@@ -288,8 +305,9 @@
+ O:x/b O:z/a B:y/c/d B:x/c &&
+ test_cmp expect actual &&
+
-+ test "$(git hash-object y/c~HEAD)" = $(git rev-parse B:x/c) &&
-+ test_cmp expected z/c
++ git hash-object y/c~HEAD >actual &&
++ git rev-parse B:x/c >expect &&
++ test_cmp expect actual
+ )
+'
+
@@ -349,12 +367,16 @@
+ test_i18ngrep "CONFLICT (rename/rename)" out &&
+ test_i18ngrep "Refusing to lose dirty file at y/c" out &&
+
-+ test 7 -eq $(git ls-files -s | wc -l) &&
-+ test 4 -eq $(git ls-files -u | wc -l) &&
-+ test 4 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 7 out &&
++ git ls-files -u >out &&
++ test_line_count = 4 out &&
++ git ls-files -o >out &&
++ test_line_count = 4 out &&
+
+ echo different >expected &&
+ echo mods >>expected &&
++ test_cmp expected y/c &&
+
+ git rev-parse >actual \
+ :0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :2:y/c :3:y/c &&
@@ -366,9 +388,7 @@
+ y/c~B^0 y/c~HEAD &&
+ git rev-parse >expect \
+ O:x/c A:y/c &&
-+ test_cmp expect actual &&
-+
-+ test_cmp expected y/c
++ test_cmp expect actual
+ )
+'
+
@@ -423,26 +443,28 @@
+ test_i18ngrep "CONFLICT (rename/rename)" out &&
+ test_i18ngrep "Refusing to lose dirty file at y/wham" out &&
+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
-+ test 2 -eq $(git ls-files -u | wc -l) &&
-+ test 4 -eq $(git ls-files -o | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
++ git ls-files -u >out &&
++ test_line_count = 2 out &&
++ git ls-files -o >out &&
++ test_line_count = 4 out &&
+
+ test_seq 1 10 >expected &&
+ echo important >>expected &&
++ test_cmp expected y/wham &&
++
++ test_must_fail git rev-parse :1:y/wham &&
++ git hash-object >actual \
++ y/wham~B^0 y/wham~HEAD &&
++ git rev-parse >expect \
++ O:x/d O:x/c &&
++ test_cmp expect actual &&
+
+ git rev-parse >actual \
+ :0:y/a :0:y/b :2:y/wham :3:y/wham &&
+ git rev-parse >expect \
+ O:z/a O:z/b O:x/c O:x/d &&
-+ test_cmp expect actual &&
-+
-+ test_must_fail git rev-parse :1:y/wham &&
-+
-+ test_cmp expected y/wham &&
-+ git hash-object >actual \
-+ y/wham~B^0 y/wham~HEAD &&
-+ git rev-parse >expect \
-+ O:x/d O:x/c &&
+ test_cmp expect actual
+ )
+'
15: 30aafc85e = 12: b7f4530bc merge-recursive: move the get_renames() function
16: 6b29a765f = 13: 45c39bb87 merge-recursive: introduce new functions to handle rename logic
17: 53c57eff7 = 14: 21b30fe2d merge-recursive: fix leaks of allocated renames and diff_filepairs
18: 5385b6762 = 15: bad89d217 merge-recursive: make !o->detect_rename codepath more obvious
19: 1f913d37d = 16: 67eec195a merge-recursive: split out code for determining diff_filepairs
20: b59f7fbe4 = 17: 288e3987a merge-recursive: add a new hashmap for storing directory renames
21: f7e14522c = 18: c2d58b3a2 merge-recursive: make a helper function for cleanup for handle_renames
22: 35393dfe0 = 19: 1dcf48227 merge-recursive: add get_directory_renames()
23: 5dcb73fe9 = 20: 968effeaf merge-recursive: check for directory level conflicts
24: f61aaf7b5 = 21: 865b98f6b merge-recursive: add a new hashmap for storing file collisions
25: 8fc5e978b = 22: f74e41c56 merge-recursive: add computation of collisions due to dir rename & merging
26: cc0ebb2e0 = 23: 6678bf2ca merge-recursive: check for file level conflicts then get new name
27: 505eeda52 = 24: 8dd2a045c merge-recursive: when comparing files, don't include trees
28: c884f8427 = 25: 30341f655 merge-recursive: apply necessary modifications for directory renames
29: dc11ea741 = 26: 498cb775f merge-recursive: avoid clobbering untracked files with directory renames
30: 0b5d46643 = 27: 81d5073ab merge-recursive: fix overwriting dirty files involved in renames
31: f20983a6a = 28: 3a2e99fe7 merge-recursive: fix remaining directory rename + dirty overwrite cases
32: 12aa1972a ! 29: e93a1b89e directory rename detection: new testcases showcasing a pair of bugs
@@ -80,7 +80,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 3 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ HEAD:y/b HEAD:y/c HEAD:x/d &&
@@ -151,7 +152,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 6 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 6 out &&
+
+ git rev-parse >actual \
+ HEAD:node1/leaf1 HEAD:node1/leaf2 HEAD:node1/leaf5 HEAD:node1/node2/leaf3 HEAD:node1/node2/leaf4 HEAD:node1/node2/leaf6 &&
@@ -220,7 +222,8 @@
+
+ git merge -s recursive B^0 &&
+
-+ test 4 -eq $(git ls-files -s | wc -l) &&
++ git ls-files -s >out &&
++ test_line_count = 4 out &&
+
+ git rev-parse >actual \
+ HEAD:node1/node2/node1/leaf1 \
@@ -287,7 +290,8 @@
+
+ test_must_fail git merge -s recursive B^0 &&
+
-+ test 12 -eq $(git ls-files -u | wc -l) &&
++ git ls-files -u >out &&
++ test_line_count = 12 out &&
+
+ git rev-parse >actual \
+ :1:node1/node2/node1/leaf1 \
33: 5530b0af9 ! 30: d77d0d85b merge-recursive: avoid spurious rename/rename conflict from dir renames
@@ -85,11 +85,14 @@
- test_i18ngrep "CONFLICT (rename/delete).* z/d.*y/d" out &&
+ test_i18ngrep "CONFLICT (modify/delete).* z/d" out &&
-- test 4 -eq $(git ls-files -s | wc -l) &&
-- test 1 -eq $(git ls-files -u | wc -l) &&
-+ test 5 -eq $(git ls-files -s | wc -l) &&
-+ test 2 -eq $(git ls-files -u | wc -l) &&
- test 1 -eq $(git ls-files -o | wc -l) &&
+ git ls-files -s >out &&
+- test_line_count = 4 out &&
++ test_line_count = 5 out &&
+ git ls-files -u >out &&
+- test_line_count = 1 out &&
++ test_line_count = 2 out &&
+ git ls-files -o >out &&
+ test_line_count = 1 out &&
git rev-parse >actual \
- :0:y/b :0:y/c :0:y/e :3:y/d &&
@@ -102,11 +105,11 @@
- test_must_fail git rev-parse :1:y/d &&
- test_must_fail git rev-parse :2:y/d &&
- git ls-files -s y/d | grep ^100755 &&
-- test -f y/d
+- test_path_is_file y/d
+ test_must_fail git rev-parse :2:z/d &&
+ git ls-files -s z/d | grep ^100755 &&
-+ test -f z/d &&
-+ ! test -f y/d
++ test_path_is_file z/d &&
++ test_path_is_missing y/d
)
'
34: 8e199d483 = 31: c7ed5a213 merge-recursive: ensure we write updates for directory-renamed file
--
2.14.2
next reply other threads:[~2018-01-05 20:28 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-05 20:26 Elijah Newren [this message]
2018-01-05 20:26 ` [PATCHv6 01/31] directory rename detection: basic testcases Elijah Newren
2018-01-05 20:26 ` [PATCHv6 02/31] directory rename detection: directory splitting testcases Elijah Newren
2018-01-05 20:26 ` [PATCHv6 03/31] directory rename detection: testcases to avoid taking detection too far Elijah Newren
2018-01-26 11:37 ` SZEDER Gábor
2018-01-26 16:55 ` Elijah Newren
2018-01-05 20:26 ` [PATCHv6 04/31] directory rename detection: partially renamed directory testcase/discussion Elijah Newren
2018-01-05 20:26 ` [PATCHv6 05/31] directory rename detection: files/directories in the way of some renames Elijah Newren
2018-01-05 20:26 ` [PATCHv6 06/31] directory rename detection: testcases checking which side did the rename Elijah Newren
2018-01-05 20:26 ` [PATCHv6 07/31] directory rename detection: more involved edge/corner testcases Elijah Newren
2018-01-05 20:26 ` [PATCHv6 08/31] directory rename detection: testcases exploring possibly suboptimal merges Elijah Newren
2018-01-05 20:26 ` [PATCHv6 09/31] directory rename detection: miscellaneous testcases to complete coverage Elijah Newren
2018-01-05 20:26 ` [PATCHv6 10/31] directory rename detection: tests for handling overwriting untracked files Elijah Newren
2018-01-05 20:26 ` [PATCHv6 11/31] directory rename detection: tests for handling overwriting dirty files Elijah Newren
2018-01-05 20:26 ` [PATCHv6 12/31] merge-recursive: move the get_renames() function Elijah Newren
2018-01-05 20:26 ` [PATCHv6 13/31] merge-recursive: introduce new functions to handle rename logic Elijah Newren
2018-01-05 20:26 ` [PATCHv6 14/31] merge-recursive: fix leaks of allocated renames and diff_filepairs Elijah Newren
2018-01-05 20:26 ` [PATCHv6 15/31] merge-recursive: make !o->detect_rename codepath more obvious Elijah Newren
2018-01-05 20:26 ` [PATCHv6 16/31] merge-recursive: split out code for determining diff_filepairs Elijah Newren
2018-01-05 20:26 ` [PATCHv6 17/31] merge-recursive: add a new hashmap for storing directory renames Elijah Newren
2018-01-05 20:26 ` [PATCHv6 18/31] merge-recursive: make a helper function for cleanup for handle_renames Elijah Newren
2018-01-05 20:26 ` [PATCHv6 19/31] merge-recursive: add get_directory_renames() Elijah Newren
2018-01-05 20:27 ` [PATCHv6 20/31] merge-recursive: check for directory level conflicts Elijah Newren
2018-01-05 20:27 ` [PATCHv6 21/31] merge-recursive: add a new hashmap for storing file collisions Elijah Newren
2018-01-05 20:27 ` [PATCHv6 22/31] merge-recursive: add computation of collisions due to dir rename & merging Elijah Newren
2018-01-05 20:27 ` [PATCHv6 23/31] merge-recursive: check for file level conflicts then get new name Elijah Newren
2018-01-05 20:27 ` [PATCHv6 24/31] merge-recursive: when comparing files, don't include trees Elijah Newren
2018-01-05 20:27 ` [PATCHv6 25/31] merge-recursive: apply necessary modifications for directory renames Elijah Newren
2018-01-05 20:27 ` [PATCHv6 26/31] merge-recursive: avoid clobbering untracked files with " Elijah Newren
2018-01-05 20:27 ` [PATCHv6 27/31] merge-recursive: fix overwriting dirty files involved in renames Elijah Newren
2018-01-05 20:27 ` [PATCHv6 28/31] merge-recursive: fix remaining directory rename + dirty overwrite cases Elijah Newren
2018-01-05 20:27 ` [PATCHv6 29/31] directory rename detection: new testcases showcasing a pair of bugs Elijah Newren
2018-01-05 20:27 ` [PATCHv6 30/31] merge-recursive: avoid spurious rename/rename conflict from dir renames Elijah Newren
2018-01-05 20:27 ` [PATCHv6 31/31] merge-recursive: ensure we write updates for directory-renamed file Elijah Newren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180105202711.24311-1-newren@gmail.com \
--to=newren@gmail.com \
--cc=git@matthieu-moy.fr \
--cc=git@vger.kernel.org \
--cc=j6t@kdbg.org \
--cc=jrnieder@gmail.com \
--cc=peff@peff.net \
--cc=sbeller@google.com \
--cc=szeder.dev@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.