Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is "git" syntax for getting just the unified diff of how a single commit X changed a single file Y?

Tags:

git

I'm writing code to programmatically run git commands and learning git at the same time. Am I mis-reading the man pages or is what I want to do not doable?

The following will tell me how MYFILE changed between the two commits:

git diff COMMIT1..COMMIT2 -- MYFILE

Good.

But, let's say I just want to ask how COMMITX changed the file, without specifying the prior commit. In my imagination the syntax would be something like this:

git diff COMMITX -- MYFILE

or this:

git diff COMMITX^..COMMITX -- MYFILE

But the above commands don't work (for me).

The following works in the sense that it gives me the unified diff showing how that COMMITX changed MYFILE, but it also includes other stuff I have to strip out - like author, date, the checkin msg. Stripping out the extra stuff is easy, but it feels like it's something I shouldn't have to be doing. Does the command exist? Am I misunderstanding something simple?

git show COMMITX -- MYFILE

EDIT1: I'm showing here the actual output from my "git bash" window. I changed the "show" to "diff", and got no output.

$ git show 789e9 -- dir1/file3.txt
commit 789e948bce733dab9605bf8eb51584e3b9a2eba3
Author: corey 
Date:   Sun Oct 11 21:54:14 2009 -0500

    my msg

diff --git a/dir1/file3.txt b/dir1/file3.txt
index a351259..cf2bd35 100644
--- a/dir1/file3.txt
+++ b/dir1/file3.txt
@@ -4,5 +4,7 @@ c
 ddd
 e
 f
+a new line
+another new line
 g
 h

Administrator@BIOSTAR /c/temp/mygit (master)
$ git diff 789e9 -- dir1/file3.txt

Administrator@BIOSTAR /c/temp/mygit (master)
like image 249
Corey Trager Avatar asked Dec 17 '22 05:12

Corey Trager


1 Answers

Try:

git show --pretty=format: <commitid> -- <file>

Here's how it looks:

diff --git a/config.y b/config.y
index 7750514..f051b99 100644
--- a/config.y
+++ b/config.y
@@ -454,8 +454,8 @@ definegame : TYPE_DEFINE_GAME '{'
        }
        game_definitions '}'
        {
-           num_games = ncnf;
            ncnf++;
+           num_games = ncnf;
        }
        ;

There's still a single blank line at the start (not shown here due to markdown limitations), but patch will happily ignore that (indeed, it will ignore the header stuff in default git show output too). You can also pipe through tail -n +2 to drop said line.

--pretty=oneline is also useful:

3ed347de4c6e0e3230f651f82aabf964c6d16100 Fix a bug where more than one defined game didn't show up or showed gibberish
diff --git a/config.y b/config.y
index 7750514..f051b99 100644
--- a/config.y
+++ b/config.y
@@ -454,8 +454,8 @@ definegame : TYPE_DEFINE_GAME '{'
        }
        game_definitions '}'
        {
-           num_games = ncnf;
            ncnf++;
+           num_games = ncnf;
        }
        ;

That said, if you're formatting a patch for submission somewhere, don't strip off that stuff. In fact, use git format-patch and revel in it. Third-party patching tools will happily ignore that extra metadata, and for projects using git, git apply will use your provided commit message and author line, making it easy for them to apply it.

like image 143
bdonlan Avatar answered Jan 19 '23 00:01

bdonlan