Commit 2d24690c67713ce2e809f1393c96541bcf2662df

Kartikaya Gupta 2021-04-15T07:48:43

Add testcase

diff --git a/tests/diff/rename.c b/tests/diff/rename.c
index aaae3e9..bd25d29 100644
--- a/tests/diff/rename.c
+++ b/tests/diff/rename.c
@@ -21,6 +21,8 @@ void test_diff_rename__cleanup(void)
 #define RENAME_MODIFICATION_COMMIT "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13"
 #define REWRITE_DELETE_COMMIT "84d8efa38af7ace2b302de0adbda16b1f1cd2e1b"
 #define DELETE_RENAME_COMMIT "be053a189b0bbde545e0a3f59ce00b46ad29ce0d"
+#define BREAK_REWRITE_BASE_COMMIT "db98035f715427eef1f5e17f03e1801c05301e9e"
+#define BREAK_REWRITE_COMMIT "7e7bfb88ba9bc65fd700fee1819cf1c317aafa56"
 
 /*
  * Renames repo has:
@@ -1977,3 +1979,56 @@ void test_diff_rename__delete_and_rename(void)
 	git_tree_free(old_tree);
 	git_tree_free(new_tree);
 }
+
+/*
+ * The break_rewrite branch contains a testcase reduced from
+ * a real-world scenario, rather than being "constructed" like
+ * the above tests seem to be. There are two commits layered
+ * on top of the repo's initial commit; the base commit which
+ * clears out the files from the initial commit and installs
+ * four files. And then there's the modification commit which
+ * mutates the files in such a way as to trigger the bug in
+ * libgit2.
+ * commit db98035f715427eef1f5e17f03e1801c05301e9e
+ *   serving.txt     (deleted)
+ *   sevencities.txt (deleted)
+ *   AAA             (313 lines)
+ *   BBB             (314 lines)
+ *   CCC             (704 lines)
+ *   DDD             (314 lines, identical to BBB)
+ * commit 7e7bfb88ba9bc65fd700fee1819cf1c317aafa56
+ *   This deletes CCC and makes slight modifications
+ *   to AAA, BBB, and DDD. The find_best_matches loop
+ *   for git_diff_find_similar computes the following:
+ *   CCC    moved to    AAA     (similarity 91)
+ *   CCC    copied to   AAA     (similarity 91)
+ *   DDD    moved to    BBB     (similarity 52)
+ *   CCC    copied to   BBB     (similarity 90)
+ *   BBB    moved to    DDD     (similarity 52)
+ *   CCC    copied to   DDD     (similarity 90)
+ * The code to rewrite the diffs by resolving these
+ * copies/renames would resolve the BBB <-> DDD moves
+ * but then still leave BBB as a rename target for
+ * the deleted file CCC. Since the split flag on BBB
+ * was cleared, this would trigger an error.
+ */
+void test_diff_rename__break_rewrite(void)
+{
+	const char *old_sha = BREAK_REWRITE_BASE_COMMIT;
+	const char *new_sha = BREAK_REWRITE_COMMIT;
+	git_tree *old_tree, *new_tree;
+	git_diff *diff;
+	git_diff_find_options find_opts = GIT_DIFF_FIND_OPTIONS_INIT;
+
+	old_tree = resolve_commit_oid_to_tree(g_repo, old_sha);
+	new_tree = resolve_commit_oid_to_tree(g_repo, new_sha);
+
+	find_opts.flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES | GIT_DIFF_BREAK_REWRITES | GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY;
+
+	cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, old_tree, new_tree, NULL));
+	cl_git_pass(git_diff_find_similar(diff, &find_opts));
+
+	git_diff_free(diff);
+	git_tree_free(old_tree);
+	git_tree_free(new_tree);
+}
diff --git a/tests/resources/renames/.gitted/ORIG_HEAD b/tests/resources/renames/.gitted/ORIG_HEAD
new file mode 100644
index 0000000..642c319
--- /dev/null
+++ b/tests/resources/renames/.gitted/ORIG_HEAD
@@ -0,0 +1 @@
+19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13
diff --git a/tests/resources/renames/.gitted/index b/tests/resources/renames/.gitted/index
index 72363c0..5882a8d 100644
Binary files a/tests/resources/renames/.gitted/index and b/tests/resources/renames/.gitted/index differ
diff --git a/tests/resources/renames/.gitted/logs/HEAD b/tests/resources/renames/.gitted/logs/HEAD
index e697922..e6da678 100644
--- a/tests/resources/renames/.gitted/logs/HEAD
+++ b/tests/resources/renames/.gitted/logs/HEAD
@@ -2,3 +2,8 @@
 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 2bc7f351d20b53f1c72c16c4b036e491c478c49a Russell Belfer <rb@github.com> 1351024817 -0700	commit: copy and rename with no change
 2bc7f351d20b53f1c72c16c4b036e491c478c49a 1c068dee5790ef1580cfc4cd670915b48d790084 Russell Belfer <rb@github.com> 1361485758 -0800	commit: rewrites, copies with changes, etc.
 1c068dee5790ef1580cfc4cd670915b48d790084 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 Russell Belfer <rb@github.com> 1361486360 -0800	commit: more renames and smallish modifications
