From: Linus Torvalds Date: Mon, 21 Nov 2005 18:37:10 GMT Subject: Re: Pure renames/copies Message-ID: In-Reply-To: <87hda61a80.fsf@gmail.com> On Mon, 21 Nov 2005, Santi Béjar wrote: > > Is there any way to ask git to find pure renames or copies? Not directly, but git sure makes it easy for you. Do this: git-diff-tree -r old..new | grep '^:[^]*0000000000000000000000000000000000000000' and you'll get all the information (that "" is obviously the tab character) you need to efficiently do it (or, if you want to just do one commit, just do "git-diff-tree -r cmit"). In the git tree, commit 0086e2c854e3af3209915e4ec2f933bcef400050 can act as a good example of this: the output of git-diff-tree -r 0086e2c854e3af3209915e4ec2f933bcef400050 is 0086e2c854e3af3209915e4ec2f933bcef400050 :100644 100644 328b399f9fe6e2b668691ab359319f50561cd773 16a8af63f0523cec82faa23f29cee579ac224e82 M .gitignore :100644 000000 a8cc5739d7851da3aeca2388d74eb92c464f1732 0000000000000000000000000000000000000000 D Documentation/git-lost+found.txt :000000 100644 0000000000000000000000000000000000000000 03156f218bb41b955779207ec2e94120f958fc45 A Documentation/git-lost-found.txt :100644 100644 a9d47c115c071694321d076af8a73a06ddd46875 1c32dd5be7156ae0e1142523fe50d84745964793 M Documentation/git.txt :100644 100644 b75cb137875b3cdb8746d2e0135e6f2743e2046a 5b2eca897386e17021d2a8a052b0c2759df96447 M Makefile :100755 000000 3892f52005d1e36676681806a87ef35dc0689f22 0000000000000000000000000000000000000000 D git-lost+found.sh :000000 100755 0000000000000000000000000000000000000000 3892f52005d1e36676681806a87ef35dc0689f22 A git-lost-found.sh and then after the "grep", you have just :100644 000000 a8cc5739d7851da3aeca2388d74eb92c464f1732 0000000000000000000000000000000000000000 D Documentation/git-lost+found.txt :000000 100644 0000000000000000000000000000000000000000 03156f218bb41b955779207ec2e94120f958fc45 A Documentation/git-lost-found.txt :100755 000000 3892f52005d1e36676681806a87ef35dc0689f22 0000000000000000000000000000000000000000 D git-lost+found.sh :000000 100755 0000000000000000000000000000000000000000 3892f52005d1e36676681806a87ef35dc0689f22 A git-lost-found.sh left, which shows you the new and the deleted files. Then, look for renames: just match up a new file that has the same SHA1 as a deleted file, and you can see that the change from "git-lost+found.sh" to "git-lost-found.sh" was exactly such an exact rename, because they share the 3892f52005d1e36676681806a87ef35dc0689f22 SHA1. After rename detection, look at any remaining new files (in the above example, only :000000 100644 0000000000000000000000000000000000000000 03156f218bb41b955779207ec2e94120f958fc45 A Documentation/git-lost-found.txt would be left), and try to match up the SHA1 of that file with the result of "git-ls-tree -r $old", ie something like git-ls-tree -r 0086e2c854e3af3209915e4ec2f933bcef400050^ | grep 03156f218bb41b955779207ec2e94120f958fc45 which in this case is empty (that new file wasn't an exact copy of any old file, it was a rename+edit, of course). Very efficient, very simple, you can do it either with a small shell-script (using cut + sort + join + grep), or write a specialized tool around the git-diff-tree logic. Of course, arguably "-M100" should really do this optimization for you. Junio? Linus