Reputation: 1266
With git, how can I get the tree hash of the current state of the git directory? That is, what the tree hash of the commit (not the commit hash) would be if I were to run git add -A
followed by git commit
?
Upvotes: 3
Views: 1029
Reputation: 488193
Somewhat easier than Greg Bacon's method:
git add -A
to update everything in the temporary indexgit commit-tree
to turn the temporary index into an actual treefor which a small shell script (untested) suffices:
#! /bin/sh -e
export GIT_INDEX_FILE=$(mktemp)
trap "rm -f $GIT_INDEX_FILE" 0 1 2 3 15
cp $(git rev-parse --git-dir)/index $GIT_INDEX_FILE
git add -A && git write-tree
The reason to copy the current index is that files that might be ignored (through .gitignore
or an exclude file) that are currently tracked (in the regular index) would be ignored when using the temporary index, if we did not prime the temporary index from the real index.
See also your own question How to get the tree hash of the index in git?
Upvotes: 4
Reputation: 139471
You could attempt to piece it together with git hash-object
and git mktree
as described in the Raw Git chapter of The Git Community Book, but I suggest the simpler approach of doing all the work on a throwaway detached HEAD.
Assuming you want to begin from the tip of the current branch, go to a detached HEAD state with
git checkout $(git rev-parse HEAD)
Part of the chatty output from git checkout
hints at the advantage of doing it this way.
You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout.
Here I create new files that will give git something to do and that represent your real changes with
touch new other stuff blah etc
Now rather than having to reimplement git, let git do what it already does
git add -A .
This stages changes to the index, from which git write-tree
will happily create a new tree object. The output on your machine in your repository is the hash you asked about.
git write-tree
afba5669cbf579a9f27f1fda66cb0958282fae3a
The hash written to the standard output is the hash of the tree object just created, but no need to take my word for it.
$ git commit -m 'Throwaway commit'
[detached HEAD 0ae9d12] Throwaway commit
5 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 blah
create mode 100644 etc
create mode 100644 new
create mode 100644 other
create mode 100644 stuff
The output hints at the new commit’s SHA1 object name (0ae9d12), which we can confirm with
$ git rev-parse HEAD
0ae9d12408d1ea7eb02821d66f6de8a2f8423e7f
But you want to know the hash of the commit’s tree object, addressable with
$ git rev-parse HEAD^{tree}
afba5669cbf579a9f27f1fda66cb0958282fae3a
Note that the hash is identical to the output from git write-tree
.
Now if you want to keep the commit, create a new branch here with git branch
. Otherwise, if you ignore it, the commit and unused objects will eventually be discarded as part of git’s ordinary garbage collection.
Upvotes: 1