Consider that a file (1.c) contains three functions and changes made by authors M and J. If someone runs git blame 1.c
, he will get the following output:
^869c699 (M 2012-09-25 14:05:31 -0600 1)
de24af82 (J 2012-09-25 14:23:52 -0600 2)
de24af82 (J 2012-09-25 14:23:52 -0600 3)
de24af82 (J 2012-09-25 14:23:52 -0600 4) public int add(int x, int y) {
de24af82 (J 2012-09-25 14:23:52 -0600 5) int z = x+y;
de24af82 (J 2012-09-25 14:23:52 -0600 6) return z;
de24af82 (J 2012-09-25 14:23:52 -0600 7) }
de24af82 (J 2012-09-25 14:23:52 -0600 8)
^869c699 (M 2012-09-25 14:05:31 -0600 9) public int multiplication(int y, int z){
^869c699 (M 2012-09-25 14:05:31 -0600 10) int result = y*z;
^869c699 (M 2012-09-25 14:05:31 -0600 11) return temp;
^869c699 (M 2012-09-25 14:05:31 -0600 12) }
^869c699 (M 2012-09-25 14:05:31 -0600 13)
^869c699 (M 2012-09-25 14:05:31 -0600 14) public void main(){
de24af82 (J 2012-09-25 14:23:52 -0600 15) //this is a comment
de24af82 (J 2012-09-25 14:23:52 -0600 16) }
Now, if author A changes the position of the multiplication()
and add()
functions and commits the changes, git blame
can detect the code movement. See following output:
$ git blame -C -M e4672cf82 1.c
^869c699 (M 2012-09-25 14:05:31 -0600 1)
de24af82 (J 2012-09-25 14:23:52 -0600 2)
de24af82 (J 2012-09-25 14:23:52 -0600 3)
e4672cf8 (M 2012-09-25 14:26:39 -0600 4)
de24af82 (J 2012-09-25 14:23:52 -0600 5)
^869c699 (M 2012-09-25 14:05:31 -0600 6) public int multiplication(int y, int z){
^869c699 (M 2012-09-25 14:05:31 -0600 7) int result = y*z;
^869c699 (M 2012-09-25 14:05:31 -0600 8) return temp;
^869c699 (M 2012-09-25 14:05:31 -0600 9) }
^869c699 (M 2012-09-25 14:05:31 -0600 10)
^869c699 (M 2012-09-25 14:05:31 -0600 11) public void main(){
de24af82 (J 2012-09-25 14:23:52 -0600 12) //this is a comment
e4672cf8 (M 2012-09-25 14:26:39 -0600 13) }
de24af82 (J 2012-09-25 14:23:52 -0600 14) public int add(int x, int y){
de24af82 (J 2012-09-25 14:23:52 -0600 15) int z = x+y;
de24af82 (J 2012-09-25 14:23:52 -0600 16) return z;
e4672cf8 (M 2012-09-25 14:26:39 -0600 17) }
However, if I try to run git diff
between these two revisions, it cannot detect that functions change their location and gives the following output:
$ git diff -C -M de24af8..e4672cf82 1.c
diff --git a/1.c b/1.c
index 5b1fcba..56b4430 100644
--- a/1.c
+++ b/1.c
@@ -1,10 +1,7 @@
-public int add(int x, int y){
- int z = x+y;
- return z;
-}
+
public int multiplication(int y, int z){
int result = y*z;
@@ -13,4 +10,8 @@ public int multiplication(int y, int z){
public void main(){
//this is a comment
-}
\ No newline at end of file
+}
+public int add(int x, int y){
+ int z = x+y;
+ return z;
+}
\ No newline at end of file
My questions are:
How can I enforce detecting code movement in getting diff output? Is it even possible?
Git diff can be applied with several options. For example --minimal
, --patience
. How can I apply those options here? I tried with one, but get the following error:
$ git diff --minimal de24af8..e4672cf82 1.c
usage: git diff <options> <rev>{0,2} -- <path>*
Can anyone suggest/give sample example how to add these options correctly?
As of Git 2.15, git diff
now supports detection of moved lines with the --color-moved
option. It even detects moves between files.
It works, obviously, for colorized terminal output. As far as I can tell, there is no option to indicate moves in plain text patch format, but that makes sense.
For default behavior, try
git diff --color-moved
The command also takes options, which currently are no
, default
, plain
, zebra
and dimmed_zebra
(Use git help diff
to get the latest options and their descriptions). For example:
git diff --color-moved=zebra