diff options
author | Junio C Hamano <junkio@cox.net> | 2005-05-01 23:45:49 -0700 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2005-05-01 23:45:49 -0700 |
commit | 74400e7175e3dac994e75452973d78f6a42de65e (patch) | |
tree | 07f84ebdc715d72c409ce85ab0e8a74672b0a101 /sha1_file.c | |
parent | 285bf834bea11981ae7c2242e9f087d3effe7de8 (diff) | |
download | git-74400e7175e3dac994e75452973d78f6a42de65e.tar.gz |
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 <junkio@cox.net>
Diffstat (limited to 'sha1_file.c')
-rw-r--r-- | sha1_file.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/sha1_file.c b/sha1_file.c index ced0791847..cb556cae5c 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); +} |