{"thread":{"id":"5778","subject":"[BUG] 'git mv a/fileA b/fileB' causes 'c/fileC' to be deleted","startedAt":"2006-10-01T14:21:38Z","lastAt":"2006-10-02T05:20:13Z","messageCount":5,"participants":["Michael Cassar","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"28064","messageId":"750170aa0610010721p66899ba5pcc7efa13be4cd10a@mail.gmail.com","threadId":"5778","inReplyTo":null,"subject":"[BUG] 'git mv a/fileA b/fileB' causes 'c/fileC' to be deleted","fromName":"Michael Cassar","fromEmail":"m.e.cassar@gmail.com","sentAt":"2006-10-01T14:21:38Z","receivedAt":"2006-10-01T14:21:38Z","isPatch":false,"sender":{"key":"m.e.cassar@gmail.com","avatar":null},"body":"Hi,\n\nI'm new to git, so this may be user error, but I am getting some\nstrange behaviour using the 'git mv' command. In particular,\nattempting to move a file from one directory to another (performing\na rename in the process) causes an unrelated third-party file to\nbe deleted after commit.\n\nI have flicked through the git man pages and googled for git mv\nrelated issues, but haven't come up with anything.\n\nHere is a transcript. These results are reproducable using the same\nfiles, but I can't seem to reproduce with different files.\n\n\n## Create initial respository\n\n[mike@simba ~] git version\ngit version 1.4.2.1\n\n[mike@simba ~] mkdir repos; cd repos\n\n[mike@simba ~/repos] git init-db\ndefaulting to local storage area\n\n[mike@simba ~/repos] cp -r ~/thesis_work/* .\n\n[mike@simba ~/repos] ls -a\n.  ..  .git  metathesis  notes  papers  partA\n\n[mike@simba ~/repos] git add metathesis notes papers partA\n\n[mike@simba ~/repos] git commit -m 'initial import'\nCommitting initial tree 77d618ebc7c8e655c1d2f0e223e1957b6b5ff247\n\n## Files that we are going to deal with. Note that 'outline.txt' is an\n## innocent third party.\n\n[mike@simba ~/repos] sha1sum partA/outline.txt\n891256d20531ebc288f1abb5e23f9979597889d3  partA/outline.txt\n\n[mike@simba ~/repos] sha1sum papers/unsorted/Thesis.pdf\n52446ade19a067253e8407bf092b52e5efa35247  papers/unsorted/Thesis.pdf\n\n## Move 'Thesis.pdf' to a new name, and commit\n\n[mike@simba ~/repos] git mv papers/unsorted/Thesis.pdf\npapers/all-papers/new-name.pdf\n\n[mike@simba ~/repos] git commit -m 'moved a file'\n\n## Have a look at what git just did. In particular, note that 'outline.txt'\n## has magically appeared in the log\n\n[mike@simba ~/repos] cg log -f | head\ncommit aa544a0d58118eb01fa6768e438fa0f521d6095b\ntree 07c4971e3946b7c33742515e8915ec6e8abc4e40\nparent 0d4292e44aa999707eddf31c4bbcadd711a170be\nauthor mike <mike@simba.home> Sun, 01 Oct 2006 23:39:06 +1000\ncommitter mike <mike@simba.home> Sun, 01 Oct 2006 23:39:06 +1000\n\n    * papers/all-papers/new-name.pdf, partA/outline.txt:\n\n    moved a file\n\n## What changes are in the commit?\n\n[mike@simba ~/repos] git show aa544a0d58118eb01fa6768e438fa0f521d6095b\n| head -19\ncommit aa544a0d58118eb01fa6768e438fa0f521d6095b\nAuthor: mike <mike@simba.home>\nDate:   Sun Oct 1 23:39:06 2006 +1000\n\n    moved a file\n\ndiff --git a/papers/all-papers/new-name.pdf b/papers/all-papers/new-name.pdf\nnew file mode 100644\nindex 0000000..5441543\nBinary files /dev/null and b/papers/all-papers/new-name.pdf differ\ndiff --git a/partA/outline.txt b/partA/outline.txt\ndeleted file mode 100644\nindex d3ac280..0000000\n--- a/partA/outline.txt\n+++ /dev/null\n@@ -1,65 +0,0 @@\n-\n-Thesis Part A\n-\n[rest of file outline.txt deleted]\n\nIs this just me being an idiot, or could there be a bigger problem\nhere?\n\nPlease CC me in any replies.\n\nCheers,\n\nMike\n"},{"id":"28067","messageId":"7vpsdc0wkz.fsf@assigned-by-dhcp.cox.net","threadId":"5778","inReplyTo":"750170aa0610010721p66899ba5pcc7efa13be4cd10a@mail.gmail.com","subject":"Re: [BUG] 'git mv a/fileA b/fileB' causes 'c/fileC' to be deleted","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-01T17:34:04Z","receivedAt":"2006-10-01T17:34:04Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Michael Cassar\" <m.e.cassar@gmail.com> writes:\n\n> Is this just me being an idiot, or could there be a bigger problem\n> here?\n>\n> Please CC me in any replies.\n\nThere could be a bigger problem, but it does not seem to easily\nreproduce as you noted in the message.  It could be that some\nunrelated thing in the working tree is playing a role in this\nbreakage, but I do not think of offhand what that is.\n\nHere is what I just ran.\n\n-- >8 cut >8 --\n#!/bin/sh\n\nreport () {\n\techo\n\techo \"* $*\"\n\techo\n}\n\nrm -fr test0\nmkdir test0\ncd test0\n\nreport working tree preparation\nmkdir -p partA papers/unsorted papers/all-papers\necho outline >partA/outline.txt\necho Thesis >papers/unsorted/Thesis.pdf\n\nreport repository initialization\ngit init-db\n\nreport initial import\ngit add papers partA\ngit commit -m 'initial'\ngit show --root --stat --summary\n\nreport run mv\ngit mv papers/unsorted/Thesis.pdf papers/all-papers/Thesis.pdf\n\nreport before commit\ngit diff --stat HEAD\n\nreport make a commit\ngit commit -m 'moved a file'\n\nreport final result\ngit show --stat --summary\n-- 8< cut 8< --\n\nand I did not see the breakage.  Care to show a bit more details\non your working tree?  I do not think this depends on any\ncontents of the individual files, but\n\n> Here is a transcript. These results are reproducable using the same\n> files, but I can't seem to reproduce with different files.\n>\n> ## Create initial respository\n>\n> [mike@simba ~] git version\n> git version 1.4.2.1\n>\n> [mike@simba ~] mkdir repos; cd repos\n>\n> [mike@simba ~/repos] git init-db\n> defaulting to local storage area\n>\n> [mike@simba ~/repos] cp -r ~/thesis_work/* .\n>\n> [mike@simba ~/repos] ls -a\n> .  ..  .git  metathesis  notes  papers  partA\n>\n> [mike@simba ~/repos] git add metathesis notes papers partA\n\n\noutput from \"find metathesis notes papers partA -ls\" and \"git\nls-files -s\" at this step may be a starter.\n"},{"id":"28094","messageId":"750170aa0610011833n39271704q349d86af76832783@mail.gmail.com","threadId":"5778","inReplyTo":"7vpsdc0wkz.fsf@assigned-by-dhcp.cox.net","subject":"Re: [BUG] 'git mv a/fileA b/fileB' causes 'c/fileC' to be deleted","fromName":"Michael Cassar","fromEmail":"m.e.cassar@gmail.com","sentAt":"2006-10-02T01:33:09Z","receivedAt":"2006-10-02T01:33:09Z","isPatch":false,"sender":{"key":"m.e.cassar@gmail.com","avatar":null},"body":"On 10/2/06, Junio C Hamano <junkio@cox.net> wrote:\n> There could be a bigger problem, but it does not seem to easily\n> reproduce as you noted in the message.  It could be that some\n> unrelated thing in the working tree is playing a role in this\n> breakage, but I do not think of offhand what that is.\n\n> [...]  Care to show a bit more details\n> on your working tree?\n\nOkay, I should stop being lazy and actually produce a minimal test-case.\n\nHere we go:\n\n--CUT--\n#!/bin/bash\n\ngit init-db\n\nmkdir papers\nmkdir papers/unsorted\nmkdir papers/all-papers\nmkdir partA\necho 'moo' > papers/unsorted/Thesis.pdf\necho 'cow' > partA/outline.txt\necho 'this file has brackets in its filename' > 'papers/unsorted/(brackets).pdf'\n\ngit add  papers partA\ngit commit -m 'intial commit'\n\ngit mv papers/unsorted/Thesis.pdf papers/all-papers/moo-blah.pdf\ngit commit -m 'move a file'\n\ncg log -f\n--CUT--\n\nThe problem seems to have come from the fact that a file in the source\ndirectory of the move contained brackets in its filename.Removing the\nfile causes the problem to go away.\n\nHope this helps a little,\n\nMike\n"},{"id":"28100","messageId":"7vven3xq7l.fsf@assigned-by-dhcp.cox.net","threadId":"5778","inReplyTo":"750170aa0610011833n39271704q349d86af76832783@mail.gmail.com","subject":"Re: [BUG] 'git mv a/fileA b/fileB' causes 'c/fileC' to be deleted","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-02T05:05:18Z","receivedAt":"2006-10-02T05:05:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks.  I see it reproduces.\n\nIt is a bug in git-mv that fails to update cache-tree data\nstructure properly.  This patch should fix it.\n\n-- >8 --\ngit-mv: do not write out a bogus cache-tree in the index\n\nThe command updates the cache without invalidating the cache\ntree entries.  Since this is not as performance critical as\none-tree and two-tree git-read-tree and git-apply, disable\nuse of cache-tree entirely.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\ndiff --git a/builtin-mv.c b/builtin-mv.c\nindex 4d21d88..9a4e2e0 100644\n--- a/builtin-mv.c\n+++ b/builtin-mv.c\n@@ -83,6 +83,9 @@ int cmd_mv(int argc, const char **argv, \n \tif (read_cache() < 0)\n \t\tdie(\"index file corrupt\");\n \n+\t/* This does not manage cache-tree properly */\n+\tcache_tree_free(&active_cache_tree);\n+\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \n"},{"id":"28101","messageId":"7vmz8fxpiq.fsf@assigned-by-dhcp.cox.net","threadId":"5778","inReplyTo":"7vven3xq7l.fsf@assigned-by-dhcp.cox.net","subject":"Re: [BUG] 'git mv a/fileA b/fileB' causes 'c/fileC' to be deleted","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-02T05:20:13Z","receivedAt":"2006-10-02T05:20:13Z","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> Thanks.  I see it reproduces.\n>\n> It is a bug in git-mv that fails to update cache-tree data\n> structure properly.  This patch should fix it.\n\nThe previous patch was safer but unnecessarily was a bit heavy\nhanded.  This should fix it nicer.\n\n-- >8 --\ngit-mv: invalidate the removed path properly in cache-tree\n\nThe command updated the cache without invalidating the cache\ntree entries while removing an existing entry.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\ndiff --git a/builtin-mv.c b/builtin-mv.c\nindex 4d21d88..54dd3bf 100644\n--- a/builtin-mv.c\n+++ b/builtin-mv.c\n@@ -278,6 +278,7 @@ int cmd_mv(int argc, const char **argv, \n \t\tfor (i = 0; i < deleted.nr; i++) {\n \t\t\tconst char *path = deleted.items[i].path;\n \t\t\tremove_file_from_cache(path);\n+\t\t\tcache_tree_invalidate_path(active_cache_tree, path);\n \t\t}\n \n \t\tif (active_cache_changed) {\n"}]}