{"thread":{"id":"28183","subject":"Merge after directory rename ?","startedAt":"2011-08-21T21:41:38Z","lastAt":"2011-08-23T19:13:50Z","messageCount":8,"participants":["Marcin Wiśnicki","Michael Witten","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"173972","messageId":"j2ru2h$cd$1@dough.gmane.org","threadId":"28183","inReplyTo":null,"subject":"Merge after directory rename ?","fromName":"Marcin Wiśnicki","fromEmail":"mwisnicki@gmail.com","sentAt":"2011-08-21T21:41:38Z","receivedAt":"2011-08-21T21:41:38Z","isPatch":false,"sender":{"key":"mwisnicki@gmail.com","avatar":"https://gravatar.com/avatar/6bc6cce46e549217fe39b05ac03acb4f5755154d6752ff65b580783365ad3e50?d=mp&s=160"},"body":"Is it possible to merge files after performing directory renames in such \nway that new files will end up in renamed directories ?\n\nFor example:\n1. [master]  add dir1/file1\n2. [branch1] branch from master\n3. [branch1] add dir1/file2\n4. [master]  rename dir1 to dir2\n5. [master]  merge branch1\n\nWhere it should notice that dir1=>dir2 and therefore {dir1=>dir2}/file2.\n\nCurrently I end up with dir1/file2 which is undesirable as it breaks \nrefactorings and requires a lot of manual effort to clean-up.\n"},{"id":"173978","messageId":"CAMOZ1BukGPZt8gJh0J4EHRrPHv5teAdnkNT+gZJa9mX=2ohFOw@mail.gmail.com","threadId":"28183","inReplyTo":"j2ru2h$cd$1@dough.gmane.org","subject":"Re: Merge after directory rename ?","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2011-08-21T23:45:19Z","receivedAt":"2011-08-21T23:45:19Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"2011/8/21 Marcin Wiśnicki <mwisnicki@gmail.com>:\n> Is it possible to merge files after performing directory renames in such\n> way that new files will end up in renamed directories ?\n>\n> For example:\n> 1. [master]  add dir1/file1\n> 2. [branch1] branch from master\n> 3. [branch1] add dir1/file2\n> 4. [master]  rename dir1 to dir2\n> 5. [master]  merge branch1\n>\n> Where it should notice that dir1=>dir2 and therefore {dir1=>dir2}/file2.\n>\n> Currently I end up with dir1/file2 which is undesirable as it breaks\n> refactorings and requires a lot of manual effort to clean-up.\n\nPart of the assumption for someone working on `branch1' might be that\n`dir1/file2' is in fact in `dir1'. The rename via `master' conflicts\nwith that assumption. In this case, a full-blown conflict might be\nuseful.\n\nHowever, suppose that the author who is working with `master' doesn't\nneed `dir1', but the author who is working with `branch1' does need it\nINDEPENDENTLY:\n\n  1. [master]  add dir2/file1\n  2. [branch1] branch from master\n  3. [branch1] add dir1/file2\n  4. [master]  add dir1/file3\n  5. [master]  rename dir1/file3 to dir3/file3\n  6. [master]  merge branch1\n\nIn that case, you'd want `dir1/file2' from the `branch1' work to be\nsilently created rather than automatically renamed to `dir3/file3'.\nThis should not result in a conflict or a rename.\n\nSo, from your grievance, I suppose that git currently assumes the\nlatter case (and hence, gives no indication of a possible conflict).\nPerhaps git could be improved here at least in terms of a warning.\nPerhaps the merger could request that directory renames be considered\nconflicts or enforced, but this would have to involve the intent of\nthe merger me thinks (using command line flags).\n"},{"id":"173979","messageId":"CAMOZ1Bt8cP146xiDXfSA-naSOaS3AC8pUZgW12=3TMg2JGCD=w@mail.gmail.com","threadId":"28183","inReplyTo":"CAMOZ1BukGPZt8gJh0J4EHRrPHv5teAdnkNT+gZJa9mX=2ohFOw@mail.gmail.com","subject":"Re: Merge after directory rename ?","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2011-08-21T23:53:34Z","receivedAt":"2011-08-21T23:53:34Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"2011/8/21 Michael Witten <mfwitten@gmail.com>:\n> 2011/8/21 Marcin Wiśnicki <mwisnicki@gmail.com>:\n>> Is it possible to merge files after performing directory renames in such\n>> way that new files will end up in renamed directories ?\n>>\n>> For example:\n>> 1. [master]  add dir1/file1\n>> 2. [branch1] branch from master\n>> 3. [branch1] add dir1/file2\n>> 4. [master]  rename dir1 to dir2\n>> 5. [master]  merge branch1\n>>\n>> Where it should notice that dir1=>dir2 and therefore {dir1=>dir2}/file2.\n>>\n>> Currently I end up with dir1/file2 which is undesirable as it breaks\n>> refactorings and requires a lot of manual effort to clean-up.\n>\n> Part of the assumption for someone working on `branch1' might be that\n> `dir1/file2' is in fact in `dir1'. The rename via `master' conflicts\n> with that assumption. In this case, a full-blown conflict might be\n> useful.\n>\n> However, suppose that the author who is working with `master' doesn't\n> need `dir1', but the author who is working with `branch1' does need it\n> INDEPENDENTLY:\n>\n>  1. [master]  add dir2/file1\n>  2. [branch1] branch from master\n>  3. [branch1] add dir1/file2\n>  4. [master]  add dir1/file3\n>  5. [master]  rename dir1/file3 to dir3/file3\n>  6. [master]  merge branch1\n>\n> In that case, you'd want `dir1/file2' from the `branch1' work to be\n> silently created rather than automatically renamed to `dir3/file3'.\n> This should not result in a conflict or a rename.\n>\n> So, from your grievance, I suppose that git currently assumes the\n> latter case (and hence, gives no indication of a possible conflict).\n> Perhaps git could be improved here at least in terms of a warning.\n> Perhaps the merger could request that directory renames be considered\n> conflicts or enforced, but this would have to involve the intent of\n> the merger me thinks (using command line flags).\n\nImportantly, note that I used only file names in my example, specifically:\n\n  5. [master]  rename dir1/file3 to dir3/file3\n\nrather than mirroring your example by writing:\n\n  5. [master]  rename dir1 to dir3\n\nThis is because git fundamentally tracks content, and paths are just\none kind of content associated with another blob of content.\nConsequently, git really knows next to nothing about directories, so\nit's not too surprising that git doesn't bother finding such a\nDIRECTORY rename anyway (at most, git would detect a FILE rename, and\nyour FILE `dir1/file2' has nothing to do with, say, the FILE\n`dir1/file1' being renamed `dir2/file1').\n\nStill, some command line switches could be useful to help the user\nexpress to git what should be going on in a case such as yours.\n"},{"id":"173983","messageId":"j2s83l$eqg$1@dough.gmane.org","threadId":"28183","inReplyTo":"CAMOZ1Bt8cP146xiDXfSA-naSOaS3AC8pUZgW12=3TMg2JGCD=w@mail.gmail.com","subject":"Re: Merge after directory rename ?","fromName":"Marcin Wiśnicki","fromEmail":"mwisnicki@gmail.com","sentAt":"2011-08-22T00:32:54Z","receivedAt":"2011-08-22T00:32:54Z","isPatch":false,"sender":{"key":"mwisnicki@gmail.com","avatar":"https://gravatar.com/avatar/6bc6cce46e549217fe39b05ac03acb4f5755154d6752ff65b580783365ad3e50?d=mp&s=160"},"body":"On Sun, 21 Aug 2011 23:53:34 +0000, Michael Witten wrote:\n> Importantly, note that I used only file names in my example,\n> specifically:\n> \n>   5. [master]  rename dir1/file3 to dir3/file3\n> \n> rather than mirroring your example by writing:\n> \n>   5. [master]  rename dir1 to dir3\n> \n> This is because git fundamentally tracks content, and paths are just one\n> kind of content associated with another blob of content. Consequently,\n\nI know it tracks content, yet it puts effort to detect file renames.\nI want it to also detect directory renames, detecting it should be quite \neasy.\n\n> git really knows next to nothing about directories, so it's not too\n> surprising that git doesn't bother finding such a DIRECTORY rename\n> anyway (at most, git would detect a FILE rename, and your FILE\n> `dir1/file2' has nothing to do with, say, the FILE `dir1/file1' being\n> renamed `dir2/file1').\n> \n> Still, some command line switches could be useful to help the user\n> express to git what should be going on in a case such as yours.\n\nI would prefer it to be fully automatic :)\nOr at least detect/warn about tree conflict.\nDirectory renames can happen quite frequently when working with Java/C# \nand it is unreasonable to expect that lazy user will have to keep track of \nit manually (with huge number of files it's impossible).\n"},{"id":"173989","messageId":"CAMOZ1Bsb7UxYOFpRWh47+130upfD9_E=CMQtZd1NyUWPwWiW4A@mail.gmail.com","threadId":"28183","inReplyTo":"j2s83l$eqg$1@dough.gmane.org","subject":"Re: Merge after directory rename ?","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2011-08-22T02:19:05Z","receivedAt":"2011-08-22T02:19:05Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"2011/8/22 Marcin Wiśnicki <mwisnicki@gmail.com>:\n> On Sun, 21 Aug 2011 23:53:34 +0000, Michael Witten wrote:\n>> Importantly, note that I used only file names in my example,\n>> specifically:\n>>\n>>   5. [master]  rename dir1/file3 to dir3/file3\n>>\n>> rather than mirroring your example by writing:\n>>\n>>   5. [master]  rename dir1 to dir3\n>>\n>> This is because git fundamentally tracks content, and paths are just one\n>> kind of content associated with another blob of content. Consequently,\n>\n> I know it tracks content, yet it puts effort to detect file renames.\n> I want it to also detect directory renames, detecting it should be quite\n> easy.\n>\n>> git really knows next to nothing about directories, so it's not too\n>> surprising that git doesn't bother finding such a DIRECTORY rename\n>> anyway (at most, git would detect a FILE rename, and your FILE\n>> `dir1/file2' has nothing to do with, say, the FILE `dir1/file1' being\n>> renamed `dir2/file1').\n>>\n>> Still, some command line switches could be useful to help the user\n>> express to git what should be going on in a case such as yours.\n>\n> I would prefer it to be fully automatic :)\n\nI assume the smiley is tongue-in-cheek; however, in case it is not: It\ncan't be automatic in general; did my examples mean nothing?\n\n> Or at least detect/warn about tree conflict.\n\nDid my examples mean nothing?\n\n> Directory renames can happen quite frequently when working with Java/C#\n> and it is unreasonable to expect that lazy user will have to keep track of\n> it manually (with huge number of files it's impossible).\n\nGit doesn't know anything about Java/C#; that's the point.\n\nIn general, the user could make use of switches (as suggested). In\nparticular, perhaps there are merge hooks or merge drivers that could\nbe used or implemented for allowing a more environment-specific\nhandling of merges, a la GNU's ChangeLog merge driver:\n\n  http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/git-merge-changelog.c\n\nAlso, see the configuration section of `git help merge'. Also look at\nthe tool `git mergetool'.\n"},{"id":"174004","messageId":"CAC9GOO8w_zZ8wuRambnGoaS+rKskdjuSZVpF+b4mzdhzK48bjg@mail.gmail.com","threadId":"28183","inReplyTo":"CAMOZ1Bsb7UxYOFpRWh47+130upfD9_E=CMQtZd1NyUWPwWiW4A@mail.gmail.com","subject":"Re: Merge after directory rename ?","fromName":"Marcin Wiśnicki","fromEmail":"mwisnicki@gmail.com","sentAt":"2011-08-22T08:49:18Z","receivedAt":"2011-08-22T08:49:18Z","isPatch":false,"sender":{"key":"mwisnicki@gmail.com","avatar":"https://gravatar.com/avatar/6bc6cce46e549217fe39b05ac03acb4f5755154d6752ff65b580783365ad3e50?d=mp&s=160"},"body":"2011/8/22 Michael Witten <mfwitten@gmail.com>:\n> I assume the smiley is tongue-in-cheek; however, in case it is not: It\n> can't be automatic in general; did my examples mean nothing?\n>\n>> Or at least detect/warn about tree conflict.\n>\n> Did my examples mean nothing?\n\nWell kind of. Your example was different because you have created dir1\nindependently on branch1 and master in which case automatic rename\nwouldn't be expected. If you would've created dir1 before branching\nand renamed dir1 to dir3 (renamed all files under dir1) then I would\nexpect a rename while merging.\n\nThe exact behaviour of merging branch1 to master I want is:\n\nlet base = $(git merge-base master branch1)\nfor each {modified,added,deleted} file in $base..branch1:\n  let dir = $(dirname $file)\n  if $dir exists in master:\n    if $dir existed in $base: [1]\n      proceed\n    else: # both branches independently introduced same directory\n      tree conflict\n  else: # no $dir in master\n    if $dir existed in $base:\n      if all $dir/* files in $base..master were renamed to $newdir/*:\n        rename $file [s/$dir/$newdir/]\n      else: # $dir was removed\n        tree conflict\n    else:\n       proceed # simple addition\n\nWhere \"$dir exists\" means that a file with path of matching prefix exists.\nBy default tree conflict should be ignored (proceed with merge as\ntoday) but user should be able to make it fatal.\n\n[1] It would be better if instead of comparing two trees it would\nanalyze each commit independently to detect shadowed renames:\n(dir1=>dir2 then new dir1) => still rename.\n\n>\n>> Directory renames can happen quite frequently when working with Java/C#\n>> and it is unreasonable to expect that lazy user will have to keep track of\n>> it manually (with huge number of files it's impossible).\n>\n> Git doesn't know anything about Java/C#; that's the point.\n\nAnd it shouldn't. Renames can happen with anything, I'm just pointing\nout that they are quite frequent in Java/C#.\nYou might as well have a C project and rename directory \"src\" to\n\"sources\" and, when merging branch created from before that, expect to\nget automatic s/src/sources/.\n\n> In general, the user could make use of switches (as suggested). In\n> particular, perhaps there are merge hooks or merge drivers that could\n> be used or implemented for allowing a more environment-specific\n> handling of merges, a la GNU's ChangeLog merge driver:\n> Also, see the configuration section of `git help merge'. Also look at\n> the tool `git mergetool'.\n>\n\nMerge drivers are file type specific, mergetool is used to resolve\nconflicts after merge and I don't see a pre-merge hook :(\n"},{"id":"174090","messageId":"CAMOZ1BtY=-F555pKtNWbNgRt_T-V5mtQE9dxTk-MQzhgNBuQXw@mail.gmail.com","threadId":"28183","inReplyTo":"CAC9GOO8w_zZ8wuRambnGoaS+rKskdjuSZVpF+b4mzdhzK48bjg@mail.gmail.com","subject":"Re: Merge after directory rename ?","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2011-08-23T14:50:33Z","receivedAt":"2011-08-23T14:50:33Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"2011/8/22 Marcin Wiśnicki <mwisnicki@gmail.com>:\n> Well kind of. Your example was different because you have created dir1\n> independently on branch1 and master in which case automatic rename\n> wouldn't be expected. If you would've created dir1 before branching\n> and renamed dir1 to dir3 (renamed all files under dir1) then I would\n> expect a rename while merging.\n\nI already covered this case in my initial paragraph. Good Luck!\n"},{"id":"174111","messageId":"20110823191350.GA4016@sigill.intra.peff.net","threadId":"28183","inReplyTo":"CAMOZ1Bt8cP146xiDXfSA-naSOaS3AC8pUZgW12=3TMg2JGCD=w@mail.gmail.com","subject":"Re: Merge after directory rename ?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-08-23T19:13:50Z","receivedAt":"2011-08-23T19:13:50Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Aug 21, 2011 at 11:53:34PM +0000, Michael Witten wrote:\n\n> This is because git fundamentally tracks content, and paths are just\n> one kind of content associated with another blob of content.\n> Consequently, git really knows next to nothing about directories, so\n> it's not too surprising that git doesn't bother finding such a\n> DIRECTORY rename anyway (at most, git would detect a FILE rename, and\n> your FILE `dir1/file2' has nothing to do with, say, the FILE\n> `dir1/file1' being renamed `dir2/file1').\n> \n> Still, some command line switches could be useful to help the user\n> express to git what should be going on in a case such as yours.\n\nFYI, Yann Dirson was working on some patches to detect directory\nrenames, but we haven't heard anything for a while. The last version I\ncould find was:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/163328\n\n-Peff\n"}]}