+19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 Kartikaya Gupta <kats@pancake.staktrace.com> 1618486966 -0400	checkout: moving from master to break_rewrite
+31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 db98035f715427eef1f5e17f03e1801c05301e9e Kartikaya Gupta <kats@pancake.staktrace.com> 1618487039 -0400	commit: This test needs to start with a minimum of four files
+db98035f715427eef1f5e17f03e1801c05301e9e 7e7bfb88ba9bc65fd700fee1819cf1c317aafa56 Kartikaya Gupta <kats@pancake.staktrace.com> 1618487097 -0400	commit: Copy/modify files around
+7e7bfb88ba9bc65fd700fee1819cf1c317aafa56 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 Kartikaya Gupta <kats@pancake.staktrace.com> 1618487105 -0400	checkout: moving from break_rewrite to master
+19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13 Kartikaya Gupta <kats@pancake.staktrace.com> 1618487271 -0400	reset: moving to HEAD
diff --git a/tests/resources/renames/.gitted/objects/41/2a2eaf2c13103ea976b3b02c17abee7a358432 b/tests/resources/renames/.gitted/objects/41/2a2eaf2c13103ea976b3b02c17abee7a358432
new file mode 100644
index 0000000..d0d3334
Binary files /dev/null and b/tests/resources/renames/.gitted/objects/41/2a2eaf2c13103ea976b3b02c17abee7a358432 differ
diff --git a/tests/resources/renames/.gitted/objects/5a/71babaaac78a758b52576a60cea3c218c8b546 b/tests/resources/renames/.gitted/objects/5a/71babaaac78a758b52576a60cea3c218c8b546
new file mode 100644
index 0000000..e685bfa
Binary files /dev/null and b/tests/resources/renames/.gitted/objects/5a/71babaaac78a758b52576a60cea3c218c8b546 differ
diff --git a/tests/resources/renames/.gitted/objects/7e/7bfb88ba9bc65fd700fee1819cf1c317aafa56 b/tests/resources/renames/.gitted/objects/7e/7bfb88ba9bc65fd700fee1819cf1c317aafa56
new file mode 100644
index 0000000..e53c843
--- /dev/null
+++ b/tests/resources/renames/.gitted/objects/7e/7bfb88ba9bc65fd700fee1819cf1c317aafa56
@@ -0,0 +1,2 @@
+xKn0))"e19Ec
+b4n0WR^2)؎>'VL	܀׎<Dv!ygMVqP"oHbTJHC^W<486eY̳vYg|u|GDh.zUyc~vޗ:N2dnXGT
\ No newline at end of file
diff --git a/tests/resources/renames/.gitted/objects/bf/102db0c9c0c1513909a90e0611b5dddfc87c93 b/tests/resources/renames/.gitted/objects/bf/102db0c9c0c1513909a90e0611b5dddfc87c93
new file mode 100644
index 0000000..69ddd68
--- /dev/null
+++ b/tests/resources/renames/.gitted/objects/bf/102db0c9c0c1513909a90e0611b5dddfc87c93
@@ -0,0 +1,2 @@
+x+)JMU042a040031Qpttd83яfӮ-[yPi''']V*
+J8ĉnPigggכU=ᩫvR%b	Pi:6
\ No newline at end of file
diff --git a/tests/resources/renames/.gitted/objects/cc/980ffac5f1393696d4cd703ea9d2fde67dd367 b/tests/resources/renames/.gitted/objects/cc/980ffac5f1393696d4cd703ea9d2fde67dd367
new file mode 100644
index 0000000..ac7a005
Binary files /dev/null and b/tests/resources/renames/.gitted/objects/cc/980ffac5f1393696d4cd703ea9d2fde67dd367 differ
diff --git a/tests/resources/renames/.gitted/objects/db/98035f715427eef1f5e17f03e1801c05301e9e b/tests/resources/renames/.gitted/objects/db/98035f715427eef1f5e17f03e1801c05301e9e
new file mode 100644
index 0000000..48bc2e1
Binary files /dev/null and b/tests/resources/renames/.gitted/objects/db/98035f715427eef1f5e17f03e1801c05301e9e differ
diff --git a/tests/resources/renames/.gitted/objects/eb/b3b7af1d25c8492d2f626826c92458b7cefd60 b/tests/resources/renames/.gitted/objects/eb/b3b7af1d25c8492d2f626826c92458b7cefd60
new file mode 100644
index 0000000..813e7ad
Binary files /dev/null and b/tests/resources/renames/.gitted/objects/eb/b3b7af1d25c8492d2f626826c92458b7cefd60 differ
diff --git a/tests/resources/renames/.gitted/objects/ed/2a95c4a6c295b9afcea50baff63ec544ccf600 b/tests/resources/renames/.gitted/objects/ed/2a95c4a6c295b9afcea50baff63ec544ccf600
new file mode 100644
index 0000000..4f439e2
Binary files /dev/null and b/tests/resources/renames/.gitted/objects/ed/2a95c4a6c295b9afcea50baff63ec544ccf600 differ
diff --git a/tests/resources/renames/.gitted/objects/f6/7e2f70efe89665e829ea0d77c46965ad1307e4 b/tests/resources/renames/.gitted/objects/f6/7e2f70efe89665e829ea0d77c46965ad1307e4
new file mode 100644
index 0000000..1cad213
Binary files /dev/null and b/tests/resources/renames/.gitted/objects/f6/7e2f70efe89665e829ea0d77c46965ad1307e4 differ
diff --git a/tests/resources/renames/.gitted/refs/heads/break_rewrite b/tests/resources/renames/.gitted/refs/heads/break_rewrite
new file mode 100644
index 0000000..d170915
--- /dev/null
+++ b/tests/resources/renames/.gitted/refs/heads/break_rewrite
@@ -0,0 +1 @@
+7e7bfb88ba9bc65fd700fee1819cf1c317aafa56