{"thread":{"id":"6659","subject":"[PATCH 2/2] Keep untracked files not involved in a merge.","startedAt":"2007-02-04T05:45:54Z","lastAt":"2007-02-04T05:45:54Z","messageCount":1,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"33534","messageId":"20070204054554.GB17344@spearce.org","threadId":"6659","inReplyTo":null,"subject":"[PATCH 2/2] Keep untracked files not involved in a merge.","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-04T05:45:54Z","receivedAt":"2007-02-04T05:45:54Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"My earlier fix (8371234e) to delete renamed tracked files from the\nworking directory also caused merge-recursive to delete untracked\nfiles that were in the working directory.\n\nThe problem here is merge-recursive is deleting the working directory\nfile without regard for which branch it was associated with.  What we\nreally want to do during a merge is to only delete files that were\nrenamed by the branch we are merging into the current branch,\nand that are still tracked by the current branch.  These files\ndefinately don't belong in the working directory anymore.\n\nAnything else is either a merge conflict (already handled in other\nparts of the code) or a file that is untracked by the current branch\nand thus is not even participating in the merge.  Its this latter\nclass that must be left alone.\n\nFor this fix to work we are now assuming that the first non-base\nargument passed to git-merge-recursive always corresponds to the\nworking directory.  This is already true for all in-tree callers\nof merge-recursive.  This assumption is also supported by the\nlong time usage message of \"<base> ... -- <head> <remote>\", where\n\"<head>\" is implied to be HEAD, which is generally assumed to be\nthe current tree-ish.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n merge-recursive.c               |    2 +-\n t/t6023-merge-rename-nocruft.sh |   42 +++++++++++++++++++++++++++++++++++++++\n 2 files changed, 43 insertions(+), 1 deletions(-)\n\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex fa320eb..bbb52a7 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -891,7 +891,7 @@ static int process_renames(struct path_list *a_renames,\n \t\t\tstruct diff_filespec src_other, dst_other;\n \t\t\tint try_merge, stage = a_renames == renames1 ? 3: 2;\n \n-\t\t\tremove_file(1, ren1_src, index_only);\n+\t\t\tremove_file(1, ren1_src, index_only || stage == 3);\n \n \t\t\thashcpy(src_other.sha1, ren1->src_entry->stages[stage].sha);\n \t\t\tsrc_other.mode = ren1->src_entry->stages[stage].mode;\ndiff --git a/t/t6023-merge-rename-nocruft.sh b/t/t6023-merge-rename-nocruft.sh\nindex 69c66cf..65be95f 100755\n--- a/t/t6023-merge-rename-nocruft.sh\n+++ b/t/t6023-merge-rename-nocruft.sh\n@@ -45,6 +45,7 @@ git add A M &&\n git commit -m \"initial has A and M\" &&\n git branch white &&\n git branch red &&\n+git branch blue &&\n \n git checkout white &&\n sed -e \"/^g /s/.*/g : white changes a line/\" <A >B &&\n@@ -58,6 +59,13 @@ echo created by red >R &&\n git update-index --add R &&\n git commit -m \"red creates R\" &&\n \n+git checkout blue &&\n+sed -e \"/^o /s/.*/g : blue changes a line/\" <A >B &&\n+rm -f A &&\n+mv B A &&\n+git update-index A &&\n+git commit -m \"blue modify A\" &&\n+\n git checkout master'\n \n # This test broke in 65ac6e9c3f47807cb603af07a6a9e1a43bc119ae\n@@ -94,4 +102,38 @@ test_expect_success 'merge white into red (A->B,M->N)' \\\n \treturn 0\n '\n \n+# This test broke in 8371234ecaaf6e14fe3f2082a855eff1bbd79ae9\n+test_expect_success 'merge blue into white (A->B, mod A, A untracked)' \\\n+'\n+\tgit checkout -b white-blue white &&\n+\techo dirty >A &&\n+\tgit merge blue &&\n+\tgit write-tree >/dev/null || {\n+\t\techo \"BAD: merge did not complete\"\n+\t\treturn 1\n+\t}\n+\n+\ttest -f A || {\n+\t\techo \"BAD: A does not exist in working directory\"\n+\t\treturn 1\n+\t}\n+\ttest `cat A` = dirty || {\n+\t\techo \"BAD: A content is wrong\"\n+\t\treturn 1\n+\t}\n+\ttest -f B || {\n+\t\techo \"BAD: B does not exist in working directory\"\n+\t\treturn 1\n+\t}\n+\ttest -f N || {\n+\t\techo \"BAD: N does not exist in working directory\"\n+\t\treturn 1\n+\t}\n+\ttest -f M && {\n+\t\techo \"BAD: M still exists in working directory\"\n+\t\treturn 1\n+\t}\n+\treturn 0\n+'\n+\n test_done\n-- \n1.5.0.rc3.22.g5057\n"}]}