From: Junio C Hamano Date: Mon, 2 May 2005 06:45:49 +0000 (-0700) Subject: Add git-write-blob. X-Git-Tag: v0.99~655^2~2 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=74400e7175e3dac994e75452973d78f6a42de65e;p=git.git Add git-write-blob. A new command, git-write-blob, is introduced. This registers the contents of any file on the filesystem as a blob in the object database and reports its SHA1 to the standard output. To implement it, the patch promotes index_fd() from a static function in update-cache.c to extern and moves it to a library source, sha1_file.c. This command is used to update git-merge-one-file-script so that it does not smudge the work tree. Signed-off-by: Junio C Hamano --- diff --git a/Makefile b/Makefile index 86aca612..99b4753d 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ PROG= git-update-cache git-diff-files git-init-db git-write-tree \ git-check-files git-ls-tree git-merge-base git-merge-cache \ git-unpack-file git-export git-diff-cache git-convert-cache \ git-http-pull git-rpush git-rpull git-rev-list git-mktag \ - git-diff-tree-helper git-tar-tree git-local-pull + git-diff-tree-helper git-tar-tree git-local-pull git-write-blob all: $(PROG) @@ -94,6 +94,7 @@ git-rev-list: rev-list.c git-mktag: mktag.c git-diff-tree-helper: diff-tree-helper.c git-tar-tree: tar-tree.c +git-write-blob: write-blob.c git-http-pull: LIBS += -lcurl diff --git a/cache.h b/cache.h index 940ced03..94f22c21 100644 --- a/cache.h +++ b/cache.h @@ -116,6 +116,7 @@ extern int remove_entry_at(int pos); extern int remove_file_from_cache(char *path); extern int same_name(struct cache_entry *a, struct cache_entry *b); extern int cache_match_stat(struct cache_entry *ce, struct stat *st); +extern int index_fd(unsigned char *sha1, int fd, struct stat *st); #define MTIME_CHANGED 0x0001 #define CTIME_CHANGED 0x0002 diff --git a/sha1_file.c b/sha1_file.c index ced07918..cb556cae 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -460,3 +460,54 @@ int has_sha1_file(const unsigned char *sha1) return 1; return 0; } + +int index_fd(unsigned char *sha1, int fd, struct stat *st) +{ + z_stream stream; + unsigned long size = st->st_size; + int max_out_bytes = size + 200; + void *out = xmalloc(max_out_bytes); + void *metadata = xmalloc(200); + int metadata_size; + void *in; + SHA_CTX c; + + in = ""; + if (size) + in = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + close(fd); + if (!out || (int)(long)in == -1) + return -1; + + metadata_size = 1+sprintf(metadata, "blob %lu", size); + + SHA1_Init(&c); + SHA1_Update(&c, metadata, metadata_size); + SHA1_Update(&c, in, size); + SHA1_Final(sha1, &c); + + memset(&stream, 0, sizeof(stream)); + deflateInit(&stream, Z_BEST_COMPRESSION); + + /* + * ASCII size + nul byte + */ + stream.next_in = metadata; + stream.avail_in = metadata_size; + stream.next_out = out; + stream.avail_out = max_out_bytes; + while (deflate(&stream, 0) == Z_OK) + /* nothing */; + + /* + * File content + */ + stream.next_in = in; + stream.avail_in = size; + while (deflate(&stream, Z_FINISH) == Z_OK) + /*nothing */; + + deflateEnd(&stream); + + return write_sha1_buffer(sha1, out, stream.total_out); +} diff --git a/update-cache.c b/update-cache.c index d53c9b5c..0401372e 100644 --- a/update-cache.c +++ b/update-cache.c @@ -31,57 +31,6 @@ static inline long IS_ERR(const void *ptr) return (unsigned long)ptr > (unsigned long)-1000L; } -static int index_fd(unsigned char *sha1, int fd, struct stat *st) -{ - z_stream stream; - unsigned long size = st->st_size; - int max_out_bytes = size + 200; - void *out = xmalloc(max_out_bytes); - void *metadata = xmalloc(200); - int metadata_size; - void *in; - SHA_CTX c; - - in = ""; - if (size) - in = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); - close(fd); - if (!out || (int)(long)in == -1) - return -1; - - metadata_size = 1+sprintf(metadata, "blob %lu", size); - - SHA1_Init(&c); - SHA1_Update(&c, metadata, metadata_size); - SHA1_Update(&c, in, size); - SHA1_Final(sha1, &c); - - memset(&stream, 0, sizeof(stream)); - deflateInit(&stream, Z_BEST_COMPRESSION); - - /* - * ASCII size + nul byte - */ - stream.next_in = metadata; - stream.avail_in = metadata_size; - stream.next_out = out; - stream.avail_out = max_out_bytes; - while (deflate(&stream, 0) == Z_OK) - /* nothing */; - - /* - * File content - */ - stream.next_in = in; - stream.avail_in = size; - while (deflate(&stream, Z_FINISH) == Z_OK) - /*nothing */; - - deflateEnd(&stream); - - return write_sha1_buffer(sha1, out, stream.total_out); -} - /* * This only updates the "non-critical" parts of the directory * cache, ie the parts that aren't tracked by GIT, and only used diff --git a/write-blob.c b/write-blob.c new file mode 100644 index 00000000..8bfd5761 --- /dev/null +++ b/write-blob.c @@ -0,0 +1,25 @@ +/* + * GIT - The information manager from hell + * + * Copyright (C) Linus Torvalds, 2005 + */ +#include "cache.h" + +int main(int argc, char **argv) +{ + int i; + + for (i = 1 ; i < argc; i++) { + char *path = argv[i]; + int fd; + struct stat st; + unsigned char sha1[20]; + fd = open(path, O_RDONLY); + if (fd < 0 || + fstat(fd, &st) < 0 || + index_fd(sha1, fd, &st) < 0) + die("Unable to add blob %s to database", path); + printf("%s\n", sha1_to_hex(sha1)); + } + return 0; +}