From 1494e03888d084aa1da265f8534d235461b3fc91 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 4 Dec 2005 22:48:43 -0800 Subject: sha1_file.c: make sure packs in an alternate odb is named properly. We somehow ended up registering packs in alternate object directories as "dir/object//pack/pack-*", which confusd the update-server-info code very badly. Also we did not attempt to detect a mistake of listing the object directory itself as one of the alternates. This does not lead to incorrect behaviour, but is simply wasteful, so try to do so when we are trivially able to. Signed-off-by: Junio C Hamano --- sha1_file.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'sha1_file.c') diff --git a/sha1_file.c b/sha1_file.c index 82a01887c2..111a71de6b 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -184,8 +184,8 @@ static struct alternate_object_database **alt_odb_tail; * alternate_object_database. The elements on this list come from * non-empty elements from colon separated ALTERNATE_DB_ENVIRONMENT * environment variable, and $GIT_OBJECT_DIRECTORY/info/alternates, - * whose contents is exactly in the same format as that environment - * variable. Its base points at a statically allocated buffer that + * whose contents is similar to that environment variable but can be + * LF separated. Its base points at a statically allocated buffer that * contains "/the/directory/corresponding/to/.git/objects/...", while * its name points just after the slash at the end of ".git/objects/" * in the example above, and has enough space to hold 40-byte hex @@ -197,6 +197,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, { const char *cp, *last; struct alternate_object_database *ent; + const char *objdir = get_object_directory(); int base_len = -1; last = alt; @@ -211,6 +212,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, for ( ; cp < ep && *cp != sep; cp++) ; if (last != cp) { + struct alternate_object_database *alt; /* 43 = 40-byte + 2 '/' + terminating NUL */ int pfxlen = cp - last; int entlen = pfxlen + 43; @@ -223,9 +225,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, pfxlen += base_len; } ent = xmalloc(sizeof(*ent) + entlen); - *alt_odb_tail = ent; - alt_odb_tail = &(ent->next); - ent->next = NULL; + if (*last != '/' && relative_base) { memcpy(ent->base, relative_base, base_len - 1); ent->base[base_len - 1] = '/'; @@ -237,6 +237,22 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, ent->name = ent->base + pfxlen + 1; ent->base[pfxlen] = ent->base[pfxlen + 3] = '/'; ent->base[entlen-1] = 0; + + /* Prevent the common mistake of listing the same + * thing twice, or object directory itself. + */ + for (alt = alt_odb_list; alt; alt = alt->next) + if (!memcmp(ent->base, alt->base, pfxlen)) + goto bad; + if (!memcmp(ent->base, objdir, pfxlen)) { + bad: + free(ent); + } + else { + *alt_odb_tail = ent; + alt_odb_tail = &(ent->next); + ent->next = NULL; + } } while (cp < ep && *cp == sep) cp++; @@ -531,8 +547,9 @@ void prepare_packed_git(void) prepare_packed_git_one(get_object_directory(), 1); prepare_alt_odb(); for (alt = alt_odb_list; alt; alt = alt->next) { - alt->name[0] = 0; + alt->name[-1] = 0; prepare_packed_git_one(alt->base, 0); + alt->name[-1] = '/'; } run_once = 1; } -- cgit v1.2.3 From 024510c8d947be6ae4765840e21a89d5a21271c4 Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Sat, 10 Dec 2005 17:25:24 -0500 Subject: 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(-) (limited to 'sha1_file.c') 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; -- cgit v1.2.3