Does anyone have an example of using git hash-object on a directory? It works easily enough on a file* but doesn't work as I'd expect for a directory**
*: git hash-object c:\somefile.txt **: git hash-object -t tree c:\somedirectory
When I try to use hash-object with the directory, it complains "fatal: Cannot open 'C:\someDirectory': Permission denied"
Git uses hashes in two important ways. When you commit a file into your repository, Git calculates and remembers the hash of the contents of the file. When you later retrieve the file, Git can verify that the hash of the data being retrieved exactly matches the hash that was computed when it was stored.
In its simplest form, git hash-object would take the content you handed to it and merely return the unique key that would be used to store it in your Git database. The -w option then tells the command to not simply return the key, but to write that object to the database.
Objects folder is a very important folder in the . git directory. In Git, everything is saved in the objects folder as a hash value. By everything I mean every commit, every tree or every file that you create is saved in this directory.
Every time a commit is added to a git repository, a hash string which identifies this commit is generated. This hash is computed with the SHA-1 algorithm and is 160 bits (20 bytes) long. Expressed in hexadecimal notation, such hashes are 40 digit strings.
Depending why you wish to do this, the following git command might be useful:
git ls-files -s somedirectory | git hash-object --stdin
This give a single hash which takes into account the filenames and contents.
It works like this. The git ls-files -s ....
outputs a list of files and their hashes as text to stdout
, then git hash-object
generates a hash for the data it receives from stdin
.
My use case for this is the following - I want to know whether the (git managed) files in a directory in one branch exactly(*) match those in another branch. The specific use is to compare the "directory hashes" decide whether I need to re-generate derived files which are cached.
By default git ls-files
will list files in sub-directories too. If you don't want that, try looking at answers to "how to git ls-file for just one directory level. There are also various other options to git ls-files, including the ability to specify a list of files to include.
(*) excluding hash-collisions
git hash-object -t tree
is expecting the file parameter to be a file that describes the entries in the tree, rather than a directory in the filesystem. I understand from the comment here that this command is expecting a file that describes the tree in a binary format, and that it would be easier to use git mktree
for you to create the tree object.
git mktree
understands input of the format you get from (for example) git ls-tree HEAD
. There is a nice example of constructing a tree from scratch using git hash-object
and git mktree
in the Git Community Book.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With