aboutsummaryrefslogtreecommitdiffstats
path: root/sha1_file.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2005-05-01 23:45:49 -0700
committerJunio C Hamano <junkio@cox.net>2005-05-01 23:45:49 -0700
commit74400e7175e3dac994e75452973d78f6a42de65e (patch)
tree07f84ebdc715d72c409ce85ab0e8a74672b0a101 /sha1_file.c
parent285bf834bea11981ae7c2242e9f087d3effe7de8 (diff)
downloadgit-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.c51
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);
+}