Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compute the git hash-object of a directory?

Tags:

git

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"

like image 609
Frank Schwieterman Avatar asked May 15 '11 20:05

Frank Schwieterman


People also ask

How does Git calculate hash?

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.

What is Git hash object?

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.

What is .Git object folder?

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.

How many bytes is a Git hash?

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.


2 Answers

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

like image 169
Andy Pryke Avatar answered Sep 20 '22 11:09

Andy Pryke


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.

like image 33
Mark Longair Avatar answered Sep 23 '22 11:09

Mark Longair