tags:

views:

104

answers:

3

If I were to receive a patch file generated with something like git diff rev^ rev or even git show -p rev, how can I discover which commits are being diffed?

I'm not positive this use case is even relevant in git, but noting a file's path and/or revision numbers in the patch header included with cvs/svn give me a warm fuzzy that the patch that I have received, or created, is diffing against the correct source or revision.

Specifically, if we examine a git diff header:

diff --git a/lib/blueprint/semantic_class_names.rb b/lib/blueprint/semantic_class_names.rb
index 41bd496..c17af1d 100644
--- a/lib/blueprint/semantic_class_names.rb
+++ b/lib/blueprint/semantic_class_names.rb

I can find no distinguishing information about the commits involved in this diff. There is an index line, that I can only assume is not an abbreviated commit hash, but rather a hash of the diffed portions of the files. It certainly doesn't match the associated commit signatures.

If I diff a couple files, and decide to go old school with an emailed patch, is there no way for me to double-check quickly that I've diffed the right files/revisions before sending out the patch I made with a quick glance at the header? I understand that revisions aren't as meaningful in git as they are in cvs/svn due to the distributed nature, but am I the only one who wouldn't mind seeing at least the abbreviated commit signature of the files in the header?

+1  A: 

The hash provided in the diff is actually the hash for a blob.

As such, you can find the commits that contain the blob using the method provided in this question: Git: Which commit has this blob?

htanata
+1  A: 

If you use git show <rev>, (or git show -p <rev>), you get a patch that includes the commit identifier, along with the author, date, and commit message.

$ git show rel
commit 82bf5b5df1e0308939a6e91cf4c7d2dae8088d99
Author: Brian Campbell 
Date:   Thu Mar 5 14:00:54 2009 -0500

    Update another file

diff --git a/another b/another
index 2102854..4083e0c 100644
--- a/another
+++ b/another
@@ -1 +1,3 @@
 Yet another
+
+More lines
\ No newline at end of file

Patch utilities generally ignore extra stuff at the beginning of the patch, so the entire output of this should be valid to use as a patch. You can also use git format-patch to get something that is formatted to be easier to automatically send, using for instance git send-email or git imap-send.

As htanata points out, what you see in the diff header itself for the individual file is the blob identifier; while you can use that to find revisions it could have come from, that will be slow and not necessarily correct. If you need to refer to the commit, it's better to leave the headers mentioning the commit with the patch.

Brian Campbell
A: 

You can quite easily pickout the commits that introduced a particular blob id at a known path in the tree.

e.g. with blob_path set to the path in the tree that the patch affects and blob_sha1 being the abbreviated sha1 from the patch (i.e. what immediately follows the "index" after the diff line in the patch), this short script will find which commit introduced that version of the file.

for h in $(git log --pretty=format:%H "$blob_path")
do
    test "$(git rev-parse "$h:$blob_path")" = "$(git rev-parse "$blob_sha1")" &&
        echo $h
done

Of cours, you may want the most recent commit that still has that version of the file, in which case you want the parent of the commit that appears immediately before it in git log --pretty=format:%H "$blob_path".

Charles Bailey