{"thread":{"id":"5859","subject":"\"fatal: Untracked working tree file 'so-and-so' would be overwritten by merge\"","startedAt":"2006-10-09T00:11:01Z","lastAt":"2006-10-10T06:32:31Z","messageCount":12,"participants":["Linus Torvalds","Junio C Hamano","Luben Tuikov"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"28438","messageId":"Pine.LNX.4.64.0610081657400.3952@g5.osdl.org","threadId":"5859","inReplyTo":null,"subject":"\"fatal: Untracked working tree file 'so-and-so' would be overwritten by merge\"","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-10-09T00:11:01Z","receivedAt":"2006-10-09T00:11:01Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nHmm. I'm getting this message annoyingly often, simply because a few files \nthat used to be tracked are now generated, and so they exist in my tree \nbut are no longer tracked.\n\nHowever, they may be tracked in an older tree that I pull, because in that \nolder tree they _do_ exist, and we get the\n\n\tfatal: Untracked working tree file 'so-and-so' would be overwritten by merge.\n\nwhich is actually incorrect, because the merge result will not even \n_contain_ that untracked file any more.\n\nSo the message is misleading - we should only consider this a fatal thing \nif we actually do generate that file as part of a git-read-tree, but if a \nmerge won't touch a file, it shouldn't be \"overwritten\".\n\nIt's true that if the _other_ end actually removed a file that we used to \nhave (ie the file _disappears_ as part of the merge), then we should \nverify that that file matched what we're going to remove, but if the old \nindex didn't contain the file at all, and the new index won't contain it \neither, it really should be a no-op.\n\nIOW, I think there is one \"verify_absent()\" too many somewhere, where we \ncheck this unnecessarily. I think it's the one in \"deleted_entry()\" in \nunpack-trees.c, but I'm not sure.\n\n\t\tLinus\n"},{"id":"28445","messageId":"7v7izaf62c.fsf@assigned-by-dhcp.cox.net","threadId":"5859","inReplyTo":"Pine.LNX.4.64.0610081657400.3952@g5.osdl.org","subject":"Re: \"fatal: Untracked working tree file 'so-and-so' would be overwritten by merge\"","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-09T04:48:11Z","receivedAt":"2006-10-09T04:48:11Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> Hmm. I'm getting this message annoyingly often, simply because a few files \n> that used to be tracked are now generated, and so they exist in my tree \n> but are no longer tracked.\n>\n> However, they may be tracked in an older tree that I pull, because in that \n> older tree they _do_ exist, and we get the\n>\n> \tfatal: Untracked working tree file 'so-and-so' would be overwritten by merge.\n>\n> which is actually incorrect, because the merge result will not even \n> _contain_ that untracked file any more.\n\n> So the message is misleading - we should only consider this a fatal thing \n> if we actually do generate that file as part of a git-read-tree, but if a \n> merge won't touch a file, it shouldn't be \"overwritten\".\n>\n> It's true that if the _other_ end actually removed a file that we used to \n> have (ie the file _disappears_ as part of the merge), then we should \n> verify that that file matched what we're going to remove, but if the old \n> index didn't contain the file at all, and the new index won't contain it \n> either, it really should be a no-op.\n\nTrue.\n\nI think it is verify_absent() on l.665 in threeway_merge().\n\n\tif (index) {\n\t\tverify_uptodate(index, o);\n\t}\n\telse if (path)\n\t\tverify_absent(path, \"overwritten\", o);\n\n\to->nontrivial_merge = 1;\n\nWe say \"we know this path is involved in the non-trivial merge;\nif the current index has it, it had better be up-to-date\" (the\nfirst \"if\").  I think that up to that check is fine.\n\nHowever, we say that otherwise, the path should not exist in the\nworking tree; this should not be done unconditionally.  As you\nsay, the check should depend on the merge result.\n\nBut that is a bit tricky.  This is not on the aggressive path,\nand the merge result is decided by the policy implemented by the\ncaller of read-tree.  So in that sense we should not be doing\nthe working tree check ourselves either.  We just should leave\nthat to the caller.\n\nHence, I think removing the above \"else if\" part altogether is\nthe right thing to do here.\n\n---\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 3ac0289..b1d78b8 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -661,8 +661,6 @@ int threeway_merge(struct cache_entry **\n \tif (index) {\n \t\tverify_uptodate(index, o);\n \t}\n-\telse if (path)\n-\t\tverify_absent(path, \"overwritten\", o);\n \n \to->nontrivial_merge = 1;\n \n"},{"id":"28446","messageId":"7vodsmdq0m.fsf@assigned-by-dhcp.cox.net","threadId":"5859","inReplyTo":"7v7izaf62c.fsf@assigned-by-dhcp.cox.net","subject":"Re: \"fatal: Untracked working tree file 'so-and-so' would be overwritten by merge\"","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-09T05:20:09Z","receivedAt":"2006-10-09T05:20:09Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n> But that is a bit tricky.  This is not on the aggressive path,\n> and the merge result is decided by the policy implemented by the\n> caller of read-tree.  So in that sense we should not be doing\n> the working tree check ourselves either.  We just should leave\n> that to the caller.\n>\n> Hence, I think removing the above \"else if\" part altogether is\n> the right thing to do here.\n>\n> ---\n> diff --git a/unpack-trees.c b/unpack-trees.c\n> index 3ac0289..b1d78b8 100644\n> --- a/unpack-trees.c\n> +++ b/unpack-trees.c\n> @@ -661,8 +661,6 @@ int threeway_merge(struct cache_entry **\n>  \tif (index) {\n>  \t\tverify_uptodate(index, o);\n>  \t}\n> -\telse if (path)\n> -\t\tverify_absent(path, \"overwritten\", o);\n>  \n>  \to->nontrivial_merge = 1;\n>  \n\nNote note note.  The above patch alone leaves merge risky to\nremove an untracked working tree files, and needs to be\ncompensated by corresponding checks to the git-merge-xxx\nstrategies.  The original code was overcautious, but was\nprotecting valid cases too.\n\nFor example, you and I recently independently did something\ncalled show-refs (mine was actually called show-ref but I could\nhave picked a name that happened to conflict with yours), and it\nwas when I had an uncommitted, not even in index, work-in-progress\nwhen I saw your version.  If I pulled from you, the version of\nread-tree without above check would have happily said it is OK\nto do a three-way merge, and git-merge-one-file would have said\nyou added one while I haven't, and would have tried to overwrite\nthe file in my working tree.\n\nBut this still feels wrong, at two levels.\n\nFor one thing, the beauty of git merge was that if there is a\nrisk of local changes being lost, it was detected at read-tree\nstage and we did not even touch index in that case.  Not\ndetecting problems at read-tree time and leaving it to\nmerge-one-file feels wrong.  Very wrong.\n\nI suspect the other issue I have is easier to address -- if we\nwere to implement the check at merge-one-file level, it would be\nsomething like the attached patch, but at the same time it\nshould take .gitignore file into account.\n\n---\n\ndiff --git a/git-merge-one-file.sh b/git-merge-one-file.sh\nindex fba4b0c..25aedb7 100755\n--- a/git-merge-one-file.sh\n+++ b/git-merge-one-file.sh\n@@ -23,6 +23,9 @@ #\n \"$1..\" | \"$1.$1\" | \"$1$1.\")\n \tif [ \"$2\" ]; then\n \t\techo \"Removing $4\"\n+\telif test -f \"$4\"\n+\t\techo \"ERROR: untracked $4 is removed by the merge.\"\n+\t\texit 1\n \tfi\n \tif test -f \"$4\"; then\n \t\trm -f -- \"$4\" &&\n@@ -34,8 +37,16 @@ #\n #\n # Added in one.\n #\n-\".$2.\" | \"..$3\" )\n+\".$2.\")\n+\t# the other side did not add and we added so there is nothing\n+\t# to be done.\n+\t;;\n+\"..$3\")\n \techo \"Adding $4\"\n+\ttest -f \"$4\" || {\n+\t\techo \"ERROR: untracked $4 is overwritten by the merge.\"\n+\t\texit 1\n+\t}\n \tgit-update-index --add --cacheinfo \"$6$7\" \"$2$3\" \"$4\" &&\n \t\texec git-checkout-index -u -f -- \"$4\"\n \t;;\n"},{"id":"28447","messageId":"7v8xjqdoq1.fsf_-_@assigned-by-dhcp.cox.net","threadId":"5859","inReplyTo":"7vodsmdq0m.fsf@assigned-by-dhcp.cox.net","subject":"[RFC/PATCH] merge: loosen overcautious \"working file will be lost\" check.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-09T05:48:06Z","receivedAt":"2006-10-09T05:48:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The three-way merge complained unconditionally when a path that\ndoes not exist in the index is involved in a merge when it\nexisted in the working tree.  If we are merging an old version\nthat had that path tracked, but the path is not tracked anymore,\nand if we are merging that old version in, the result will be\nthat the path is not tracked.  In that case we should not\ncomplain.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n * Consolidated patch to summarize a few crapoids I sent out\n   tonight.\n\n   The change to merge-one-file still does not do .gitignore\n   check but that is easy to add once we know this is the right\n   direction to go, which I am not sure yet.  If we can convince\n   ourselves that this is the right direction we should update\n   merge-recursive as well.\n\n git-merge-one-file.sh       |   16 ++++++++++++-\n t/t1004-read-tree-m-u-wf.sh |   53 +++++++++++++++++++++++++++++++++++++++++++\n unpack-trees.c              |    2 -\n 3 files changed, 68 insertions(+), 3 deletions(-)\n\ndiff --git a/git-merge-one-file.sh b/git-merge-one-file.sh\nindex fba4b0c..74ad4f2 100755\n--- a/git-merge-one-file.sh\n+++ b/git-merge-one-file.sh\n@@ -23,6 +23,12 @@ #\n \"$1..\" | \"$1.$1\" | \"$1$1.\")\n \tif [ \"$2\" ]; then\n \t\techo \"Removing $4\"\n+\telse\n+\t\t# read-tree checked that index matches HEAD already,\n+\t\t# so we know we do not have this path tracked.\n+\t\t# there may be an unrelated working tree file here,\n+\t\t# which we should just leave unmolested.\n+\t\texit 0\n \tfi\n \tif test -f \"$4\"; then\n \t\trm -f -- \"$4\" &&\n@@ -34,8 +40,16 @@ #\n #\n # Added in one.\n #\n-\".$2.\" | \"..$3\" )\n+\".$2.\")\n+\t# the other side did not add and we added so there is nothing\n+\t# to be done.\n+\t;;\n+\"..$3\")\n \techo \"Adding $4\"\n+\ttest -f \"$4\" || {\n+\t\techo \"ERROR: untracked $4 is overwritten by the merge.\"\n+\t\texit 1\n+\t}\n \tgit-update-index --add --cacheinfo \"$6$7\" \"$2$3\" \"$4\" &&\n \t\texec git-checkout-index -u -f -- \"$4\"\n \t;;\ndiff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh\nnew file mode 100755\nindex 0000000..018fbea\n--- /dev/null\n+++ b/t/t1004-read-tree-m-u-wf.sh\n@@ -0,0 +1,53 @@\n+#!/bin/sh\n+\n+test_description='read-tree -m -u checks working tree files'\n+\n+. ./test-lib.sh\n+\n+# two-tree test\n+\n+test_expect_success 'two-way setup' '\n+\n+\techo >file1 file one &&\n+\techo >file2 file two &&\n+\tgit update-index --add file1 file2 &&\n+\tgit commit -m initial &&\n+\n+\tgit branch side &&\n+\tgit tag -f branch-point &&\n+\n+\techo file2 is not tracked on the master anymore &&\n+\trm -f file2 &&\n+\tgit update-index --remove file2 &&\n+\tgit commit -a -m \"master removes file2\"\n+'\n+\n+test_expect_success 'two-way not clobbering' '\n+\n+\techo >file2 master creates untracked file2 &&\n+\tif err=`git read-tree -m -u master side 2>&1`\n+\tthen\n+\t\techo should have complained\n+\t\tfalse\n+\telse\n+\t\techo \"happy to see $err\"\n+\tfi\n+'\n+\n+# three-tree test\n+\n+test_expect_success 'three-way not complaining' '\n+\n+\trm -f file2 &&\n+\tgit checkout side &&\n+\techo >file3 file three &&\n+\tgit update-index --add file3 &&\n+\tgit commit -a -m \"side adds file3\" &&\n+\n+\tgit checkout master &&\n+\techo >file2 file two is untracked on the master side &&\n+\n+\tgit-read-tree -m -u branch-point master side\n+'\n+\n+test_done\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 3ac0289..b1d78b8 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -661,8 +661,6 @@ int threeway_merge(struct cache_entry **\n \tif (index) {\n \t\tverify_uptodate(index, o);\n \t}\n-\telse if (path)\n-\t\tverify_absent(path, \"overwritten\", o);\n \n \to->nontrivial_merge = 1;\n \n-- \n1.4.2.3.g2c59\n"},{"id":"28455","messageId":"Pine.LNX.4.64.0610090858120.3952@g5.osdl.org","threadId":"5859","inReplyTo":"7vodsmdq0m.fsf@assigned-by-dhcp.cox.net","subject":"Re: \"fatal: Untracked working tree file 'so-and-so' would be overwritten by merge\"","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-10-09T16:03:08Z","receivedAt":"2006-10-09T16:03:08Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 8 Oct 2006, Junio C Hamano wrote:\n> \n> Note note note.  The above patch alone leaves merge risky to\n> remove an untracked working tree files, and needs to be\n> compensated by corresponding checks to the git-merge-xxx\n> strategies.  The original code was overcautious, but was\n> protecting valid cases too.\n\nI think the difference _should_ be that we only remove the local file if \nit was removed _remotely_.\n\nIn  that case, it was there in the original tree, and removing it is \ncorrect.\n\n> diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh index \n> fba4b0c..25aedb7 100755 --- a/git-merge-one-file.sh +++ \n> b/git-merge-one-file.sh @@ -23,6 +23,9 @@ #\n>  \"$1..\" | \"$1.$1\" | \"$1$1.\")\n\nSo I actually think that we should NOT consider these three cases to be \nthe same.\n\nThere are really two distinct cases:\n\n - \"$1..\" and \"$1.$1\"\n\tThe file had already been removed locally, AND WE SHOULD NOT TOUCH \n\tIT.\n\n - \"$1$1.\":\n\tThe file was removed remotely, and we SHOULD remove it locally.\n\nIn fact, we already have that as a \"special case\":\n\n>  \tif [ \"$2\" ]; then\n>  \t\techo \"Removing $4\"\n> +\telif test -f \"$4\"\n> +\t\techo \"ERROR: untracked $4 is removed by the merge.\"\n> +\t\texit 1\n>  \tfi\n>  \tif test -f \"$4\"; then\n>  \t\trm -f -- \"$4\" &&\n\nThat\n\n\tif [ \"$2\" ]; then\n\t\techo \"Removing $4\"\n\nis _exactly_ that case: it is the \"$1$1.\" case, and we already treat it \ndifferently, but we actually treat it differently the wrong way: we only \nprint out the message for that case, but the actual \"touch working tree\" \ncode should _also_ be affected.\n\nIf the local index doesn't change, we should not print out the \"Removing \n'so-and-so'\" message, but we should also not even _touch_ that file, \nbecause it was already \"gone\" as far as the local tree was concerned.\n\nAgreed?\n\n\t\tLinus\n"},{"id":"28457","messageId":"7vr6xhcttg.fsf@assigned-by-dhcp.cox.net","threadId":"5859","inReplyTo":"Pine.LNX.4.64.0610090858120.3952@g5.osdl.org","subject":"Re: \"fatal: Untracked working tree file 'so-and-so' would be overwritten by merge\"","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-09T16:55:39Z","receivedAt":"2006-10-09T16:55:39Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> If the local index doesn't change, we should not print out the \"Removing \n> 'so-and-so'\" message, but we should also not even _touch_ that file, \n> because it was already \"gone\" as far as the local tree was concerned.\n>\n> Agreed?\n\nYes.\n"},{"id":"28458","messageId":"20061009172053.48882.qmail@web31804.mail.mud.yahoo.com","threadId":"5859","inReplyTo":"7v8xjqdoq1.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: [RFC/PATCH] merge: loosen overcautious \"working file will be lost\" check.","fromName":"Luben Tuikov","fromEmail":"ltuikov@yahoo.com","sentAt":"2006-10-09T17:20:52Z","receivedAt":"2006-10-09T17:20:52Z","isPatch":true,"sender":{"key":"ltuikov@yahoo.com","avatar":null},"body":"I think this is a good thing.\n\nHow about this case I've noticed in my trees:\n\nAfter branching out, a file is deleted, only to add\na different file with the same file name.\n\nThen any time I pull in from the trunk to merge,\nmerge fails with git-diff-files showing all 0's and the\nfile name in question.  Picture:\n\n  Branch B       +-----------------M1---->\n                /                 /\n               C2 <-- git-add A  /\n              /                 /\n             C1 <-- git-rm A   /\n            /                 /\nTrunk -----+-----------------+---->\n\nSince the common ancestor precedes git-rm, any Merge M1,\ncomplains that file A needs resolving with git-show-files\nall 0's.  I don't mind that so much and was wondering\nwhat you thought about it.\n\n    Luben\n\n--- Junio C Hamano <junkio@cox.net> wrote:\n\n> The three-way merge complained unconditionally when a path that\n> does not exist in the index is involved in a merge when it\n> existed in the working tree.  If we are merging an old version\n> that had that path tracked, but the path is not tracked anymore,\n> and if we are merging that old version in, the result will be\n> that the path is not tracked.  In that case we should not\n> complain.\n> \n> Signed-off-by: Junio C Hamano <junkio@cox.net>\n> ---\n> \n>  * Consolidated patch to summarize a few crapoids I sent out\n>    tonight.\n> \n>    The change to merge-one-file still does not do .gitignore\n>    check but that is easy to add once we know this is the right\n>    direction to go, which I am not sure yet.  If we can convince\n>    ourselves that this is the right direction we should update\n>    merge-recursive as well.\n> \n>  git-merge-one-file.sh       |   16 ++++++++++++-\n>  t/t1004-read-tree-m-u-wf.sh |   53 +++++++++++++++++++++++++++++++++++++++++++\n>  unpack-trees.c              |    2 -\n>  3 files changed, 68 insertions(+), 3 deletions(-)\n> \n> diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh\n> index fba4b0c..74ad4f2 100755\n> --- a/git-merge-one-file.sh\n> +++ b/git-merge-one-file.sh\n> @@ -23,6 +23,12 @@ #\n>  \"$1..\" | \"$1.$1\" | \"$1$1.\")\n>  \tif [ \"$2\" ]; then\n>  \t\techo \"Removing $4\"\n> +\telse\n> +\t\t# read-tree checked that index matches HEAD already,\n> +\t\t# so we know we do not have this path tracked.\n> +\t\t# there may be an unrelated working tree file here,\n> +\t\t# which we should just leave unmolested.\n> +\t\texit 0\n>  \tfi\n>  \tif test -f \"$4\"; then\n>  \t\trm -f -- \"$4\" &&\n> @@ -34,8 +40,16 @@ #\n>  #\n>  # Added in one.\n>  #\n> -\".$2.\" | \"..$3\" )\n> +\".$2.\")\n> +\t# the other side did not add and we added so there is nothing\n> +\t# to be done.\n> +\t;;\n> +\"..$3\")\n>  \techo \"Adding $4\"\n> +\ttest -f \"$4\" || {\n> +\t\techo \"ERROR: untracked $4 is overwritten by the merge.\"\n> +\t\texit 1\n> +\t}\n>  \tgit-update-index --add --cacheinfo \"$6$7\" \"$2$3\" \"$4\" &&\n>  \t\texec git-checkout-index -u -f -- \"$4\"\n>  \t;;\n> diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh\n> new file mode 100755\n> index 0000000..018fbea\n> --- /dev/null\n> +++ b/t/t1004-read-tree-m-u-wf.sh\n> @@ -0,0 +1,53 @@\n> +#!/bin/sh\n> +\n> +test_description='read-tree -m -u checks working tree files'\n> +\n> +. ./test-lib.sh\n> +\n> +# two-tree test\n> +\n> +test_expect_success 'two-way setup' '\n> +\n> +\techo >file1 file one &&\n> +\techo >file2 file two &&\n> +\tgit update-index --add file1 file2 &&\n> +\tgit commit -m initial &&\n> +\n> +\tgit branch side &&\n> +\tgit tag -f branch-point &&\n> +\n> +\techo file2 is not tracked on the master anymore &&\n> +\trm -f file2 &&\n> +\tgit update-index --remove file2 &&\n> +\tgit commit -a -m \"master removes file2\"\n> +'\n> +\n> +test_expect_success 'two-way not clobbering' '\n> +\n> +\techo >file2 master creates untracked file2 &&\n> +\tif err=`git read-tree -m -u master side 2>&1`\n> +\tthen\n> +\t\techo should have complained\n> +\t\tfalse\n> +\telse\n> +\t\techo \"happy to see $err\"\n> +\tfi\n> +'\n> +\n> +# three-tree test\n> +\n> +test_expect_success 'three-way not complaining' '\n> +\n> +\trm -f file2 &&\n> +\tgit checkout side &&\n> +\techo >file3 file three &&\n> +\tgit update-index --add file3 &&\n> +\tgit commit -a -m \"side adds file3\" &&\n> +\n> +\tgit checkout master &&\n> +\techo >file2 file two is untracked on the master side &&\n> +\n> +\tgit-read-tree -m -u branch-point master side\n> +'\n> +\n> +test_done\n> diff --git a/unpack-trees.c b/unpack-trees.c\n> index 3ac0289..b1d78b8 100644\n> --- a/unpack-trees.c\n> +++ b/unpack-trees.c\n> @@ -661,8 +661,6 @@ int threeway_merge(struct cache_entry **\n>  \tif (index) {\n>  \t\tverify_uptodate(index, o);\n>  \t}\n> -\telse if (path)\n> -\t\tverify_absent(path, \"overwritten\", o);\n>  \n>  \to->nontrivial_merge = 1;\n>  \n> -- \n> 1.4.2.3.g2c59\n> \n> \n> \n> -\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n> \n"},{"id":"28465","messageId":"7vy7rp9kdz.fsf@assigned-by-dhcp.cox.net","threadId":"5859","inReplyTo":"20061009172053.48882.qmail@web31804.mail.mud.yahoo.com","subject":"Re: [RFC/PATCH] merge: loosen overcautious \"working file will be lost\" check.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-09T22:47:36Z","receivedAt":"2006-10-09T22:47:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Luben Tuikov <ltuikov@yahoo.com> writes:\n\n> I think this is a good thing.\n>\n> How about this case I've noticed in my trees:\n>\n> After branching out, a file is deleted, only to add\n> a different file with the same file name.\n>\n> Then any time I pull in from the trunk to merge,\n> merge fails with git-diff-files showing all 0's and the\n> file name in question.  Picture:\n>\n>   Branch B       +-----------------M1---->\n>                 /                 /\n>                C2 <-- git-add A  /\n>               /                 /\n>              C1 <-- git-rm A   /\n>             /                 /\n> Trunk -----+-----------------+---->\n\nSorry I do not understand the picture; where is the common\nancestor?  If it is the left plus sign on the Trunk line, and\nyou are talking about what happens when making the merge M1,\nthen before C1 A did not exist (so Trunk tip which is the right\nplus sign on the Trunk line would not either), and the other\nhead (tip of branch B you are pulling the trunk into) would have\none already (from C2), so I would imagine it would be \"one side\nadds while the other did not touch\" (net effect since branch B\nforked from trunk is an addition of A, while Trunk did not do\nanything with respect to path A), so I do not see where any\nconflict can come from.  Puzzled.\n"},{"id":"28470","messageId":"20061010000127.76332.qmail@web31801.mail.mud.yahoo.com","threadId":"5859","inReplyTo":"7vy7rp9kdz.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC/PATCH] merge: loosen overcautious \"working file will be lost\" check.","fromName":"Luben Tuikov","fromEmail":"ltuikov@yahoo.com","sentAt":"2006-10-10T00:01:27Z","receivedAt":"2006-10-10T00:01:27Z","isPatch":true,"sender":{"key":"ltuikov@yahoo.com","avatar":null},"body":"--- Junio C Hamano <junkio@cox.net> wrote:\n> Luben Tuikov <ltuikov@yahoo.com> writes:\n> \n> > I think this is a good thing.\n> >\n> > How about this case I've noticed in my trees:\n> >\n> > After branching out, a file is deleted, only to add\n> > a different file with the same file name.\n> >\n> > Then any time I pull in from the trunk to merge,\n> > merge fails with git-diff-files showing all 0's and the\n> > file name in question.  Picture:\n> >\n> >   Branch B       +-----------------M1---->\n> >                 /                 /\n> >                C2 <-- git-add A  /\n> >               /                 /\n> >              C1 <-- git-rm A   /\n> >             /                 /\n> > Trunk -----+-----------------+---->\n> \n> Sorry I do not understand the picture; where is the common\n> ancestor?  If it is the left plus sign on the Trunk line, and\n\nYes, the left plus sign is the common ancestor.\n\n> you are talking about what happens when making the merge M1,\n> then before C1 A did not exist (so Trunk tip which is the right\n\nFile A exists before C1, it does not exist after C1.  C1 removes\nit.\n\n> plus sign on the Trunk line would not either), and the other\n> head (tip of branch B you are pulling the trunk into) would have\n> one already (from C2), so I would imagine it would be \"one side\n> adds while the other did not touch\" (net effect since branch B\n\nThe trunk is free to change/update file A.  In fact this is what\nmost likely happens.\n\n> forked from trunk is an addition of A, while Trunk did not do\n> anything with respect to path A), so I do not see where any\n> conflict can come from.  Puzzled.\n\n>From branch B's point of view, we are not interested in\nany updates/changes/etc of file A coming from the trunk.\nSince we've deleted that file and added our own, albeit\nwith the same name.\n\n   Luben\nP.S. I'm not sure if this is tenable, since it is hard\nfor GIT to know... or is it?\n"},{"id":"28471","messageId":"7vd5919g55.fsf@assigned-by-dhcp.cox.net","threadId":"5859","inReplyTo":"20061010000127.76332.qmail@web31801.mail.mud.yahoo.com","subject":"Re: [RFC/PATCH] merge: loosen overcautious \"working file will be lost\" check.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-10T00:19:18Z","receivedAt":"2006-10-10T00:19:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Luben Tuikov <ltuikov@yahoo.com> writes:\n\n> --- Junio C Hamano <junkio@cox.net> wrote:\n>> Luben Tuikov <ltuikov@yahoo.com> writes:\n>> \n>> > I think this is a good thing.\n>> >\n>> > How about this case I've noticed in my trees:\n>> >\n>> > After branching out, a file is deleted, only to add\n>> > a different file with the same file name.\n>> >\n>> > Then any time I pull in from the trunk to merge,\n>> > merge fails with git-diff-files showing all 0's and the\n>> > file name in question.  Picture:\n>> >\n>> >   Branch B       +-----------------M1---->\n>> >                 /                 /\n>> >                C2 <-- git-add A  /\n>> >               /                 /\n>> >              C1 <-- git-rm A   /\n>> >             /                 /\n>> > Trunk -----+-----------------+---->\n>> \n>> Sorry I do not understand the picture; where is the common\n>> ancestor?  If it is the left plus sign on the Trunk line, and\n>\n> Yes, the left plus sign is the common ancestor.\n>\n>> you are talking about what happens when making the merge M1,\n>> then before C1 A did not exist (so Trunk tip which is the right\n>\n> File A exists before C1, it does not exist after C1.  C1 removes\n> it.\n\nAh, I misunderstood.  But then I do not understand why you see\nall 0 anywhere.  Merge base has the path, branch B has it, and\ntrunk has it too; wouldn't it result in regular 3-way merge?\n\nI understand you do _not_ even want a regular 3-way merge in\nthis case, but that is a separate issue.  You could write a new\nmerge strategy to traverse ancestry chain between the merge base\nand each heads you are merging and notice disappearance and\nreappearance of the path, but that would slow things down\ntremendously for normal case and I do not think it is worth it.\n\nYou would also have exactly the same issue if you do not remove\nand then add the file, but if your work on the branch involves a\nsignificant rewrite.  Depending on how good the rewrite is,\nbugfixes that happened on the trunk based on an ancient code may\nnot even be needed (in other words, it would not apply cleanly\nanyway, but it does not matter -- the branch work is much better\nor has different set of problems that the trunk fix is\nirrelevant).\n\nAt that point, M1 would involve significant merge conflicts (and\nnot all-0 which I am still puzzled about), but I suspect that\nthe situation is obvious enough to the human (inspect git log\nbranch...trunk output and the log somewhere had better indicate\nthat the are unrelated), and the solution very much is different\ncase-by-case (most likely the person who pulls branch into trunk\nwould say \"keep ours\" for the path which would mean running \"git\ncat-file :2:$path >$path\", or say \"we are not really ready to merge\nyet\" and abort the entire merge; somebody on the trunk pulling\nfrom that branch might say \"I want other smaller fixes but this\ntotal rewrite is not ready yet -- keep ours\", or \"now we know\nthis is total rewrite and the small updates on the trunk does\nnot matter -- take theirs and from now on we will improve on the\nwork done on the branch\").\n\nSo in short, I do not think there is a clear-cut improvement we\ncan do to the tools to solve this.\n"},{"id":"28473","messageId":"20061010005915.30066.qmail@web31813.mail.mud.yahoo.com","threadId":"5859","inReplyTo":"7vd5919g55.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC/PATCH] merge: loosen overcautious \"working file will be lost\" check.","fromName":"Luben Tuikov","fromEmail":"ltuikov@yahoo.com","sentAt":"2006-10-10T00:59:15Z","receivedAt":"2006-10-10T00:59:15Z","isPatch":true,"sender":{"key":"ltuikov@yahoo.com","avatar":null},"body":"--- Junio C Hamano <junkio@cox.net> wrote:\n> Ah, I misunderstood.  But then I do not understand why you see\n> all 0 anywhere.  Merge base has the path, branch B has it, and\n> trunk has it too; wouldn't it result in regular 3-way merge?\n> \n> I understand you do _not_ even want a regular 3-way merge in\n> this case, but that is a separate issue.  You could write a new\n> merge strategy to traverse ancestry chain between the merge base\n> and each heads you are merging and notice disappearance and\n> reappearance of the path, but that would slow things down\n> tremendously for normal case and I do not think it is worth it.\n> \n> You would also have exactly the same issue if you do not remove\n> and then add the file, but if your work on the branch involves a\n> significant rewrite.  Depending on how good the rewrite is,\n> bugfixes that happened on the trunk based on an ancient code may\n> not even be needed (in other words, it would not apply cleanly\n> anyway, but it does not matter -- the branch work is much better\n> or has different set of problems that the trunk fix is\n> irrelevant).\n> \n> At that point, M1 would involve significant merge conflicts (and\n> not all-0 which I am still puzzled about), but I suspect that\n> the situation is obvious enough to the human (inspect git log\n> branch...trunk output and the log somewhere had better indicate\n> that the are unrelated), and the solution very much is different\n> case-by-case (most likely the person who pulls branch into trunk\n> would say \"keep ours\" for the path which would mean running \"git\n> cat-file :2:$path >$path\", or say \"we are not really ready to merge\n> yet\" and abort the entire merge; somebody on the trunk pulling\n> from that branch might say \"I want other smaller fixes but this\n> total rewrite is not ready yet -- keep ours\", or \"now we know\n> this is total rewrite and the small updates on the trunk does\n> not matter -- take theirs and from now on we will improve on the\n> work done on the branch\").\n> \n> So in short, I do not think there is a clear-cut improvement we\n> can do to the tools to solve this.\n\nYes, I agree.\n\n   Luben\n"},{"id":"28491","messageId":"7vfydw7kao.fsf@assigned-by-dhcp.cox.net","threadId":"5859","inReplyTo":"Pine.LNX.4.64.0610090858120.3952@g5.osdl.org","subject":"Re: \"fatal: Untracked working tree file 'so-and-so' would be overwritten by merge\"","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-10T06:32:31Z","receivedAt":"2006-10-10T06:32:31Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> On Sun, 8 Oct 2006, Junio C Hamano wrote:\n>> \n>> Note note note.  The above patch alone leaves merge risky to\n>> remove an untracked working tree files, and needs to be\n>> compensated by corresponding checks to the git-merge-xxx\n>> strategies.  The original code was overcautious, but was\n>> protecting valid cases too.\n>\n> I think the difference _should_ be that we only remove the local file if \n> it was removed _remotely_.\n>...\n> Agreed?\n\nI reviewed the patch I sent out, the one after the one you\nresponded to, and I think it (which is the one I have in \"pu\")\nis in line with the reasoning you outlined in your message.\n"}]}