summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi4
-rw-r--r--guix/scripts/hash.scm14
-rw-r--r--tests/guix-hash.sh6
3 files changed, 23 insertions, 1 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 7f579f81d4..31a23874b1 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -11758,7 +11758,7 @@ legacy alias for @var{type} sets to @code{nar}.
 @itemx -S
 Compute the hash on @var{file} using @var{type} serialization.
 
-Supported types: @code{none} and @code{nar}.
+Supported types: @code{none}, @code{nar} and @code{git}.
 
 When using @code{nar}, the hash is computed on an archive containing
 @var{file}, including its children if it is a directory.  Some of the
@@ -11769,6 +11769,8 @@ impact on the hash (@pxref{Invoking guix archive}).
 @c FIXME: Replace xref above with xref to an ``Archive'' section when
 @c it exists.
 
+Using @code{git} serializes the file or directory as a Git tree.
+
 @item --exclude-vcs
 @itemx -x
 When combined with @option{--recursive}, exclude version control system
diff --git a/guix/scripts/hash.scm b/guix/scripts/hash.scm
index debe8b4068..d73e3d13dd 100644
--- a/guix/scripts/hash.scm
+++ b/guix/scripts/hash.scm
@@ -35,6 +35,7 @@
   #:use-module (srfi srfi-11)
   #:use-module (srfi srfi-26)
   #:use-module (srfi srfi-37)
+  #:autoload   (disarchive git-hash) (git-hash-file git-hash-directory)
   #:export (guix-hash))
 
 
@@ -60,6 +61,17 @@
      (call-with-input-file file
        (cute port-hash algorithm <>)))))
 
+(define* (git-hash file #:optional
+                       (algorithm (assoc-ref %default-options 'hash-algorithm))
+                       select?)
+  (define directory?
+    (case (stat:type (stat file))
+      ((directory) #t)
+      (else #f)))
+  (if directory?
+      (git-hash-directory file algorithm)
+      (git-hash-file file algorithm)))
+
 
 ;;;
 ;;; Command-line options.
@@ -138,6 +150,8 @@ use '--serializer' instead~%"))
                        default-hash)
                       ("nar"
                        nar-hash)
+                      ("git"
+                       git-hash)
                       (x
                        (leave (G_ "unsupported serializer type: ~a~%")
                               arg))))
diff --git a/tests/guix-hash.sh b/tests/guix-hash.sh
index 7d186c91e6..854c493514 100644
--- a/tests/guix-hash.sh
+++ b/tests/guix-hash.sh
@@ -40,6 +40,9 @@ test "`guix hash /dev/null "$abs_top_srcdir/README"`" = "`guix hash /dev/null ;
 # Zero files.
 ! guix hash
 
+# idem as `cat /dev/null | git hash-object --stdin`
+test `guix hash -S git -H sha1 -f hex  /dev/null` = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
+
 ! guix hash -H abcd1234 /dev/null
 
 mkdir "$tmpdir"
@@ -50,6 +53,7 @@ mkdir "$tmpdir/subdir"
 
 test `guix hash -S nar "$tmpdir"` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppir13g7d74p
 test `guix hash -S nar "$tmpdir" -H sha512` = 301ra58c2vahczzxiyfin41mpyb0ljh4dh9zn3ijvwviaw1j40sfzw5skh9x945da88n3785ggifzig7acd6k72h0mpsc20m1f66m9n
+test `guix hash -S git "$tmpdir" -H sha512` = 158b10d1bsdk4pm8ym9cg9ckfak1b0cgpw7365cl6s341ir380mh2f4ylicyh8khyrfnwq5cn9766d7m8fbfwwl94ndkv456v6a8knr
 
 # Deprecated --recursive option
 test `guix hash -r "$tmpdir" 2>/dev/null` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppir13g7d74p
@@ -68,9 +72,11 @@ touch "$tmpdir/.git/foo"
 
 # ...changes the hash
 test `guix hash -S nar $tmpdir` = 0a50z04zyzf7pidwxv0nwbj82pgzbrhdy9562kncnvkcfvb48m59
+test `guix hash -S git $tmpdir` = 0ghlpca9xaswa1ay1g55dknwd9q899mi3ahfr43pq083v8wisjc7
 
 # ...but remains the same when using `-x'
 test `guix hash -S nar $tmpdir -x` = 10k1lw41wyrjf9mxydi0is5nkpynlsvgslinics4ppir13g7d74p
+test `guix hash -S git $tmpdir -x` = 0ghlpca9xaswa1ay1g55dknwd9q899mi3ahfr43pq083v8wisjc7
 
 # Without '-r', this should fail.
 ! guix hash "$tmpdir"