Skip to content

Commit 74400e7

Browse files
author
Junio C Hamano
committed
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>
1 parent 285bf83 commit 74400e7

File tree

5 files changed

+79
-52
lines changed

5 files changed

+79
-52
lines changed

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PROG= git-update-cache git-diff-files git-init-db git-write-tree \
2121
git-check-files git-ls-tree git-merge-base git-merge-cache \
2222
git-unpack-file git-export git-diff-cache git-convert-cache \
2323
git-http-pull git-rpush git-rpull git-rev-list git-mktag \
24-
git-diff-tree-helper git-tar-tree git-local-pull
24+
git-diff-tree-helper git-tar-tree git-local-pull git-write-blob
2525

2626
all: $(PROG)
2727

@@ -94,6 +94,7 @@ git-rev-list: rev-list.c
9494
git-mktag: mktag.c
9595
git-diff-tree-helper: diff-tree-helper.c
9696
git-tar-tree: tar-tree.c
97+
git-write-blob: write-blob.c
9798

9899
git-http-pull: LIBS += -lcurl
99100

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ extern int remove_entry_at(int pos);
116116
extern int remove_file_from_cache(char *path);
117117
extern int same_name(struct cache_entry *a, struct cache_entry *b);
118118
extern int cache_match_stat(struct cache_entry *ce, struct stat *st);
119+
extern int index_fd(unsigned char *sha1, int fd, struct stat *st);
119120

120121
#define MTIME_CHANGED 0x0001
121122
#define CTIME_CHANGED 0x0002

sha1_file.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,3 +460,54 @@ int has_sha1_file(const unsigned char *sha1)
460460
return 1;
461461
return 0;
462462
}
463+
464+
int index_fd(unsigned char *sha1, int fd, struct stat *st)
465+
{
466+
z_stream stream;
467+
unsigned long size = st->st_size;
468+
int max_out_bytes = size + 200;
469+
void *out = xmalloc(max_out_bytes);
470+
void *metadata = xmalloc(200);
471+
int metadata_size;
472+
void *in;
473+
SHA_CTX c;
474+
475+
in = "";
476+
if (size)
477+
in = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
478+
close(fd);
479+
if (!out || (int)(long)in == -1)
480+
return -1;
481+
482+
metadata_size = 1+sprintf(metadata, "blob %lu", size);
483+
484+
SHA1_Init(&c);
485+
SHA1_Update(&c, metadata, metadata_size);
486+
SHA1_Update(&c, in, size);
487+
SHA1_Final(sha1, &c);
488+
489+
memset(&stream, 0, sizeof(stream));
490+
deflateInit(&stream, Z_BEST_COMPRESSION);
491+
492+
/*
493+
* ASCII size + nul byte
494+
*/
495+
stream.next_in = metadata;
496+
stream.avail_in = metadata_size;
497+
stream.next_out = out;
498+
stream.avail_out = max_out_bytes;
499+
while (deflate(&stream, 0) == Z_OK)
500+
/* nothing */;
501+
502+
/*
503+
* File content
504+
*/
505+
stream.next_in = in;
506+
stream.avail_in = size;
507+
while (deflate(&stream, Z_FINISH) == Z_OK)
508+
/*nothing */;
509+
510+
deflateEnd(&stream);
511+
512+
return write_sha1_buffer(sha1, out, stream.total_out);
513+
}

update-cache.c

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -31,57 +31,6 @@ static inline long IS_ERR(const void *ptr)
3131
return (unsigned long)ptr > (unsigned long)-1000L;
3232
}
3333

34-
static int index_fd(unsigned char *sha1, int fd, struct stat *st)
35-
{
36-
z_stream stream;
37-
unsigned long size = st->st_size;
38-
int max_out_bytes = size + 200;
39-
void *out = xmalloc(max_out_bytes);
40-
void *metadata = xmalloc(200);
41-
int metadata_size;
42-
void *in;
43-
SHA_CTX c;
44-
45-
in = "";
46-
if (size)
47-
in = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
48-
close(fd);
49-
if (!out || (int)(long)in == -1)
50-
return -1;
51-
52-
metadata_size = 1+sprintf(metadata, "blob %lu", size);
53-
54-
SHA1_Init(&c);
55-
SHA1_Update(&c, metadata, metadata_size);
56-
SHA1_Update(&c, in, size);
57-
SHA1_Final(sha1, &c);
58-
59-
memset(&stream, 0, sizeof(stream));
60-
deflateInit(&stream, Z_BEST_COMPRESSION);
61-
62-
/*
63-
* ASCII size + nul byte
64-
*/
65-
stream.next_in = metadata;
66-
stream.avail_in = metadata_size;
67-
stream.next_out = out;
68-
stream.avail_out = max_out_bytes;
69-
while (deflate(&stream, 0) == Z_OK)
70-
/* nothing */;
71-
72-
/*
73-
* File content
74-
*/
75-
stream.next_in = in;
76-
stream.avail_in = size;
77-
while (deflate(&stream, Z_FINISH) == Z_OK)
78-
/*nothing */;
79-
80-
deflateEnd(&stream);
81-
82-
return write_sha1_buffer(sha1, out, stream.total_out);
83-
}
84-
8534
/*
8635
* This only updates the "non-critical" parts of the directory
8736
* cache, ie the parts that aren't tracked by GIT, and only used

write-blob.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* GIT - The information manager from hell
3+
*
4+
* Copyright (C) Linus Torvalds, 2005
5+
*/
6+
#include "cache.h"
7+
8+
int main(int argc, char **argv)
9+
{
10+
int i;
11+
12+
for (i = 1 ; i < argc; i++) {
13+
char *path = argv[i];
14+
int fd;
15+
struct stat st;
16+
unsigned char sha1[20];
17+
fd = open(path, O_RDONLY);
18+
if (fd < 0 ||
19+
fstat(fd, &st) < 0 ||
20+
index_fd(sha1, fd, &st) < 0)
21+
die("Unable to add blob %s to database", path);
22+
printf("%s\n", sha1_to_hex(sha1));
23+
}
24+
return 0;
25+
}

0 commit comments

Comments
 (0)