path: root/diffcore-rename.c
diff options
authorMartin von Zweigbergk <>2011-03-24 02:41:01 (GMT)
committerJunio C Hamano <>2011-03-24 05:44:22 (GMT)
commitd7c9bf22351e39756f93f09b4251a6b5861d9cc0 (patch)
tree91df67daf4141de1ed040cd578e6280c0a1f41fd /diffcore-rename.c
parentda656f17d37fe96454645c08f21a24134f5aa900 (diff)
diffcore-rename: don't consider unmerged path as source
Since e9c8409 (diff-index --cached --raw: show tree entry on the LHS for unmerged entries., 2007-01-05), an unmerged entry should be detected by using DIFF_PAIR_UNMERGED(p), not by noticing both one and two sides of the filepair records mode=0 entries. However, it forgot to update some parts of the rename detection logic. This only makes difference in the "diff --cached" codepath where an unmerged filepair carries information on the entries that came from the tree. It probably hasn't been noticed for a long time because nobody would run "diff -M" during a conflict resolution, but "git status" uses rename detection when it internally runs "diff-index" and "diff-files" and gives nonsense results. In an unmerged pair, "one" side can have a valid filespec to record the tree entry (e.g. what's in HEAD) when running "diff --cached". This can be used as a rename source to other paths in the index that are not unmerged. The path that is unmerged by definition does not have the final content yet (i.e. "two" side cannot have a valid filespec), so it can never be a rename destination. Use the DIFF_PAIR_UNMERGED() to detect unmerged filepair correctly, and allow the valid "one" side of an unmerged filepair to be considered a potential rename source, but never to be considered a rename destination. Commit message and first two test cases by Junio, the rest by Martin. Signed-off-by: Martin von Zweigbergk <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'diffcore-rename.c')
1 files changed, 5 insertions, 2 deletions
diff --git a/diffcore-rename.c b/diffcore-rename.c
index df41be5..d5a99d6 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -439,7 +439,7 @@ void diffcore_rename(struct diff_options *options)
locate_rename_dst(p->two, 1);
- else if (!DIFF_FILE_VALID(p->two)) {
+ else if (!DIFF_PAIR_UNMERGED(p) && !DIFF_FILE_VALID(p->two)) {
* If the source is a broken "delete", and
* they did not really want to get broken,
@@ -574,7 +574,10 @@ void diffcore_rename(struct diff_options *options)
struct diff_filepair *p = q->queue[i];
struct diff_filepair *pair_to_free = NULL;
- if (!DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
+ diff_q(&outq, p);
+ }
+ else if (!DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
* Creation