From 024510c8d947be6ae4765840e21a89d5a21271c4 Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Sat, 10 Dec 2005 17:25:24 -0500 Subject: [PATCH] Allow saving an object from a pipe 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 Signed-off-by: Junio C Hamano --- Documentation/git-hash-object.txt | 5 ++++- cache.h | 1 + hash-object.c | 15 +++++++++++++-- sha1_file.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt index db12e926f8..0924931dc1 100644 --- a/Documentation/git-hash-object.txt +++ b/Documentation/git-hash-object.txt @@ -8,7 +8,7 @@ git-hash-object - Computes object ID and optionally creates a blob from a file. SYNOPSIS -------- -'git-hash-object' [-t ] [-w] +'git-hash-object' [-t ] [-w] [--stdin] [--] ... DESCRIPTION ----------- @@ -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 diff --git a/cache.h b/cache.h index 86fc25084c..c78d8aea41 100644 --- a/cache.h +++ b/cache.h @@ -144,6 +144,7 @@ extern int ce_match_stat(struct cache_entry *ce, struct stat *st); 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 62279368b8..6502b5b3d1 100644 --- a/hash-object.c +++ b/hash-object.c @@ -21,8 +21,16 @@ static void hash_object(const char *path, const char *type, int write_object) 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 ] [-w] ..."; +"git-hash-object [-t ] [-w] [--stdin] ..."; 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 111a71de6b..fa22e9c71a 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1528,6 +1528,40 @@ int has_sha1_file(const unsigned char *sha1) 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; -- 2.11.4.GIT