threads / patch / 2795

patchAllow saving an object from a pipe

Subject: [PATCH] Allow saving an object from a pipe

## tl;dr

3 messages between Dec 10, 2005 and Dec 12, 2005. Diffs are folded; open one to read it.

replies: 2people: 2as markdown or json

Daniel Barkalow· Dec 10, 2005, 22:25 UTC · lore

In order to support getting data into git with scripts, this adds a --stdin option to git-hash-object, which will make it read from stdin.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 Documentation/git-hash-object.txt |    3 +++
 cache.h                           |    1 +
 hash-object.c                     |   15 +++++++++++++--
 sha1_file.c                       |   34 ++++++++++++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 2 deletions(-)
fac4c3a5c27839006e5d086ef282b252bd5f390e
Show changes to 4 files +51 −2

Documentation/git-hash-object.txt, cache.h, hash-object.c, sha1_file.c

diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index db12e92..eaac4c9 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -29,6 +29,9 @@ OPTIONS
 -w::
 	Actually write the object into the object database.
 
+--stdin::
+	Read the object from standard input instead of from a file.
+
 Author
 ------
 Written by Junio C Hamano <junkio@cox.net>
diff --git a/cache.h b/cache.h
index 86fc250..c78d8ae 100644
--- a/cache.h
+++ b/cache.h
@@ -144,6 +144,7 @@ extern int ce_match_stat(struct cache_en
 extern int ce_modified(struct cache_entry *ce, struct stat *st);
 extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
 extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, const char *type);
+extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object);
 extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
 extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
 
diff --git a/hash-object.c b/hash-object.c
index 6227936..6502b5b 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -21,8 +21,16 @@ static void hash_object(const char *path
 	printf("%s\n", sha1_to_hex(sha1));
 }
 
+static void hash_stdin(const char *type, int write_object)
+{
+	unsigned char sha1[20];
+	if (index_pipe(sha1, 0, type, write_object))
+		die("Unable to add stdin to database");
+	printf("%s\n", sha1_to_hex(sha1));
+}
+
 static const char hash_object_usage[] =
-"git-hash-object [-t <type>] [-w] <file>...";
+"git-hash-object [-t <type>] [-w] [--stdin] <file>...";
 
 int main(int argc, char **argv)
 {
@@ -53,9 +61,12 @@ int main(int argc, char **argv)
 			}
 			else if (!strcmp(argv[i], "--help"))
 				usage(hash_object_usage);
+			else if (!strcmp(argv[i], "--stdin")) {
+				hash_stdin(type, write_object);
+			}
 			else
 				die(hash_object_usage);
-		}
+		} 
 		else {
 			const char *arg = argv[i];
 			if (0 <= prefix_length)
diff --git a/sha1_file.c b/sha1_file.c
index 111a71d..fa22e9c 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1528,6 +1528,40 @@ int has_sha1_file(const unsigned char *s
 	return find_sha1_file(sha1, &st) ? 1 : 0;
 }
 
+int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object)
+{
+	unsigned long size = 4096;
+	char *buf = malloc(size);
+	int iret, ret;
+	unsigned long off = 0;
+	unsigned char hdr[50];
+	int hdrlen;
+	do {
+		iret = read(fd, buf + off, size - off);
+		if (iret > 0) {
+			off += iret;
+			if (off == size) {
+				size *= 2;
+				buf = realloc(buf, size);
+			}
+		}
+	} while (iret > 0);
+	if (iret < 0) {
+		free(buf);
+		return -1;
+	}
+	if (!type)
+		type = "blob";
+	if (write_object)
+		ret = write_sha1_file(buf, off, type, sha1);
+	else {
+		write_sha1_file_prepare(buf, off, type, sha1, hdr, &hdrlen);
+		ret = 0;
+	}
+	free(buf);
+	return ret;
+}
+
 int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, const char *type)
 {
 	unsigned long size = st->st_size;
-- 
0.99.9.GIT
Junio C Hamano· Dec 11, 2005, 02:59 UTC · re: Daniel Barkalow · lore

Re: [PATCH] Allow saving an object from a pipe

Daniel Barkalow <barkalow@iabervon.org> writes:
> In order to support getting data into git with scripts, this adds a
> --stdin option to git-hash-object, which will make it read from stdin.
Thanks, will apply.

To be honest, though, I am still debating myself about the merit of not having to have a temporary file. Because we need the size of the blob available before starting to hash (i.e. we cannot say "atend"), index_pipe ends up keeping the whole blob data in memory, which is not much better than the caller storing it in a temporary file and driving the normal hash-object from the command line anyway.

Daniel Barkalow· Dec 12, 2005, 17:12 UTC · re: Junio C Hamano · lore

Re: [PATCH] Allow saving an object from a pipe

On Sat, 10 Dec 2005, Junio C Hamano wrote:
Show 14 quoted lines
> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > In order to support getting data into git with scripts, this adds a
> > --stdin option to git-hash-object, which will make it read from stdin.
> 
> Thanks, will apply.
> 
> To be honest, though, I am still debating myself about the merit
> of not having to have a temporary file.  Because we need the
> size of the blob available before starting to hash (i.e. we
> cannot say "atend"), index_pipe ends up keeping the whole blob
> data in memory, which is not much better than the caller storing
> it in a temporary file and driving the normal hash-object from
> the command line anyway.

It's not much better for efficiency, but it's a whole lot easier to write the script without having to worry about a temporary file, what could happen to it while you're trying to use it, and making sure it gets cleaned up afterwards. It can also save on disk writes, depending on where you put it and how the system is configured.

	-Daniel
*This .sig left intentionally blank*

← back to recent threads