{"thread":{"id":"7316","subject":"Rename handling","startedAt":"2007-03-19T16:10:25Z","lastAt":"2007-03-22T03:53:51Z","messageCount":31,"participants":["John Goerzen","Steven Grimm","Nicolas Pitre","Linus Torvalds","Andy Parkins","Daniel Barkalow","Robin Rosenberg","Martin Langhoff","Junio C Hamano","Jakub Narebski","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"37518","messageId":"slrnevtdfh.v0v.jgoerzen@katherina.lan.complete.org","threadId":"7316","inReplyTo":null,"subject":"Rename handling","fromName":"John Goerzen","fromEmail":"jgoerzen@complete.org","sentAt":"2007-03-19T16:10:25Z","receivedAt":"2007-03-19T16:10:25Z","isPatch":false,"sender":{"key":"jgoerzen@complete.org","avatar":null},"body":"Hi,\n\nI've read the FAQ and Linus' philosophy on this topic, and have some\nquestions still.  I'm considering using Git and its philosophy on\nrenames is troubling me.\n\nMy use for version control presently has most changes being written and\ncommitted by me directly, with occasional patches coming in from random\nothers.  As such, running something like 'git mv' when a rename occurs\nis not a problem.\n\nMy main concerns with Git are:\n\n1) git log does not show complete history of files that have been\n   renamed or copied.\n\n   If I have foo.txt, and rename it to bar.txt, the liberal use of -M\n   can tease out a proper patch from a number of places.  But\n   git log bar.txt, with any set of options I can possibly come up with,\n   absolutely refuses to show me the history of bar.txt before it was\n   renamed to bar.txt.  git log foo.txt also does not show me the old\n   history for the file.\n\n2) For me, a rename is a logical change to the source tree that I want\n   to be recorded with absolute certainty, not guessed about later.\n   Sometimes I may make API changes and it is useful to see how module\n   names changed, with complete precision, later.  I do not want to be\n   victim to an incorrect guess, which could be possible.\n\nIs there any way to resolve this with Git, or do I basically have to\nstick with Mercurial here?\n\n-- John\n"},{"id":"37529","messageId":"45FED31B.8070307@midwinter.com","threadId":"7316","inReplyTo":"slrnevtdfh.v0v.jgoerzen@katherina.lan.complete.org","subject":"Re: Rename handling","fromName":"Steven Grimm","fromEmail":"koreth@midwinter.com","sentAt":"2007-03-19T18:14:51Z","receivedAt":"2007-03-19T18:14:51Z","isPatch":false,"sender":{"key":"koreth@midwinter.com","avatar":"https://gravatar.com/avatar/71b4d2e8b62f168bdc9e9205341159e3567003b4f9e2127c617c5fa0a1f5bad2?d=mp&s=160"},"body":"John Goerzen wrote:\n> 2) For me, a rename is a logical change to the source tree that I want\n>    to be recorded with absolute certainty, not guessed about later.\n>    Sometimes I may make API changes and it is useful to see how module\n>    names changed, with complete precision, later.  I do not want to be\n>    victim to an incorrect guess, which could be possible.\n>   \n\nIf you commit your renames separately from your content changes, it'll \nbe unambiguous and you won't have to worry about it. That's what I \nusually do when this is a concern and it has yet to break for me.\n\nOn the other hand, I agree with your general point; I really don't like \nbeing uncertain about whether renames are going to come out correctly or \nnot (\"it has always worked before\" and \"it is by design unable to fail\" \nare two very different things.) In particular, I strongly disagree with \nthe \"names are just syntactic sugar, it's the content we're tracking\" \nphilosophy. Here's a simple example of why:\n\n#include <xyz.h>\n\nThat simple statement is an intermingling of content and namespace. The \npresence of something like that actually breaks the \"commit the rename \nseparately\" approach -- if you rename xyz.h to something else and commit \njust that rename, that revision won't compile, and I *really* don't like \nintentionally committing broken revisions.\n\nOkay, so you say, rename xyz.h and update the references to it, but \ndon't actually modify it. Fine, that works in this case. Now how about \nthis one:\n\npublic abstract class Foo {\n    private static Logger logger = Logger.getLogger(Foo.class.getName());\n}\n\nThe references to the name \"Foo.java\" in that case are within the file \nitself (assuming you're using a Java compiler that requires the filename \nand class name to match, which the common ones do.) You can't change \njust the references without changing the file you're renaming. And, \ndepending on how many self-references there are in this file, it's \nanyone's guess whether the content-based rename detection will consider \nthe renamed file to be close enough to the old one to be a probable rename.\n\nCombine renames with major code refactoring where the content changes \nsubstantially, and all bets are off.\n\nNow, having said all that, I'll argue in favor of the content-based \nrename support for a moment. It is extremely cool that git will actually \ndetect renames in third-party packages where you've just untarred a new \nrelease into your git repository and committed it, but have given git no \nhints at all about the nature of the content changes. I'm not aware of \nany other version control system that'll do that, and I've taken \nadvantage of that feature in the past. So by no stretch am I saying that \ncontent-based rename detection is worthless.\n\nBut I would sure rest a lot easier if \"git mv\" would record a \"the user \nrenamed this file\" entry in some log somewhere and the merge code would \nsee that entry and say, \"aha, no need to guess at it, file X got renamed \nto Y.\" Bonus points if that record could apply to directories too, so \nyou don't have the \"I created a new file in a directory you renamed, and \nafter git-pull my file is still sitting by itself in the old directory\" \nbug. If no such record exists, then the current rename code should still \nbe invoked to work its considerable magic.\n\nSo to answer your question, in my opinion if 100% guaranteed renames are \nhigh on your priority list, then Mercurial might be the better option \nfor now. In practice, I've found that git's 99+% rename detection has \nyet to fail on me aside from the above directory renaming case, but at \nthe end of the day it *is* guessing at your renames after the fact.\n\nOkay, git gurus, show me no mercy. :)\n\n-Steve\n"},{"id":"37530","messageId":"alpine.LFD.0.83.0703191427140.18328@xanadu.home","threadId":"7316","inReplyTo":"45FED31B.8070307@midwinter.com","subject":"Re: Rename handling","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-03-19T18:35:03Z","receivedAt":"2007-03-19T18:35:03Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Mon, 19 Mar 2007, Steven Grimm wrote:\n\n> So to answer your question, in my opinion if 100% guaranteed renames are high\n> on your priority list, then Mercurial might be the better option for now. In\n> practice, I've found that git's 99+% rename detection has yet to fail on me\n> aside from the above directory renaming case, but at the end of the day it\n> *is* guessing at your renames after the fact.\n> \n> Okay, git gurus, show me no mercy. :)\n\nWell...  the fact that you _still_ use GIT even in the face of a 1% \nprobability that it might guess renames wrong (according to your own \nnumbers) should mean that you didn't felt switching to Mercurial was \nworth the 100% guarantee for rename identification.\n\nAnd some will argue that explicit renames are susceptible to user error \nmisidentifying the rename too, certainly in the 1% figure of all renames \nif not more.\n\nSo maybe, just maybe, at the end of the day getting renames right 100% \nof the time instead of 99% is not such a big thing after all.\n\n\nNicolas\n"},{"id":"37531","messageId":"Pine.LNX.4.64.0703191145530.6730@woody.linux-foundation.org","threadId":"7316","inReplyTo":"alpine.LFD.0.83.0703191427140.18328@xanadu.home","subject":"Re: Rename handling","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-19T18:48:34Z","receivedAt":"2007-03-19T18:48:34Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 19 Mar 2007, Nicolas Pitre wrote:\n> \n> And some will argue that explicit renames are susceptible to user error \n> misidentifying the rename too, certainly in the 1% figure of all renames \n> if not more.\n\nIt's much worse than that. I will *guarantee* that renames are missed when \nthey come in as traditional patches, for example. That's a 100% error rate \nright there, not some \"1%\" one.\n\nAnd even if people never make mistakes, and people *only* use the native \nSCM \"rename\" functions, I guarantee that the downsides of thinking that \nfiles have identities is still much much bigger than the upsides. We've \nalready shown that the git \"blame\" functionality is strictly more powerful \nthan anything based on renames.\n\nSo learn to love the bomb. Rename tracking is *wrong*. \n\n\t\tLinus\n"},{"id":"37532","messageId":"200703191903.20005.andyparkins@gmail.com","threadId":"7316","inReplyTo":"45FED31B.8070307@midwinter.com","subject":"Re: Rename handling","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-03-19T19:03:17Z","receivedAt":"2007-03-19T19:03:17Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"On Monday 2007, March 19, Steven Grimm wrote:\n\n> On the other hand, I agree with your general point; I really don't\n> like being uncertain about whether renames are going to come out\n> correctly or not (\"it has always worked before\" and \"it is by design\n\nI agree with you, but I think that git does exactly what you want.  In \nfact I think git is better.\n\nThe beauty of git figuring out renames for itself is that git can figure \nit out later. \n\n $ mv file1 file2\n $ git update-index --remove file1\n $ git add file2\n\nThe important thing here is that git wasn't used to do the move.  This \nis great when you're lost in a development haze and do the move without \nthinking.\n\n> So to answer your question, in my opinion if 100% guaranteed renames\n> are high on your priority list, then Mercurial might be the better\n> option for now. In practice, I've found that git's 99+% rename\n> detection has yet to fail on me aside from the above directory\n> renaming case, but at the end of the day it *is* guessing at your\n> renames after the fact.\n\nIt's not really a guess; through the magic of sha-1, and provided you \nare disciplined enough to commit the rename without any changes to the \ncontent you can be sure that the rename is tracked.  The sha-1 /must/ \nbe the same before and after.  For this 100% case, git doesn't even \nneed the \"-M\", git-blame, git-diff and git-merge will find it anyway.\n\nEven better is that because the rename isn't recorded explicitly when \nyou upgrade git and the detection gets better, all your history \ninstantly gets interpreted correctly.\n\nThe only command I've found that doesn't do the \"right thing\" by default \nis git-log and I think that once the following works, all the \"why \ndoesn't git track renames\" people will go quietly away:\n\n $ git init\n $ date > file1\n $ git add file1\n $ git commit -m \"\"\n $ git mv file1 file2\n $ git commit -m \"\"\n $ git mv file2 file3\n $ git commit -m \"\"\n $ git log -- file3\n\n\n\n\nAndy\n-- \nDr Andy Parkins, M Eng (hons), MIET\nandyparkins@gmail.com\n"},{"id":"37533","messageId":"Pine.LNX.4.64.0703191425560.6485@iabervon.org","threadId":"7316","inReplyTo":"45FED31B.8070307@midwinter.com","subject":"Re: Rename handling","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-03-19T19:15:11Z","receivedAt":"2007-03-19T19:15:11Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 19 Mar 2007, Steven Grimm wrote:\n\n> John Goerzen wrote:\n> > 2) For me, a rename is a logical change to the source tree that I want\n> >    to be recorded with absolute certainty, not guessed about later.\n> >    Sometimes I may make API changes and it is useful to see how module\n> >    names changed, with complete precision, later.  I do not want to be\n> >    victim to an incorrect guess, which could be possible.\n> >   \n> \n> If you commit your renames separately from your content changes, it'll be\n> unambiguous and you won't have to worry about it. That's what I usually do\n> when this is a concern and it has yet to break for me.\n> \n> On the other hand, I agree with your general point; I really don't like being\n> uncertain about whether renames are going to come out correctly or not (\"it\n> has always worked before\" and \"it is by design unable to fail\" are two very\n> different things.) In particular, I strongly disagree with the \"names are just\n> syntactic sugar, it's the content we're tracking\" philosophy.\n\nWe are tracking the names as part of the content. They're right there in \nthe tree objects. It's not like, when you check out an older revision, you \ncould get the right content under the wrong name. The philosophy is \nactually that we're tracking a series of states, and we're somewhat \nagnostic on the description of the difference between two states. And it \noften makes sense to postpone trying to describe this difference until you \nknow why you want to know, because it's certainly possible that there are \nmultiple reasonable interpretations, and some may give better results than \nothers.\n\nIf you're trying to merge a rename-and-refactor change (often something \nlike splitting a source or header file into two files) with a \nmodification, and it's arguable what happened in the refactor, the \ninterpretation which gives the state that's easiest to resolve correctly \nmay depend on what the modification is. So you really want to leave it up \nto the merge code to choose the best guess at the result, without using a \nfixed description of what the changes are.\n\nAs for whether names or contents \"matter more\", we have both answers. \"git \nlog <names>\" gives you the history of what has happened to change what \nappears with those names. \"git blame <name>\", on the other hand, gives you \nthe history of the content which now appears at that name. You just need \nto ask the question you want the answer to.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"37535","messageId":"45FEE2B2.6050904@midwinter.com","threadId":"7316","inReplyTo":"200703191903.20005.andyparkins@gmail.com","subject":"Re: Rename handling","fromName":"Steven Grimm","fromEmail":"koreth@midwinter.com","sentAt":"2007-03-19T19:21:22Z","receivedAt":"2007-03-19T19:21:22Z","isPatch":false,"sender":{"key":"koreth@midwinter.com","avatar":"https://gravatar.com/avatar/71b4d2e8b62f168bdc9e9205341159e3567003b4f9e2127c617c5fa0a1f5bad2?d=mp&s=160"},"body":"Andy Parkins wrote:\n> It's not really a guess; through the magic of sha-1, and provided you \n> are disciplined enough to commit the rename without any changes to the \n> content you can be sure that the rename is tracked.  The sha-1 /must/ \n> be the same before and after.  For this 100% case, git doesn't even \n> need the \"-M\", git-blame, git-diff and git-merge will find it anyway.\n>   \n\nI said as much in my mail. The problem is that \"commit the rename \nwithout any changes to the content\" is synonymous in many cases with \n\"commit a revision that fails to compile.\" Which may or may not be \nacceptable in some environments but is, to me at least, a sign that \nsomething is inadequate in the version control system. I shouldn't be \nforced to have a broken build in my revision history just to be 100% \ncertain my rename will be tracked accurately.\n\n> The only command I've found that doesn't do the \"right thing\" by default \n> is git-log and I think that once the following works, all the \"why \n> doesn't git track renames\" people will go quietly away:\n>\n>  $ git init\n>  $ date > file1\n>  $ git add file1\n>  $ git commit -m \"\"\n>  $ git mv file1 file2\n>  $ git commit -m \"\"\n>  $ git mv file2 file3\n>  $ git commit -m \"\"\n>  $ git log -- file3\n>   \n\nThe following is actually my biggest beef with git's rename tracking, \nand it has nothing whatsoever to do with git-log (though I agree git-log \nneeds to track renames too):\n\n$ ls\ndir1\n$ ls dir1\nfile1 file2 file3\n$ echo \"#include file1\" > dir1/file4\n$ git add dir1/file4\n$ git commit\n$ git pull\n$ ls\ndir1 dir2\n$ ls dir1\nfile4\n$ ls dir2\nfile1 file2 file3\n\nThat's just plain broken in my opinion. One can perhaps contrive a test \ncase or two where that's the desired behavior, but in the real world it \nis almost never what you actually want.\n\nBy the way, I don't think fixing that is necessarily related to how \nrenames get detected, so in some sense it's a different bug report / \nfeature request than the rename hints one. It would be possible to \nfigure out the directory had been renamed based purely on content \nanalysis; a bunch of files all individually renamed to the same places \nunder a new directory, and a lack of any files at all left in the old \none, probably means the directory got renamed. The content-based rename \ndetector could handle this case.\n\n-Steve\n"},{"id":"37536","messageId":"45FEE629.8030606@midwinter.com","threadId":"7316","inReplyTo":"alpine.LFD.0.83.0703191427140.18328@xanadu.home","subject":"Re: Rename handling","fromName":"Steven Grimm","fromEmail":"koreth@midwinter.com","sentAt":"2007-03-19T19:36:09Z","receivedAt":"2007-03-19T19:36:09Z","isPatch":false,"sender":{"key":"koreth@midwinter.com","avatar":"https://gravatar.com/avatar/71b4d2e8b62f168bdc9e9205341159e3567003b4f9e2127c617c5fa0a1f5bad2?d=mp&s=160"},"body":"Nicolas Pitre wrote:\n> Well...  the fact that you _still_ use GIT even in the face of a 1% \n> probability that it might guess renames wrong (according to your own \n> numbers) should mean that you didn't felt switching to Mercurial was \n> worth the 100% guarantee for rename identification.\n>   \n\nYes, that's right, for me that's the correct tradeoff. For the person \nwho asked the original question, it may or may not be. He seemed a lot \nmore worried about the situation than I am. In my environment renames \nare relatively rare events, but maybe in his they happen more often.\n\n> And some will argue that explicit renames are susceptible to user error \n> misidentifying the rename too, certainly in the 1% figure of all renames \n> if not more.\n>   \n\nIf you're using \"git mv\" instead of \"mv\" to do the rename, it is \nimpossible to misidentify the rename since the rename and identification \nare happening in the same command with no additional inputs that could \nconfuse anything. If you are talking about adding a new tool that can \nmanually tag a rename after the fact, then I can't disagree with you \nexcept to say that the fact that no such command exists today means any \nestimate of user error rate is pure speculation.\n\nAside from that, the possibility of user error is an entirely different \nthing than the possibility of tool error -- if I misidentify a rename, I \nwill blame myself, not the version control system, and rightly so. \nPeople are expected to make mistakes from time to time. But if my \nversion control tool misidentifies a rename on my behalf, and there's \nnothing I can do about it because there's no way to influence the tool's \nconcept of what got renamed to what, then I'm not going to consider it a \nfailure of the tool, not a mistake on my part.\n\n> So maybe, just maybe, at the end of the day getting renames right 100% \n> of the time instead of 99% is not such a big thing after all.\n>   \n\nFor me personally, that is true -- but I'd still prefer that extra 1%.\n\n-Steve\n"},{"id":"37537","messageId":"45FEE869.3040308@midwinter.com","threadId":"7316","inReplyTo":"45FEE629.8030606@midwinter.com","subject":"Re: Rename handling","fromName":"Steven Grimm","fromEmail":"koreth@midwinter.com","sentAt":"2007-03-19T19:45:45Z","receivedAt":"2007-03-19T19:45:45Z","isPatch":false,"sender":{"key":"koreth@midwinter.com","avatar":"https://gravatar.com/avatar/71b4d2e8b62f168bdc9e9205341159e3567003b4f9e2127c617c5fa0a1f5bad2?d=mp&s=160"},"body":"Steven Grimm wrote:\n> But if my version control tool misidentifies a rename on my behalf, \n> and there's nothing I can do about it because there's no way to \n> influence the tool's concept of what got renamed to what, then I'm not \n> going to consider it a failure of the tool, not a mistake on my part.\n\nErr, then I am *going* to consider it a failure of the tool.\n\n-Steve\n"},{"id":"37542","messageId":"slrnevtqaq.1df.jgoerzen@katherina.lan.complete.org","threadId":"7316","inReplyTo":"45FED31B.8070307@midwinter.com","subject":"Re: Rename handling","fromName":"John Goerzen","fromEmail":"jgoerzen@complete.org","sentAt":"2007-03-19T19:49:46Z","receivedAt":"2007-03-19T19:49:46Z","isPatch":false,"sender":{"key":"jgoerzen@complete.org","avatar":null},"body":"On 2007-03-19, Steven Grimm <koreth@midwinter.com> wrote:\n> John Goerzen wrote:\n>> 2) For me, a rename is a logical change to the source tree that I want\n>>    to be recorded with absolute certainty, not guessed about later.\n>>    Sometimes I may make API changes and it is useful to see how module\n>>    names changed, with complete precision, later.  I do not want to be\n>>    victim to an incorrect guess, which could be possible.\n>>   \n>\n> If you commit your renames separately from your content changes, it'll \n> be unambiguous and you won't have to worry about it. That's what I \n> usually do when this is a concern and it has yet to break for me.\n\nAs I have been testing Mercurial and its addremove feature (which does\nbasically what Git is doing), I encountered some situations where\nthis broke, sometimes spectacularly.  This generally happened when there\nwere identical files in the source tree, or when there were identical\nresulting files, or 0-byte files (the extreme pathological case, of\ncourse).\n\nAgain, sometimes filenames have significance.  The presence or absence\nof 0-byte files can impact what make does, for instance.  Not that I\nadvocate for this behavior, but just pointing out that it exists.\n\nI understand what Linus is saying about applying patches from others and\nagree that what git is doing is nice in this case.\n\nBut if most of my work is hacking directly on the code, I am going to\nknow better than the VCS what is being renamed, and would like to record\nthat.  Sometimes the filenames are part of the code.\n\nI want the option.\n\n-- John\n"},{"id":"37539","messageId":"45FEEB0C.3080602@midwinter.com","threadId":"7316","inReplyTo":"Pine.LNX.4.64.0703191145530.6730@woody.linux-foundation.org","subject":"Re: Rename handling","fromName":"Steven Grimm","fromEmail":"koreth@midwinter.com","sentAt":"2007-03-19T19:57:00Z","receivedAt":"2007-03-19T19:57:00Z","isPatch":false,"sender":{"key":"koreth@midwinter.com","avatar":"https://gravatar.com/avatar/71b4d2e8b62f168bdc9e9205341159e3567003b4f9e2127c617c5fa0a1f5bad2?d=mp&s=160"},"body":"Linus Torvalds wrote:\n> It's much worse than that. I will *guarantee* that renames are missed when \n> they come in as traditional patches, for example. That's a 100% error rate \n> right there, not some \"1%\" one.\n>   \n\nThat's an argument that the content-based rename detector is valuable \nand shouldn't be ditched, a sentiment with which I completely agree. It \nis a fabulous piece of work and handles cases that none of git's \ncompetitors get right, such as patches or tracking upstream \ndistributions or tracking renames made by non-git-aware tools.\n\nHowever, \"Should we keep the existing rename detection?\" is not the same \nquestion as, \"Should the user be able to tell the system he's renaming \nsomething?\" Or rather, given we already have git mv, \"Should the system \nremember that the user has told it he's renaming something?\" Right now \ngit is throwing away metadata the user is feeding to it, metadata that \ncould be used to eliminate the chance of a subsequent failure. As long \nas that metadata is used in *addition* to the existing logic, rather \nthan as a *replacement*, the downside seems minimal. You won't have it \nin the case of a patch, granted, but that just means patches will use \nthe existing, almost-always-right, rename detection, no harm done.\n\n> So learn to love the bomb. Rename tracking is *wrong*. \n>   \n\nUntil someone comes up with a way to make content-based rename detection \n100% foolproof in the face of things like frequent self-references in \nJava or C++ classes, it may be a necessary evil (or at least a \nworthwhile one.)\n\n-Steve\n"},{"id":"37540","messageId":"200703192102.20258.robin.rosenberg.lists@dewire.com","threadId":"7316","inReplyTo":"Pine.LNX.4.64.0703191145530.6730@woody.linux-foundation.org","subject":"Re: Rename handling","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg.lists@dewire.com","sentAt":"2007-03-19T20:02:19Z","receivedAt":"2007-03-19T20:02:19Z","isPatch":false,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"måndag 19 mars 2007 19:48 skrev Linus Torvalds:\n> \n> On Mon, 19 Mar 2007, Nicolas Pitre wrote:\n> > \n> > And some will argue that explicit renames are susceptible to user error \n> > misidentifying the rename too, certainly in the 1% figure of all renames \n> > if not more.\n> \n> It's much worse than that. I will *guarantee* that renames are missed when \n> they come in as traditional patches, for example. That's a 100% error rate \n> right there, not some \"1%\" one.\n> \n> And even if people never make mistakes, and people *only* use the native \n> SCM \"rename\" functions, I guarantee that the downsides of thinking that \n> files have identities is still much much bigger than the upsides. We've \n> already shown that the git \"blame\" functionality is strictly more powerful \n> than anything based on renames.\n> \n> So learn to love the bomb. Rename tracking is *wrong*. \n> \n> \t\tLinus\n\nHow about this simple receipe for defeating rename tracking (real world):\n\nUser needs to modify A. User renames A to OLD_A within his/her IDE. SCM\nrecords the rename. User now uses SaveAs to restore A, and SCM detects the \n*NEW* file A.\n\n-- robin\n"},{"id":"37541","messageId":"Pine.LNX.4.64.0703191259420.6730@woody.linux-foundation.org","threadId":"7316","inReplyTo":"45FEE869.3040308@midwinter.com","subject":"Re: Rename handling","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-19T20:07:45Z","receivedAt":"2007-03-19T20:07:45Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 19 Mar 2007, Steven Grimm wrote:\n> \n> Err, then I am *going* to consider it a failure of the tool.\n\nSure.\n\nAnd then realize that nothing is perfect.\n\nGit is just *closer* to perfect than any other SCM out there. That doesn't \nmean that you can never find cases where you consider it failed. It just \nmeans that it fails less than the alternatives.\n\nTo be perfect, an SCM would have to be able to infer a higher meaning. Who \nknows - maybe that will happen in a few centuries (or decades, but AI has \nnot had a good track-record so far). \n\nGit tracks exactly the stuff that does *not* require it to infer higher \nmeanings - purely data. I personally consider it one of gits greatest \nstrengths: it never matters *how* you get to some state, or what tools you \nused (patches, imports from other SCM's, \"git mv\" with intelligent \ndevelopers, \"git mv\" with total clutzes, \"plain mv\", random monkeys \ntyping, whatever). Git tracks not \"intent\", but \"hard data\".\n\nThe fact that git then can use that unambiguous hard data to show you \ninteresting patterns is a big deal. But you need to realize that it's an \neven *bigger* deal that git only traffics in hard data that leaves \nabsolutely no room for mistakes.\n\nGit simply doesn't *care* whether you applied a patch to create the \nrename, or whether you imported the series from a system that doesn't \ntrack renames, or whether you just forgot to do \"git mv\". You should be \nreally really happy about that. \n\nBtw, the reason -M isn't on by default is not that it's more expensive in \nCPU-time (it is, but quite frankly, you will never really see that effect \nin practice). No, the real reason is that if you use \"-M\" and actually see \nrenames, traditional tools no longer understand the patches. And sadly, \nthere are still too many unwashed and ignorant people out there to make \nthe default patch format be git-specific.\n\nWhen the revolution comes, and we can shoot everybody who uses anything \nelse, we'll turn -M on by default.  Don't despair, comrade!\n\n\t\tLinus\n"},{"id":"37543","messageId":"alpine.LFD.0.83.0703191608340.18328@xanadu.home","threadId":"7316","inReplyTo":"45FEE629.8030606@midwinter.com","subject":"Re: Rename handling","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-03-19T20:17:12Z","receivedAt":"2007-03-19T20:17:12Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Mon, 19 Mar 2007, Steven Grimm wrote:\n\n> Nicolas Pitre wrote:\n> > And some will argue that explicit renames are susceptible to user error\n> > misidentifying the rename too, certainly in the 1% figure of all renames if\n> > not more.\n> >   \n> \n> If you're using \"git mv\" instead of \"mv\" to do the rename, it is impossible to\n> misidentify the rename since the rename and identification are happening in\n> the same command with no additional inputs that could confuse anything.\n\nI was actually referring to someone using cp + rm + {svn|hg|whatever} to \ncommit a rename in which case the tool won't know.  And I'm sure that \nhappens more than 1% of the time.\n\n> If you\n> are talking about adding a new tool that can manually tag a rename after the\n> fact, then I can't disagree with you except to say that the fact that no such\n> command exists today means any estimate of user error rate is pure\n> speculation.\n\nSure.  \n\n> Aside from that, the possibility of user error is an entirely different thing\n> than the possibility of tool error -- if I misidentify a rename, I will blame\n> myself, not the version control system, and rightly so. People are expected to\n> make mistakes from time to time. But if my version control tool misidentifies\n> a rename on my behalf, and there's nothing I can do about it because there's\n> no way to influence the tool's concept of what got renamed to what, then I'm\n> not going to consider it a failure of the tool, not a mistake on my part.\n\nBut GIT's rename heuristics can be modified/improved, and all renames \nthat were wrongly identified before will suddenly be fixed.\n\nIf the rename is part of the recorded history then there is nothing you \ncan do to fix mistakes, be it human or tool based.\n\n> > So maybe, just maybe, at the end of the day getting renames right 100% of\n> > the time instead of 99% is not such a big thing after all.\n> >   \n> \n> For me personally, that is true -- but I'd still prefer that extra 1%.\n\nI'm sure the human screwups is at _least_ in the 1% range.  So even if \nyou think you should know better, being a human you'll make a mistake \neventually so you won't have that 100% anyway.\n\n\nNicolas\n"},{"id":"37544","messageId":"46a038f90703191319y54251f63ldc6060ffbc89deea@mail.gmail.com","threadId":"7316","inReplyTo":"45FEEB0C.3080602@midwinter.com","subject":"Re: Rename handling","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2007-03-19T20:19:11Z","receivedAt":"2007-03-19T20:19:11Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On 3/20/07, Steven Grimm <koreth@midwinter.com> wrote:\n> However, \"Should we keep the existing rename detection?\" is not the same\n> question as, \"Should the user be able to tell the system he's renaming\n> something?\"\n\nHow is a $SCM-mv that remembers useful in any _interesting_ scenario?\nYou don't move it just because, you refactor and re-architect\nsomething.\n\nIn that area, git's mergers still have a bit to go -- I do hope for a\nday when I can say git-merge -s refactor or just git-merge -s\ntryharder so that it if hunks don't apply, git will try and trace\nwhere the block of code the hunk applies to has gone.\n\nSo recording mv doesn't solve anything other than 1% of the cases --\nthose full file moves that git will discover anyway even if the file\nchanged a bit. And recording the mv gives you a false sense of being\nuseful. It's not.\n\nThere's more work in having\ngo-slow-and-really-try-to-merge-across-a-refactor mergers that could\nat least hint at where the hunk is likely to belong now.\n\n> Until someone comes up with a way to make content-based rename detection\n> 100% foolproof in the face of things like frequent self-references\n\nWell, if code changes, there are no guarantees. Patching is a\nbest-effort-but-not-too-smart thing. But in the end, a human needs to\nlook at it if it's tricky. Wiggle users know ;-)\n\nAnd, at the end of the day, hitting programmers that move sh*t around\nneedlessly in the head works too. You wouldn't let them change\nprojectwide function/method name conventions willy nilly either.\n\ncheers,\n\n\nmartin\n"},{"id":"37545","messageId":"Pine.LNX.4.64.0703191308130.6730@woody.linux-foundation.org","threadId":"7316","inReplyTo":"45FEEB0C.3080602@midwinter.com","subject":"Re: Rename handling","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-19T20:22:26Z","receivedAt":"2007-03-19T20:22:26Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 19 Mar 2007, Steven Grimm wrote:\n> \n> Until someone comes up with a way to make content-based rename detection 100%\n> foolproof in the face of things like frequent self-references in Java or C++\n> classes, it may be a necessary evil (or at least a worthwhile one.)\n\nTry to implement it. Trust me, it will suck so badly that you'll realize \nthat I am right.\n\nFile identities have *huge* problems. They are a total nightmare to \nimplement well, and you'd lose a lot of the really good features that git \nhas. But I suspect it's not worth trying to convince you. You really need \nto just try to do it.\n\nI can name some of the problems:\n\n - you get a whole new source of really fundamentally nasty merge \n   conflicts that are really fundmanentally hard to handle.\n\n   I have first-hand experience, and I realize that lots of people simply \n   don't even *understand* the problems. But take it from me - having two \n   different repositories create the same file independently (which is not \n   at all uncommon - patches flying around make it really easy) - is the \n   tip of a very nasty iceberg.\n\n   Git makes merges easy in comparison. Trying to track file ID's is a \n   huge gaping hole, leading to hell. I doubt you'll find an SCM that does \n   it, and does it well.\n\n   (Side note: in a *centralized* setup, with no branches, this isn't a \n   problem. But with branches it already becomes a nastier issue, and when \n   decentralized you simply cannot avoid it at all).\n\n   End result: merges suck. Unless you're smart, and use git.\n\n - The end result depends on the path you took to get there. You're going \n   to have a really hard time re-creating things exactly, and doing so \n   from patches (which is *the* most common way actual real development \n   gets done) is basically impossible. So you end up with the meaning \n   getting lost along the way (or being added), and now where is your \n   \"trustworthy\" file movement logic?\n\nI've seen both problems with BK. Bitkeeper had a nice patch application \ngraphical toolkit to help some of these issues. It was really nice, but it \nwas still *painful*. Not having it would be a total disaster. Except if \nyou simply don't need it - like git.\n\nThe merges in particular is something that git just DOES BETTER than \nanybody else. The lack of explicit file ID information means that you can \njust fix up the conflicts in the working tree using perfectly normal \ntools, and never have to do anything special with special \"merge tools\". \n\nYou may still want to use nice graphical tools to help you, of course, but \nthey aren't even git-specific any more. See the whole discussion about \nvisual merge tools recently, and \"git mergetool\", and using a random tool \nto do the merge. Realize that IF FILE IDENTITIES MATTER, none of this \nworks. Suddenly, you need to have special tools that resolve the file \nidentity problem (never mind the fact that quite often there *is* no \nideal resolution and \"resolving\" it ends up being \"pick one of the other, \nand live with it forever\").\n\nIn other words, you live in a dream-world where you know you'd like to \ntell the SCM what the rename is, but at the same time you don't really \nrealize what the problems with that is downstream. You think it's a great \nthing, because you've not thought the consequences through (which is \nunderstandable - they are subtle, and the main reason I know them is (a) \nI'm just special. My mother told me so! and (b) I've used SCM's that do \nit about as well as you can, and I've hit the problems).\n\n\t\tLinus\n"},{"id":"37549","messageId":"Pine.LNX.4.64.0703191323490.6730@woody.linux-foundation.org","threadId":"7316","inReplyTo":"200703192102.20258.robin.rosenberg.lists@dewire.com","subject":"Re: Rename handling","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-19T20:34:27Z","receivedAt":"2007-03-19T20:34:27Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Mon, 19 Mar 2007, Robin Rosenberg wrote:\n> \n> How about this simple receipe for defeating rename tracking (real world):\n> \n> User needs to modify A. User renames A to OLD_A within his/her IDE. SCM\n> records the rename. User now uses SaveAs to restore A, and SCM detects the \n> *NEW* file A.\n\nWell, the thing is, I don't think that's a very strong argument against \nrename tracking.\n\nYou can always make trivial examples of when something goes wrong. \nComputers (and SCM's) are stupid, and they simply do what they are told. \nJust about *any* policy can be trivially show to be \"totally broken\" by \nhaving a user do something - usually something very simple - that breaks \nit on purpose.\n\nSimilarly, I don't think it's hard to show examples of where git's \n\"content is king\" does something that the user thinks could be done much \nbetter. And similarly, I don't think that's an argument against the \ncontent model that git uses.\n\nNo, the reason I like the content model is that there is never any hidden \nstate that doesn't matter for the user. If you're a physicist, you could \nsay that yhere is never any \"action at a distance\" with git. There are no \nhidden linkages that aren't obvious in the source tree that you commit or \nwork on.\n\nIn contrast, the very *definition* of \"explicit rename tracking\" is to \ntrack those hidden linkages. They aren't visible to the developer, except \nwhen they clash, and that very invisibility is what makes both mistakes so \neasy (anybody who claims that they never do a rename as a del/add pair is \nsimply lying or not doing very interesting development) *and* it is what \nmakes handling merges so hard (because when there is a conflict, the \nconflict isn't actually in anything that is *visible*!).\n\nI also pretty much guarantee that the reason git development has been so \nfast, stable and trouble-free comes exactly from the simple conceptual \nmindset and very concrete implementation. There simply are never any \nsubtle issues. Content is content is content. It has no \"history\". Yes, \ngit shows history, but it's literally a \"series of snapshots\", and the \ntrees that are checked out are totally history-less. \n\nIn contrast, if you have file rename tracking, then those trees are no \nlonger stateless - they have an implied history associated with them, that \nmatters. It's largely *invisible*, but that just makes it worse!\n\n\t\t\tLinus\n"},{"id":"37550","messageId":"Pine.LNX.4.64.0703191628100.6485@iabervon.org","threadId":"7316","inReplyTo":"45FEE629.8030606@midwinter.com","subject":"Re: Rename handling","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-03-19T20:44:57Z","receivedAt":"2007-03-19T20:44:57Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 19 Mar 2007, Steven Grimm wrote:\n\n> Nicolas Pitre wrote:\n> > So maybe, just maybe, at the end of the day getting renames right 100% of\n> > the time instead of 99% is not such a big thing after all.\n> \n> For me personally, that is true -- but I'd still prefer that extra 1%.\n\nI think the discussion of 99% is misleading here. The heuristics aren't \nrandom; it's not like if you do 2000 renames, you can expect 20 of them to \nbe mishandled. What's actually going on is that git will get 100% on \nunambiguous cases; it'll get 100% on slight ambiguities; it'll get 100% on \nmostly clear cases. On the ~2% of cases where the correct result is \narguable, git will choose differently from you half of the time. If you do \na rename and have to change most of the lines of the file, git might \ndecide that you rewrote it from scratch. On the other hand, you might have \nhad an easier time rewriting it from scratch. Even more extreme, if you \nuse git-mv to rename a file, and then you totally replace the file with \nsome other content, git will treat it as a remove and an add, rather than \na rename and a total rewrite. But making it a remove and an add is the \nsensible interpretation of the change, anyway.\n\nI'd actually guess that git's analysis is at least as likely to be useful \nas the reference human analysis that the 1% error rate is measured \nagainst.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"37554","messageId":"7vmz28g98o.fsf@assigned-by-dhcp.cox.net","threadId":"7316","inReplyTo":"slrnevtqaq.1df.jgoerzen@katherina.lan.complete.org","subject":"Re: Rename handling","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-19T22:27:03Z","receivedAt":"2007-03-19T22:27:03Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"John Goerzen <jgoerzen@complete.org> writes:\n\n> But if most of my work is hacking directly on the code, I am going to\n> know better than the VCS what is being renamed, and would like to record\n> that.  Sometimes the filenames are part of the code.\n>\n> I want the option.\n\nThis depends on what you want to do with that recorded rename.\n\nLet's say you renamed foo.py to bar.py, but the content changed\nso much while you renamed the file that it is no longer similar\nenough for the default similarity threshold to consider them a\nrenamed pair.\n\nThen you run:\n\n\t$ git log bar.py\n\nand against your expectation, it says \"the history of that name\nends here --- you created this file at this point from zero\".\n\nNow, what would you do at this point, of course after an\nobligatory \"f*ck, stupid tool\" cussing?\n\nYou would do \"$ git show -M\" and you would not see the rename,\nbecause we are assuming that the similarity is smaller than the\ndefault threashold.\n\nBut it's your project and you know better than the tool.  You\nknow that bar.py used to be called foo.py.  So you can do:\n\n\t$ git diff $commit^:foo.py $commit:bar.py\n\nif you cared what huge change you did while renaming, and then\ncontinue digging from that point, perhaps with:\n\n\t$ git log $commit^ -- foo.py\n\nEarlier, I said \"you know better than the tool\", but that is a\nslight lie.  You probably knew better than the tool back when\nyou made that commit, but you cannot be better than any tool to\nremember that 10 years (or 6 months) after making that commit.\n\nThat's why you need to record somewhere you renamed foo.py to\nbar.py in this commit.\n\nWe happen to have a perfect place to record such a rename and it\nis called the commit log message.  If a rename matters *so* much\nto your project, you not only would want to record the fact that\nyou renamed it, but you would want to record *WHY*, and the\ncommit log message is the perfect place to do both.\n\nA single path being renamed is a special case of content\nmovement across file boundaries.  Pairwise diff that \"git log\n-p\" gives cannot express one file being split into two or two\nfile merged into one, and that is independent of explicitly\nrecorded rename or inferred one.  We already have a better\nsolution for that general problem and it is called git-blame.\n\nBy the way, blame is not perfect.  One thing I sometimes find\nlacking from it is that it only shows the final assignment of\nthe blame.  Often, a development goes like (1) code evolves in\ntwo or more different files, (2) at one point somebody goes in\nand cleans things up to move the duplicated code from these\nfiles and consolidate into one file, (3) and the refactored\nresults gets polished further, drastically changing.  Many\ntimes, step (2), especially when done by a competent person, is\ndone carefully not to change the logic of the code to avoid\nregression, and lines from that revision does not appear in the\nend result of the blame.\n\nThis is good when the reason why you are reading the blame\noutput is to figure out *why* a block of lines in the current\ncode is written that way (you do not care about the\nrestructuring history, but care more about the origin of the\ncode and the reasoning behind why it is that way), but when\ndoing archaeology sometimes I wish what happened in step (2) can\nalso be shown a bit more prominently in the final output.\n"},{"id":"37607","messageId":"7vfy8071qm.fsf@assigned-by-dhcp.cox.net","threadId":"7316","inReplyTo":"46a038f90703191319y54251f63ldc6060ffbc89deea@mail.gmail.com","subject":"Re: Rename handling","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-03-20T08:33:53Z","receivedAt":"2007-03-20T08:33:53Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Martin Langhoff\" <martin.langhoff@gmail.com> writes:\n\n> In that area, git's mergers still have a bit to go -- I do hope for a\n> day when I can say git-merge -s refactor or just git-merge -s\n> tryharder so that it if hunks don't apply, git will try and trace\n> where the block of code the hunk applies to has gone.\n\nLet's say Oliver creates this project with a single file,\nfrotz.c.\n\n-- >8 -- Oliver:frotz.c -- >8 --\n 1 struct frotz {\n 2     int nitfol;\n 3     int xyzzy;\n 4 };\n 5\n 6 int add_frotz(struct frotz *it)\n 7 {\n 8     return it->nitfol + it->xyzzy;\n 9 }\n-- 8< -- Oliver:frotz.c -- 8< --\n\nThen Alice and Bob forks this project, and makes their own\nmodification.\n\nAlice does this:\n\n-- >8 -- Alice:frotz.c -- >8 --\n 1 struct frotz {\n 2     int filfre;\n 3     int nitfol;\n 4     int xyzzy;\n 5 };\n 6\n 7 int add_frotz(struct frotz *it)\n 8 {\n 9     return it->filfre + it->nitfol + it->xyzzy;\n10 }\n-- 8< -- Alice:frotz.c -- 8< --\n\nwhile Bob does this:\n\n-- >8 -- Bob:frotz.h -- >8 --\n 1 #ifndef FROTZ_H\n 2 #define FROTZ_H\n 3\n 4 struct frotz {\n 5     int nitfol;\n 6     int xyzzy;\n 7 };\n 8 #endif /* FROTZ_H */\n-- 8< -- Bob:frotz.h -- 8< --\n-- >8 -- Bob:frotz.c -- >8 --\n 1 #include <frotz.h>\n 2\n 3 int add_frotz(struct frotz *it)\n 4 {\n 5     return it->nitfol + it->xyzzy;\n 6 }\n-- 8< -- Bob:frotz.c -- 8< --\n\nNow, Alice wants to merge the results of their efforts.\n\nThe \"perfect merge strategy\" (git-merge-blame) should be able to\ndetect the situation and ask Alice:\n\n\tOn Bob's branch, the original file \"frotz.c\" was split\n\tinto \"frotz.h\" and \"frotz.c\", while on your branch, the\n\tfile was not split.  Both branches changed the file(s).\n\n\tDo you want to take the split [Y/n]?\n\nWe can do this by blaming from Alice:frotz.c, Bob:frotz.c and\nBob:frotz.h down to Oliver (which is the common ancestor\ncommit).\n\nLet's say Alice likes the split and said yes.  Then, from the\n\"git-blame -C Bob -- frotz.h\" output, git-merge-blame should be\nable to figure out that this is what happened:\n\n    B:1 +#ifndef FROTZ_H\n    B:2 +#define FROTZ_H\n    B:3 +\nO:1 B:4  struct frotz {\nO:2 B:5     int nitfol;\nO:3 B:6     int xyzzy;\nO:4 B:7  };\n    B:8 +#endif /* FROTZ_H */\n\nSimilarly for \"git-blame -C Bob -- frotz.c\":\n\n    B:1 +#include <frotz.h>\nO:5 B:2  \nO:6 B:3  int add_frotz(struct frotz *it)\nO:7 B:4  {\nO:8 B:5      return it->nitfol + it->xyzzy;\nO:9 B:6  }\n\nand for \"git-blame -C Alice -- frotz.c\",\n\nO:1 A:1  struct frotz {\n    A:2 +    int filfre;\nO:2 A:3      int nitfol;\nO:3 A:4      int xyzzy;\nO:4 A:5  };\nO:5 A:6 \nO:6 A:7  int add_frotz(struct frotz *it)\nO:7 A:8  {\nO:8     -    return it->nitfol + it->xyzzy;\n    A:9 +    return it->filfre + it->nitfol + it->xyzzy;\nO:9 A:10 }\n\nLooking at this, and because Alice chose to take the file split\nBob made, the merge strategy can insert line A:2 between B:4 and\nB:5 to add filfre member to \"struct frotz\", and update B:5 with\nA:9.\n"},{"id":"37646","messageId":"etpson$qih$1@sea.gmane.org","threadId":"7316","inReplyTo":"45FEE2B2.6050904@midwinter.com","subject":"Re: Rename handling","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-03-21T00:06:33Z","receivedAt":"2007-03-21T00:06:33Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Steven Grimm wrote:\n\n> The following is actually my biggest beef with git's rename tracking, \n> and it has nothing whatsoever to do with git-log (though I agree git-log \n> needs to track renames too):\n> \n> $ ls\n> dir1\n> $ ls dir1\n> file1 file2 file3\n> $ echo \"#include file1\" > dir1/file4\n> $ git add dir1/file4\n> $ git commit\n> $ git pull\n> $ ls\n> dir1 dir2\n> $ ls dir1\n> file4\n> $ ls dir2\n> file1 file2 file3\n> \n> That's just plain broken in my opinion. One can perhaps contrive a test \n> case or two where that's the desired behavior, but in the real world it \n> is almost never what you actually want.\n> \n> By the way, I don't think fixing that is necessarily related to how \n> renames get detected, so in some sense it's a different bug report / \n> feature request than the rename hints one. It would be possible to \n> figure out the directory had been renamed based purely on content \n> analysis; a bunch of files all individually renamed to the same places \n> under a new directory, and a lack of any files at all left in the old \n> one, probably means the directory got renamed. The content-based rename \n> detector could handle this case.\n \nActually this came out in some earlier talk about recording renames \nand renames detection (IIRC in the big thread about VCS comparison which\nused to be on Bazaar-NG wiki). And one of the arguments about why directory\nrename doesn't work as _you_ expected is (beside that it is not that\neasy to code) the fact that the alternate solution (new files going\nto old subdir) can be correct and expected by _others_.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"37647","messageId":"etptkp$2uo$1@sea.gmane.org","threadId":"7316","inReplyTo":"slrnevtdfh.v0v.jgoerzen@katherina.lan.complete.org","subject":"Re: Rename handling","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-03-21T00:21:31Z","receivedAt":"2007-03-21T00:21:31Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"John Goerzen wrote:\n\n> I've read the FAQ and Linus' philosophy on this topic, and have some\n> questions still.  I'm considering using Git and its philosophy on\n> renames is troubling me.\n> \n> My use for version control presently has most changes being written and\n> committed by me directly, with occasional patches coming in from random\n> others.  As such, running something like 'git mv' when a rename occurs\n> is not a problem.\n> \n> My main concerns with Git are:\n> \n> 1) git log does not show complete history of files that have been\n>    renamed or copied.\n> \n>    If I have foo.txt, and rename it to bar.txt, the liberal use of -M\n>    can tease out a proper patch from a number of places.  But\n>    git log bar.txt, with any set of options I can possibly come up with,\n>    absolutely refuses to show me the history of bar.txt before it was\n>    renamed to bar.txt.  git log foo.txt also does not show me the old\n>    history for the file.\n\nThat is because \"bar.txt\" in \"git log bar.txt\" is not file name to show\nhistory of, but path limiter (BTW. it is not output filter, as it also\nsimplifies history). And you can say for example \"git log Documentation/\"\nwhich I guess is not available in any other SCM beside Git.\n\nThere were at least two attempts to provide a kind of --follow=<filename>\nto the git-log family of commands, to track/show history of a given file\nacross renames. See \"Why does git not track renames?\" entry in GitFaq\n(http://git.or.cz/gitwiki/GitFaq) for some history; lately Linus has\nsend prototype of blame engine based implementation of --follow option.\n\n> 2) For me, a rename is a logical change to the source tree that I want\n>    to be recorded with absolute certainty, not guessed about later.\n>    Sometimes I may make API changes and it is useful to see how module\n>    names changed, with complete precision, later.  I do not want to be\n>    victim to an incorrect guess, which could be possible.\n\nThis is much against Git philosophy of \"tracking contents\", although there\nwas talk allowing recording some optional _helper_ information about file\nrenames, in the proposed 'note' field (header) in commits, but it never\nmaterialized.\n\nYou can always say that there was rename (or that file was split into two,\nor that file was refactores) in the commit message.\n\nBesides, the place where you want renames detection to work is during\nmerge. I don't know what would happen if merge base is so far back that\ngit doesn't recognize rename; on the other hand you get huge conflict\nto resolve anyway.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"37649","messageId":"Pine.LNX.4.63.0703210120230.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7316","inReplyTo":"etpson$qih$1@sea.gmane.org","subject":"Re: Rename handling","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-21T00:25:42Z","receivedAt":"2007-03-21T00:25:42Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 21 Mar 2007, Jakub Narebski wrote:\n\n> Steven Grimm wrote:\n> \n> > The following is actually my biggest beef with git's rename tracking, \n> > and it has nothing whatsoever to do with git-log (though I agree git-log \n> > needs to track renames too):\n> > \n> > $ ls\n> > dir1\n> > $ ls dir1\n> > file1 file2 file3\n> > $ echo \"#include file1\" > dir1/file4\n> > $ git add dir1/file4\n> > $ git commit\n> > $ git pull\n> > $ ls\n> > dir1 dir2\n> > $ ls dir1\n> > file4\n> > $ ls dir2\n> > file1 file2 file3\n> > \n> > That's just plain broken in my opinion. One can perhaps contrive a test \n> > case or two where that's the desired behavior, but in the real world it \n> > is almost never what you actually want.\n> > \n> > By the way, I don't think fixing that is necessarily related to how \n> > renames get detected, so in some sense it's a different bug report / \n> > feature request than the rename hints one. It would be possible to \n> > figure out the directory had been renamed based purely on content \n> > analysis; a bunch of files all individually renamed to the same places \n> > under a new directory, and a lack of any files at all left in the old \n> > one, probably means the directory got renamed. The content-based rename \n> > detector could handle this case.\n>  \n> Actually this came out in some earlier talk about recording renames \n> and renames detection (IIRC in the big thread about VCS comparison which\n> used to be on Bazaar-NG wiki). And one of the arguments about why directory\n> rename doesn't work as _you_ expected is (beside that it is not that\n> easy to code) the fact that the alternate solution (new files going\n> to old subdir) can be correct and expected by _others_.\n\nBy now, there have been enough arguments _for_ automatic rename detection, \nbut I'll add another one.\n\nA colleague of mine worked on a certain file in a branch, where he copied \nthe file to another location, and heavily modified it. He did that in a \nbranch, and when he was satisfied with the result, he deleted the old \nfile, since he liked the new location better.\n\nNow, when I pulled, imagine my surprise (knowing the history of the file), \nwhen the pull reported a rename with a substantial similarity!\n\nSo, the automatic renamer did an awesome job.\n\nCiao,\nDscho\n\nP.S.: It would be so nice if somebody (preferably someone who previously \nthought manual renames were a pretty clever thing) to write up the \narguments, and add that to the \"why automatic renaming?\" section of the \nFAQ...\n \n"},{"id":"37702","messageId":"4601B199.9060300@midwinter.com","threadId":"7316","inReplyTo":"Pine.LNX.4.63.0703210120230.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Rename handling","fromName":"Steven Grimm","fromEmail":"koreth@midwinter.com","sentAt":"2007-03-21T22:28:41Z","receivedAt":"2007-03-21T22:28:41Z","isPatch":false,"sender":{"key":"koreth@midwinter.com","avatar":"https://gravatar.com/avatar/71b4d2e8b62f168bdc9e9205341159e3567003b4f9e2127c617c5fa0a1f5bad2?d=mp&s=160"},"body":"Johannes Schindelin wrote:\n> P.S.: It would be so nice if somebody (preferably someone who previously \n> thought manual renames were a pretty clever thing) to write up the \n> arguments, and add that to the \"why automatic renaming?\" section of the \n> FAQ...\n>   \n\nI completely understand the arguments in favor of automatic renaming. I \nhave never once advocated getting rid of it. It is useful and valuable \nand works well within its constraints.\n\nFor some reason whenever I try to argue that we need, IN ADDITION to the \nautomatic rename detection, a way to provide hints to the merge engine \nthat a non-auto-detectable rename has occurred, the responses I get back \nare mostly of the form, \"But the automatic rename detection handles all \nthese cases that wouldn't be handled with manual rename marking!\" It's \nas if one can either think autodetection is a good idea, or manual \nflagging is a good idea, but under no circumstances could they both be \ngood ideas at the same time. (As evidenced by the comment above about \n\"someone who previously thought manual renames were a pretty clever \nthing.\") But they are not in fact mutually exclusive.\n\nSay you're tracking a directory full of video files. Even a slight tweak \nto one of them (to put a logo in the corner, say, while moving it into \nan \"accessible by the public\" directory) will result in a file that has \nno content in common at all if you look at it as purely a stream of \nbytes. Short of decoding the thing to video frames and looking for \nsimilarities in the images, there's no way any merge tool will ever be \nable to tell the two versions are the same file unless the user \nindicates it. Any tool that saves its files in compressed form will have \na similar problem: unless git knows how to uncompress the tool's files, \na content comparison will often be useless to detect similarities.\n\nOf course, git actually does give you a way to mark renames manually: \ncommit them by themselves without changing the content. The problem is \nthat that overloads the \"record this snapshot of the tree for posterity\" \ncommand purely for the purpose of working around the merge tool's \ninability to detect the rename. If other people are like me, when they \nrecord a rename-only commit immediately followed by a content-change \ncommit on the same files, the intermediate state of the tree (with just \nthe renames) is not actually an interesting point in the history of the \nproject. It's not a revision in anything but an internal git sense. It \nprobably doesn't even compile or work correctly. It exists only because \nI'm forced to create it if I want to be 100% certain my renames will be \ntracked accurately. It is, in short, pollution in the history of my project.\n\nIt also means that if I want reliable renames, I can no longer impose \nthe requirement that my project be in a buildable state at each commit. \nThat doesn't seem like all that unreasonable a thing to want (but maybe \nit is?) -- I don't want to be in the situation where I say, e.g. \"git \ncheckout -b testbranch '@{1 day ago}'\" and get a broken working copy \nbecause I happened to do it at just the wrong time of day. But with the \n\"just commit your renames separately\" approach, that's exactly what can \nhappen.\n\nNow, once again, none of the above is an argument against the automatic \nrename detection. For cases where renames are automatically detectable, \nit works fine and will continue to do so, and in fact doesn't have the \nproblem of committing broken builds. I am not arguing it should be \nreplaced or that the user should be required to tell git about every \nrename. But the lack of an additional manual option forces me into a \nparticular workflow that I wouldn't otherwise use and prevents me from \nimposing the workflow rules I *do* want.\n\nHopefully that shed a little light on why I think manual rename support \nis not a totally idiotic idea.\n\n-Steve\n"},{"id":"37703","messageId":"Pine.LNX.4.63.0703212341020.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"7316","inReplyTo":"4601B199.9060300@midwinter.com","subject":"Re: Rename handling","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-03-21T23:01:54Z","receivedAt":"2007-03-21T23:01:54Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 21 Mar 2007, Steven Grimm wrote:\n\n> Johannes Schindelin wrote:\n> > P.S.: It would be so nice if somebody (preferably someone who \n> > previously thought manual renames were a pretty clever thing) to write \n> > up the arguments, and add that to the \"why automatic renaming?\" \n> > section of the FAQ...\n> \n> For some reason whenever I try to argue that we need, IN ADDITION to the \n> automatic rename detection, a way to provide hints to the merge engine \n> that a non-auto-detectable rename has occurred, the responses I get back \n> are mostly of the form, \"But the automatic rename detection handles all \n> these cases that wouldn't be handled with manual rename marking!\"\n\nNo. That's not the argument. The argument goes like this:\n\n\tWhatever solutions you choose to handle renames, it _will_ have \n\tproblems. We chose a solution which appears to have the least\n\tproblems.\n\n> Say you're tracking a directory full of video files. Even a slight tweak \n> to one of them (to put a logo in the corner, say, while moving it into \n> an \"accessible by the public\" directory) will result in a file that has \n> no content in common at all if you look at it as purely a stream of \n> bytes. Short of decoding the thing to video frames and looking for \n> similarities in the images, there's no way any merge tool will ever be \n> able to tell the two versions are the same file unless the user \n> indicates it.\n\nThat is a particularly bad example: you are not renaming files in that \nexample!\n\n> Of course, git actually does give you a way to mark renames manually: \n> commit them by themselves without changing the content. The problem is \n> that that overloads the \"record this snapshot of the tree for posterity\" \n> command purely for the purpose of working around the merge tool's \n> inability to detect the rename.\n\nNot at all. You are actually recording the rename. So, you proved that you \ndo have a method to record a rename manually.\n\n> It also means that if I want reliable renames, I can no longer impose \n> the requirement that my project be in a buildable state at each commit. \n> That doesn't seem like all that unreasonable a thing to want (but maybe \n> it is?) -- I don't want to be in the situation where I say, e.g. \"git \n> checkout -b testbranch '@{1 day ago}'\" and get a broken working copy \n> because I happened to do it at just the wrong time of day. But with the \n> \"just commit your renames separately\" approach, that's exactly what can \n> happen.\n\nHey, I might be wrong. Why don't you prove me wrong? Code talks.\n\nCiao,\nDscho\n"},{"id":"37704","messageId":"Pine.LNX.4.64.0703211607120.6730@woody.linux-foundation.org","threadId":"7316","inReplyTo":"Pine.LNX.4.63.0703212341020.22628@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: Rename handling","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-21T23:10:40Z","receivedAt":"2007-03-21T23:10:40Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 22 Mar 2007, Johannes Schindelin wrote:\n> \n> That is a particularly bad example: you are not renaming files in that \n> example!\n\nWell, yes and no.\n\nI would actually say that it si a particularly *good* example.\n\nWith git, you can actually record renames exactly this way: you just need \nto make sure that you don't change the content, and you make it two \nindependent commits.\n\nThat is in fact how some systems that support \"explicit renames\" actually \ndo it: the rename is literally a separate option, and cannot necessarily \ngo together with other actions (in particular, several file-ID-following \nsystems do not allow \"cross-renames\" in the same commit, for example, and \nyou actually have to do them as two separate commits).\n\nGit *allows* you to do renames with changes. In fact, I'd normally \nencourage it. But it doesn't force it, and then renames are totally \nunambiguos except for the case where you simply have the *same*file* in \nmultiple places, and you remove or add multiple copies (again, you can do \nthat unambiguously too, if you limit it to *one* such rename per commit)\n\n\t\tLinus\n"},{"id":"37707","messageId":"46a038f90703211710q168a691cpa282f8e2afc5c8a6@mail.gmail.com","threadId":"7316","inReplyTo":"4601B199.9060300@midwinter.com","subject":"Re: Rename handling","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2007-03-22T00:10:06Z","receivedAt":"2007-03-22T00:10:06Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On 3/22/07, Steven Grimm <koreth@midwinter.com> wrote:\n> Say you're tracking a directory full of video files. Even a slight tweak\n> to one of them (to put a logo in the corner, say, while moving it into\n> an \"accessible by the public\" directory) will result in a file that has\n> no content in common at all if you look at it as purely a stream of\n\nIn that case, tracking the rename is not useful at all from the POV of\nyour SCM. The  reason the SCM needs to understand content-movement (of\nwhich renames are a special type), it to help you as much as possible\nat merge time.\n\nSo - git as an SCM focusses on tracking your content, and helping you\nmerge. It does _that_ probably better than any other SCM. So git\ninternat data structures care strictly about the stuff that is needed\nfor git's operation as an SCM.\n\nAnd in the context of helping you merge, explicit rename tracking is a\nred-herring. This point is arguable - Linus said earlier \"you can do\nbetter by tracking content and ignoring explicit renames\" and we are\nnow getting there in terms of having code that does better.\n\nOf course in your case the fact that there was a rename is important\n-- for users. This kind of information is not metadata for the SCM but\nfor users. So that goes into the commit message, which is freeform. So\n- working with your scenario, if this happens often, I would suggest\nhaving a pre-commit hook that prepares a nice commit text message\nlisting likely renames if they can be sussed out automatically.\n\nOr having a custom git-mv that collects mv operations and then your\npre-commit-hook preps your commit message with that manifest of moved\nfiles.\n\nDoes it make sense? It is data-for-the-user, so it goes in the commit\nmsg. If it's data-for-the-SCM machinery, then it goes into the\ntracking data git handles internally.\n\ncheers,\n\n\nmartin\n"},{"id":"37710","messageId":"200703220301.41180.jnareb@gmail.com","threadId":"7316","inReplyTo":"46a038f90703211710q168a691cpa282f8e2afc5c8a6@mail.gmail.com","subject":"Re: Rename handling","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-03-22T02:01:39Z","receivedAt":"2007-03-22T02:01:39Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Martin Langhoff wrote:\n> On 3/22/07, Steven Grimm <koreth@midwinter.com> wrote:\n>>\n>> Say you're tracking a directory full of video files. Even a slight tweak\n>> to one of them (to put a logo in the corner, say, while moving it into\n>> an \"accessible by the public\" directory) will result in a file that has\n>> no content in common at all if you look at it as purely a stream of\n> \n> In that case, tracking the rename is not useful at all from the POV of\n> your SCM. The  reason the SCM needs to understand content-movement (of\n> which renames are a special type), it to help you as much as possible\n> at merge time.\n> \n> So - git as an SCM focusses on tracking your content, and helping you\n> merge. It does _that_ probably better than any other SCM. So git\n> internat data structures care strictly about the stuff that is needed\n> for git's operation as an SCM.\n> \n> And in the context of helping you merge, explicit rename tracking is a\n> red-herring. This point is arguable - Linus said earlier \"you can do\n> better by tracking content and ignoring explicit renames\" and we are\n> now getting there in terms of having code that does better.\n\nAdditional issue that we have to think about with respect to rename\nsupport for merges is that git uses 3-way merge, taking into account\n_only_ upstream commit (of the branch we want to merge to), side branch\ncommit (of the branch we want to merge) and common ancestor[*1*] \n(merge base) for merging. What is important is that the intermediate\nstates, how we got to the current state, does not matter.\n\nWell, one could argue that if we remember explicit (provided by user)\ninfo about renames for example in proposed 'note' field of a commit\nobject, or in other helper structure (we cannot remember the information\nin blob or tree), we can gather and remember information about recorded\nexplicit renames when finding common ancestor...\n\nAlthough I think it would be better and easier to just provide rerere2\ncache to git-rerere to record corrections to rename detection, and use\nit in subsequent merges (this was proposed, but IIRC not implemented)...\n\n> Of course in your case the fact that there was a rename is important\n> -- for users. This kind of information is not metadata for the SCM but\n> for users. So that goes into the commit message, which is freeform. So\n> - working with your scenario, if this happens often, I would suggest\n> having a pre-commit hook that prepares a nice commit text message\n> listing likely renames if they can be sussed out automatically.\n> \n> Or having a custom git-mv that collects mv operations and then your\n> pre-commit-hook preps your commit message with that manifest of moved\n> files.\n> \n> Does it make sense? It is data-for-the-user, so it goes in the commit\n> msg. If it's data-for-the-SCM machinery, then it goes into the\n> tracking data git handles internally.\n\nStill, it would be nice to have --follow=<file> option to git-log family,\nbesides path limiting. And this could have take use of explicit recording\nof renames (much easier than merge can).\n\n\nReferences\n==========\n[*1*] Well, it can be a bit more complicated if there is more than one\ncommon ancestor; git uses recursive merge strategy.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"37713","messageId":"46a038f90703211939j15dbda4cpfa2f49229b8c16cb@mail.gmail.com","threadId":"7316","inReplyTo":"200703220301.41180.jnareb@gmail.com","subject":"Re: Rename handling","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2007-03-22T02:39:38Z","receivedAt":"2007-03-22T02:39:38Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On 3/22/07, Jakub Narebski <jnareb@gmail.com> wrote:\n> Additional issue that we have to think about with respect to rename\n> support for merges is that git uses 3-way merge, taking into account\n> _only_ upstream commit (of the branch we want to merge to), side branch\n> commit (of the branch we want to merge) and common ancestor[*1*]\n> (merge base) for merging. What is important is that the intermediate\n> states, how we got to the current state, does not matter.\n>\n> Well, one could argue that if we remember explicit (provided by user)\n> info about renames for example in proposed 'note' field of a commit\n> object, or in other helper structure (we cannot remember the information\n> in blob or tree), we can gather and remember information about recorded\n> explicit renames when finding common ancestor...\n\nBut we do have some of that already - if one trees being merged is\nmissing a path that changed on the other one, we walk back on the\nancestry looking for renames.\n\nOr am I seeing things?\n\n> Still, it would be nice to have --follow=<file> option to git-log family,\n> besides path limiting.\n\n+1 here - git log should have something equivalent to diff's -M. When\nthe file \"disappears\", run a diff-tree -M -C against the parents to\nsee whether there were any \"related predecessors\" to the file to add\nto the pathspec. Of course, there could be more than one.\n\nFor example, right now, git log git-cvsimport.perl ends at the big tool rename.\n\ncheers,\n\n\nmartin\n"},{"id":"37714","messageId":"200703220432.27071.jnareb@gmail.com","threadId":"7316","inReplyTo":"46a038f90703211939j15dbda4cpfa2f49229b8c16cb@mail.gmail.com","subject":"Re: Rename handling","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-03-22T03:32:25Z","receivedAt":"2007-03-22T03:32:25Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Martin Langhoff wrote:\n> On 3/22/07, Jakub Narebski <jnareb@gmail.com> wrote:\n>> Additional issue that we have to think about with respect to rename\n>> support for merges is that git uses 3-way merge, taking into account\n>> _only_ upstream commit (of the branch we want to merge to), side branch\n>> commit (of the branch we want to merge) and common ancestor[*1*]\n>> (merge base) for merging. What is important is that the intermediate\n>> states, how we got to the current state, does not matter.\n>>\n>> Well, one could argue that if we remember explicit (provided by user)\n>> info about renames for example in proposed 'note' field of a commit\n>> object, or in other helper structure (we cannot remember the information\n>> in blob or tree), we can gather and remember information about recorded\n>> explicit renames when finding common ancestor...\n> \n> But we do have some of that already - if one trees being merged is\n> missing a path that changed on the other one, we walk back on the\n> ancestry looking for renames.\n> \n> Or am I seeing things?\n\nFirst, I was talking about hypotetical manually-provided helper information\nabout explicit renames, entered by user, not guessed by SCM.\n\nSecond, I have thought that rename detection is done on final states: upstream,\nbranch and ancestor, not on intermediate commits. I guess I thought wrong.\n \n-- \nJakub Narebski\nPoland\n"},{"id":"37715","messageId":"Pine.LNX.4.64.0703212047310.6730@woody.linux-foundation.org","threadId":"7316","inReplyTo":"200703220432.27071.jnareb@gmail.com","subject":"Re: Rename handling","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-03-22T03:53:51Z","receivedAt":"2007-03-22T03:53:51Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 22 Mar 2007, Jakub Narebski wrote:\n> \n> Second, I have thought that rename detection is done on final states: upstream,\n> branch and ancestor, not on intermediate commits. I guess I thought wrong.\n\nNo, you didn't think wrong, with a few caveats:\n\n - we *do* do intermediate commits occasionally (ie for the criss-cross \n   merge case and the \"recursive\" part of the merge strategy). But that's \n   strictly a \"we had multiple potential merge bases\" issue, not a \"track \n   renames through every commit\" kind of thing.\n\n - you should also see the 3-way merge as the *first* strategy. If it \n   fails, you could do more involved stuff (ie the \"blame\" merge \n   strategy).\n\nPersonally, I think the three-way merge (aka \"stupid\") is absolutely the \nright thing to do. SCM projects that always try to take intervening \ncommits into account (*cough*darcs*cough*) are just doing masturbation. \nIt's pointless. The history only matters as a \"what was the common state\" \nthing, the intermediate mistakes you did in between are meaningless.\n\nBut my point is that if you *wanted* to, you could do something fancy. I \nthink it would likely be stupid and wrong, and just cause subtle mismerges \nrather than actually *help*, but that's just my opinion. Git itself \ndoesn't *force* you to just take the end-points into account, although my \nopinion that they are the only things that matter certainly may have \ncolored how we do things right now ;)\n\n\t\t\tLinus\n"}]}