Skip to content

fvsamson/git-hash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 

Repository files navigation

git-hash

Understanding Git's hash calculations and implementing them in shell code

Sources

These provided all necessary information without resorting to reading Git's source code, but at least most of the shell implementations were not completely correct; their flaws often only start to show, when reading files with embedded newlines or other formatting characters or binary data / executables.

WWW search: https://www.startpage.com/do/settings?query=git%20hash%20calculation

Documentation for git hash-object, which is more comprehensible than its man-page:
https://git-scm.com/docs/git-hash-object

Git internal workings

Git's ongoing / stalled transition from SHA-1 to SHA-256

Hashing a file

A file corresponds to Git's type blob.

Using git hash-object

  • cat "$filepath" | git hash-object -t blob --no-filters --stdin --literally
  • git hash-object -t blob --no-filters --literally "$filepath"
  • git hash-object -t blob "$filepath"
  • git hash-object "$filepath"

Equivalent shell code

  • printf 'blob %s\0' "$(wc -c < "$filepath")" | cat - "$filepath" | sha1sum
  • printf 'blob %s\0' "$(find -L "${filepath%/*}" -maxdepth 1 -name "${filepath##*/}" -type f -printf %s)" | cat - "$filepath" | sha1sum
  • printf 'blob %s\0' "$(find -L "$(dirname "$filepath")" -maxdepth 1 -name "$(basename "$filepath")" -type f -printf %s)" | cat - "$filepath" | sha1sum
  • stat -L --printf='blob %s\0' "$filepath" | cat - "$filepath" | sha1sum
  • stat -L --printf='%F blob %s\0' "$filepath" | grep -z '^regular file blob ' | sed -z 's/^regular file \(blob .*\)/\1/' | cat - "$filepath" | sha1sum

Recreating an object entry

ToDo # find -L . -type d -path "*/.git" -prune -o -printf "1%#05m %f\t%p\t%h\n" # find -L . -type d -path "*/.git" -prune -o -perm /111 -printf "100775 %f\t%p\t%h\n" -o \! -perm /111 -printf "100664 %f\t%p\t%h\n" find -L . -type d -path "*/.git" -prune -o -readable -xtype l -type f -printf "120000 %f\t%p\t%h\n" -o -readable -executable -type f -printf "100775 %f\t%p\t%h\n" -o -readable \! -executable -type f -printf "100664 %f\t%p\t%h\n" find -L . -type d -path "*/.git" -prune -o -readable -type f \( -xtype l -printf "120000 %f\t%p\t%h\n" -o -executable -printf "100775 %f\t%p\t%h\n" -o \! -executable -printf "100664 %f\t%p\t%h\n" \) # Separate links and dirs according to https://git-scm.com/book/en/v2/Git-Internals-Git-Objects#_tree_objects

Recreating a tree object's hash

A tree object comprises one or multiple object entries.

ToDo

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published