[PATCH 02/15] builtin/hash-object: allow literally hashing with a given algorithm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add an --object-format argument to git hash-object that allows hashing
an object with a given algorithm. Currently this options is limited to
use with --literally, since the index_* functions do not yet handle
multiple hash algorithms.

Signed-off-by: brian m. carlson <sandals@xxxxxxxxxxxxxxxxxxxx>
---
 builtin/hash-object.c  | 47 ++++++++++++++++++++++++++++++------------
 t/t1007-hash-object.sh | 10 +++++++++
 2 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 640ef4ded5..0203cfbe9a 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -17,7 +17,8 @@
  * needs to bypass the data conversion performed by, and the type
  * limitation imposed by, index_fd() and its callees.
  */
-static int hash_literally(struct object_id *oid, int fd, const char *type, unsigned flags)
+static int hash_literally(struct object_id *oid, int fd, const char *type,
+			  unsigned flags, const struct git_hash_algo *algo)
 {
 	struct strbuf buf = STRBUF_INIT;
 	int ret;
@@ -25,42 +26,46 @@ static int hash_literally(struct object_id *oid, int fd, const char *type, unsig
 	if (strbuf_read(&buf, fd, 4096) < 0)
 		ret = -1;
 	else
-		ret = hash_object_file_literally(buf.buf, buf.len, type, oid,
-						 flags);
+		ret = hash_object_file_literally_algop(buf.buf, buf.len, type, oid,
+						       flags, algo);
 	strbuf_release(&buf);
 	return ret;
 }
 
 static void hash_fd(int fd, const char *type, const char *path, unsigned flags,
-		    int literally)
+		    int literally, const struct git_hash_algo *algo)
 {
 	struct stat st;
 	struct object_id oid;
 
+	if (!literally && algo != the_hash_algo)
+		die(_("Can't use hash algo %s except literally yet"), algo->name);
+
 	if (fstat(fd, &st) < 0 ||
 	    (literally
-	     ? hash_literally(&oid, fd, type, flags)
+	     ? hash_literally(&oid, fd, type, flags, algo)
 	     : index_fd(the_repository->index, &oid, fd, &st,
 			type_from_string(type), path, flags)))
 		die((flags & HASH_WRITE_OBJECT)
 		    ? "Unable to add %s to database"
 		    : "Unable to hash %s", path);
-	printf("%s\n", oid_to_hex(&oid));
+	printf("%s\n", hash_to_hex_algop(oid.hash, algo));
 	maybe_flush_or_die(stdout, "hash to stdout");
 }
 
 static void hash_object(const char *path, const char *type, const char *vpath,
-			unsigned flags, int literally)
+			unsigned flags, int literally,
+			const struct git_hash_algo *algo)
 {
 	int fd;
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
 		die_errno("Cannot open '%s'", path);
-	hash_fd(fd, type, vpath, flags, literally);
+	hash_fd(fd, type, vpath, flags, literally, algo);
 }
 
 static void hash_stdin_paths(const char *type, int no_filters, unsigned flags,
-			     int literally)
+			     int literally, const struct git_hash_algo *algo)
 {
 	struct strbuf buf = STRBUF_INIT;
 	struct strbuf unquoted = STRBUF_INIT;
@@ -73,7 +78,7 @@ static void hash_stdin_paths(const char *type, int no_filters, unsigned flags,
 			strbuf_swap(&buf, &unquoted);
 		}
 		hash_object(buf.buf, type, no_filters ? NULL : buf.buf, flags,
-			    literally);
+			    literally, algo);
 	}
 	strbuf_release(&buf);
 	strbuf_release(&unquoted);
@@ -94,6 +99,8 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
 	int nongit = 0;
 	unsigned flags = HASH_FORMAT_CHECK;
 	const char *vpath = NULL;
+	const char *object_format = NULL;
+	const struct git_hash_algo *algo;
 	const struct option hash_object_options[] = {
 		OPT_STRING('t', NULL, &type, N_("type"), N_("object type")),
 		OPT_BIT('w', NULL, &flags, N_("write the object into the object database"),
@@ -103,6 +110,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
 		OPT_BOOL( 0 , "no-filters", &no_filters, N_("store file as is without filters")),
 		OPT_BOOL( 0, "literally", &literally, N_("just hash any random garbage to create corrupt objects for debugging Git")),
 		OPT_STRING( 0 , "path", &vpath, N_("file"), N_("process file as it were from this path")),
+		OPT_STRING( 0 , "object-format", &object_format, N_("object-format"), N_("Use this hash algorithm")),
 		OPT_END()
 	};
 	int i;
@@ -121,6 +129,19 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
 
 	git_config(git_default_config, NULL);
 
+	algo = the_hash_algo;
+	if (object_format) {
+		if (flags & HASH_WRITE_OBJECT)
+			errstr = "Can't use -w with --object-format";
+		else {
+			int id = hash_algo_by_name(object_format);
+			if (id == GIT_HASH_UNKNOWN)
+				errstr = "Unknown object format";
+			else
+				algo = &hash_algos[id];
+		}
+	}
+
 	if (stdin_paths) {
 		if (hashstdin)
 			errstr = "Can't use --stdin-paths with --stdin";
@@ -142,7 +163,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
 	}
 
 	if (hashstdin)
-		hash_fd(0, type, vpath, flags, literally);
+		hash_fd(0, type, vpath, flags, literally, algo);
 
 	for (i = 0 ; i < argc; i++) {
 		const char *arg = argv[i];
@@ -151,12 +172,12 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
 		if (prefix)
 			arg = to_free = prefix_filename(prefix, arg);
 		hash_object(arg, type, no_filters ? NULL : vpath ? vpath : arg,
-			    flags, literally);
+			    flags, literally, algo);
 		free(to_free);
 	}
 
 	if (stdin_paths)
-		hash_stdin_paths(type, no_filters, flags, literally);
+		hash_stdin_paths(type, no_filters, flags, literally, algo);
 
 	return 0;
 }
diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh
index 64b340f227..ea4b3d2bda 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -83,6 +83,11 @@ test_expect_success 'hash a file' '
 	test "$(test_oid hello)" = $(git hash-object hello)
 '
 
+test_expect_failure 'hash a file with a given algorithm' '
+	test "$(test_oid --hash=sha1 hello)" = $(git hash-object --object-format=sha1 hello) &&
+	test "$(test_oid --hash=sha256 hello)" = $(git hash-object --object-format=sha256 hello)
+'
+
 test_blob_does_not_exist "$(test_oid hello)"
 
 test_expect_success 'hash from stdin' '
@@ -248,4 +253,9 @@ test_expect_success '--literally with extra-long type' '
 	echo example | git hash-object -t $t --literally --stdin
 '
 
+test_expect_success '--literally with --object-format' '
+	test $(test_oid --hash=sha1 hello) = $(git hash-object -t blob --literally --object-format=sha1 hello) &&
+	test $(test_oid --hash=sha256 hello) = $(git hash-object -t blob --literally --object-format=sha256 hello)
+'
+
 test_done



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux