From the command prompt in windows i want to have the list of every hash (SHA1) a specific file already got after every commit made on it.
With i can find the actual hascode with "git has-object ", but i want to have the previous ones too.
From the command prompt in windows i want to have the list of every hash (SHA1) a specific file already got after every commit made on it.
With i can find the actual hascode with "git has-object ", but i want to have the previous ones too.
Fastest:
git rev-list --objects @ -- path/to/it | grep /it$
The rev-list lists the selected commits (the ones in the current history that touched path/to/it
) and since you asked nice also the relevant objects: the tree ids for path
and path/to
in those commits and also the new blob id for path/to/it
. You just want the blob id's.
Perhaps neater, and more flexible:
git log --pretty='%h:path/to/it %h path/to/it' -- path/to/it \
| git cat-file --batch-check='%(objectname) %(rest)'
Each commit you make contains every file. (Well, every file it contains. That is: if you made commit deadbee
six weeks ago and there were six files back then, commit deadbee
has six files in it. If newer commit cabfeed
has nine files, it has 9 files in it. If you then removed one of them and just now made commit fabdeed
, that commit has eight files, because you removed one.)
Given some commit hash ID, and the path of some file within that commit hash ID, you can find the corresponding "blob hash ID" of that file in that commit. For instance, one of the most recent commits in the Git repository for Git itself is c4203212e360b25a1c69467b5a8437d45a373cac
. This commit contains 3971 files (well, one of them is a submodule, so 3970 files is more accurate). One of these files is named builtin/tag.c
. Let's see its hash ID, using the git rev-parse
command:
$ git rev-parse c4203212e360b25a1c69467b5a8437d45a373cac:builtin/tag.c
452558ec95751965c5eb83b96220e411c3bc29d2
This means 452558ec95751965c5eb83b96220e411c3bc29d2
contains the data for that file, as we can see with a bit more effort:
$ git cat-file -p 452558ec95751965c5eb83b96220e411c3bc29d2 | head -2
/*
* Builtin "git tag"
So, what you need Git to do here is iterate through each commit, just like git log
does. Now, git log
has no option to print the hash IDs of each file (or any specific file) within the commit, but git log
and its sister command git rev-list
will, when you use them the right way, print out the hash ID of each commit. So that gets you just enough to write a program to do what you want done.
This program is very easy to write in shell-script commands, which can be run with /bin/sh
or bash
. Git needs some shell so on systems that don't have one, the Git installation usually includes bash
. Here's a minimal bash
program that runs git rev-parse
over and over again in the right way:
git rev-list HEAD | while read hash; do git rev-parse $hash:builtin/tag.c; done
Running this briefly produces:
452558ec95751965c5eb83b96220e411c3bc29d2
452558ec95751965c5eb83b96220e411c3bc29d2
452558ec95751965c5eb83b96220e411c3bc29d2
452558ec95751965c5eb83b96220e411c3bc29d2
452558ec95751965c5eb83b96220e411c3bc29d2
452558ec95751965c5eb83b96220e411c3bc29d2
452558ec95751965c5eb83b96220e411c3bc29d2
452558ec95751965c5eb83b96220e411c3bc29d2
452558ec95751965c5eb83b96220e411c3bc29d2
82fcfc0982423f3c7ee90fe43d30295023cc7873
82fcfc0982423f3c7ee90fe43d30295023cc7873
82fcfc0982423f3c7ee90fe43d30295023cc7873
[I interrupted at this point]
which, as you can see, shows the hash ID for each copy of tag.c
in each commit.
You'll no doubt want to improve this program to print each hash ID only once, or perhaps once per commit-that-has-a-different builtin/tag.c
in it, than the later commit printed earlier (remember that Git works backwards, which is why git log
starts with the latest commit and works backwards). You will probably also want to make sure that each commit of interest actually has the file: if you go far enough back in the Git repository for Git, there ceases to be a builtin/tag.c
at all. Before that point all the builtins were in the top level, spelled builtin-whatever
, so it was builtin-tag.c
instead.
Unless you use PowerShell, the Windows command prompt is generally not a usable programming language, so you'll want to write your program in a more capable language. Remember the following:
git log
can be told to print just the commit hash ID;git log
can be told to --follow
file renames (rev-list cannot); andgit log
can be told to print commit hash IDs only for commits where some file changed between this commit and its parent.So git log
may end up being more useful than git rev-list
, depending on your needs here.