Reputation: 13995
I am trying to figure out how I could get a list of files and their respective old and new blobs for a single commit.
Say you have commit 1 which changed 3 files. I would run said function and return 3 files along with their old blob and new blob (assuming they are not binary).
Would the only way to do this be get the commit and previous commit, resolve their trees, then do a diff on the trees to find out what is different, and then get the blob for every different file?
Upvotes: 4
Views: 1096
Reputation: 67649
Would the only way to do this be get the commit and previous commit, resolve their trees, then do a diff on the trees to find out what is different, and then get the blob for every different file?
Yes, this is the recommended way. "Old" and "new" entries are only concepts that make sense when comparing two Tree
s.
Beware that "old" and "new" are not that expressive qualifiers. As one can peek in the diff header, the resulting diffing status of an entry may be
The libgit2 tests-clar/diff/tree test file should give you some sample usage of this feature.
A similar question (from you? ;-) ) has been raised in the libgit2 issue tracker. The answer from @arrbee also relies on leveraging the git_diff_tree_to_tree() API
.
Upvotes: 3
Reputation: 139681
Consider the output of git show --raw v1.8.1^0
in git’s own repository.
commit 5d417842efeafb6e109db7574196901c4e95d273 Author: Junio C Hamano Date: Mon Dec 31 14:24:22 2012 -0800 Git 1.8.1 Signed-off-by: Junio C Hamano <[email protected]> :100644 100644 fec1a06... d6f9555... M Documentation/RelNotes/1.8.1.txt :100644 100644 b0e8f02... 7a3f03b... M Documentation/git.txt :100755 100755 b2dffc8... 72e37c9... M GIT-VERSION-GEN
The last three lines indicate files that changed with that commit. The first SHA1 on a change line is the object name of the previous revision of a given file, and the second is the blob in the named commit. For example, GIT-VERSION-GEN
in v1.8.1
hashes to
$ git show v1.8.1^0:GIT-VERSION-GEN | git hash-object --stdin 72e37c9bfe3e897635f8c211569d9e6f5658a980
and the blob associated with its parent commit is
$ git show v1.8.1^0~:GIT-VERSION-GEN | git hash-object --stdin b2dffc839f306123d544e8f536ee31a7574f1139
Note: the documentation for git rev-parse
explains
As a special rule,
<rev>^0
means the commit itself and is used when<rev>
is the object name of a tag object that refers to a commit object.
In this case, v1.8.1^0
means the commit to which tag v1.8.1
refers.
To get object names for all blobs associated with a given commit, read the output of git ls-tree
, which resembles
$ git ls-tree -r v1.8.1^0 100644 blob 5e98806c6cc246acef5f539ae191710a0c06ad3f .gitattributes 100644 blob f702415c12c5a4a66180f7ffd697347e5343ac4a .gitignore 100644 blob c7e86183001a00ad2105765708b5b59852ef6640 .mailmap 100644 blob 536e55524db72bd2acf175208aef4f3dfc148d42 COPYING 100644 blob ddb030137d54ef3fb0ee01d973ec5cee4bb2b2b3 Documentation/.gitattributes 100644 blob d62aebd848b2a44f977ad4d7c4b75b6ff72b2163 Documentation/.gitignore 100644 blob 69f7e9b76c3f9b87b7951fb0df6a9720edadeb3e Documentation/CodingGuidelines 100644 blob e53d333e5c08515af1e21d81c7daa365b12609a1 Documentation/Makefile 100644 blob fea3f9935b7794ce86f04d22c9d68fb9d537167d Documentation/RelNotes/1.5.0.1.txt 100644 blob b061e50ff05b5e13211bb315e240974e898de32c Documentation/RelNotes/1.5.0.2.txt ...
Upvotes: 0
Reputation: 388223
Using only Git commands, don’t know about the particular libgit2 functions to access this information, but you can probably figure that out.
You can get a file listing of which files have changed in a particular commit using git show --stat COMMIT
. At the bottom is a list of file paths that have changed (plus details how many lines changed). You can probably filter out the stuff from there. You can further use the pretty-formatting to remove even more content from the output.
Once you have the file path, you can get a file blob using git show COMMIT:PATH
. You get the previous version of the file using git show COMMIT^:PATH
.
Upvotes: -1