Git Tip of the Day – detect moved files

When you rename your files in your project, git may display that as removing and adding the file. Let’s see a demo.

Let’s prepare a commit where we rename a file:

$ mv foo bar
$ git add -A
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	renamed:    foo -> bar
#
$ git commit -m 'improve naming'
[master 80d5850] improve naming
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename foo => bar (100%)

Now let’s show the default behavior of git:

$ git show
commit 80d5850fa16ecc783fa86a1d474c4324ec9f4c2d
Author: Kamil Páral
Date:   Wed Aug 3 13:49:01 2011 +0200

    improve naming

diff --git a/bar b/bar
new file mode 100644
index 0000000..4e4b354
--- /dev/null
+++ b/bar
@@ -0,0 +1,2 @@
+this is a
+sample file
diff --git a/foo b/foo
deleted file mode 100644
index 4e4b354..0000000
--- a/foo
+++ /dev/null
@@ -1,2 +0,0 @@
-this is a
-sample file

You will get the same output with git diffgit format-patch or git log -p. Basically the whole file is removed and added back again in another location. This is not great, because if the file has 1000 lines, then it will really clutter your view. There is a better approach:

$ git show -M
commit 80d5850fa16ecc783fa86a1d474c4324ec9f4c2d
Author: Kamil Páral
Date:   Wed Aug 3 13:49:01 2011 +0200

    improve naming

diff --git a/foo b/bar
similarity index 100%
rename from foo
rename to bar

We shortened the output to 4 simple lines. You see that similarity index is 100%, that means the files are the same, just at different locations (i.e. with different names). The similarity index can be lower, that means git can detect even files that changed a little during the move. The threshold can be set as an argument to the -M option.

If you use this option for patch creation, you may get a much shorter patches that are much more readable. The disadvantage? They are no longer “standard” patches that can be applied with patch command, you must use git to do that.


Flattr this

4 thoughts on “Git Tip of the Day – detect moved files

  1. And git won’t store it more effectively. It will just store it as you wouldn’t provide that option.

    But smaller patch is definitely nicer.

    1. Remember git doesn’t store patches, just file contents. If the contents stay the same, it won’t store anything new in any case.

Leave a Reply (Markdown syntax supported)