From 1ddda5eefb55de5c88d071fcb40e6709be60672f Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Tue, 22 Feb 2011 16:18:45 +0100 Subject: [PATCH] refname objects: do not prune Refname objects are blobs with content "" which are typically dangling. Protect them from prune and fsck by pretending that they are reachable from existing refs. --- builtin/fsck.c | 10 +++++++++- cache.h | 3 +++ reachable.c | 7 +++++++ sha1_file.c | 5 +++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index bb9a2cd447..e42c14cfb0 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -490,7 +490,15 @@ static int is_branch(const char *refname) static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data) { - struct object *obj; + struct object *obj, *refobj; + unsigned char refsha1[20]; + + hash_sha1_refname(refname, refsha1); + if (has_sha1_file(refsha1)) { + refobj = parse_object(refsha1); + refobj->used = 1; + mark_object_reachable(refobj); + } obj = parse_object(sha1); if (!obj) { diff --git a/cache.h b/cache.h index 59e5b53179..6c5765b423 100644 --- a/cache.h +++ b/cache.h @@ -775,6 +775,9 @@ extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size); extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz); extern int parse_sha1_header(const char *hdr, unsigned long *sizep); +/* refname objects */ +extern int hash_sha1_refname(const char *path, unsigned char *refsha1); + /* global flag to enable extra checks when accessing packed objects */ extern int do_check_packed_object_crc; diff --git a/reachable.c b/reachable.c index e7e6a1e342..2e8d1b27a1 100644 --- a/reachable.c +++ b/reachable.c @@ -152,9 +152,16 @@ static int add_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1, static int add_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data) { + unsigned char refsha1[20]; struct object *object = parse_object_or_die(sha1, path); struct rev_info *revs = (struct rev_info *)cb_data; + hash_sha1_refname(path, refsha1); + if (has_sha1_file(refsha1)) + add_pending_object(revs, parse_object(refsha1), ""); + + if (!object) + die("bad object ref: %s:%s", path, sha1_to_hex(sha1)); add_pending_object(revs, object, ""); return 0; diff --git a/sha1_file.c b/sha1_file.c index 16967d3b9a..3d7faaf7fc 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -2914,3 +2914,8 @@ void assert_sha1_type(const unsigned char *sha1, enum object_type expect) die("%s is not a valid '%s' object", sha1_to_hex(sha1), typename(expect)); } + +int hash_sha1_refname(const char *path, unsigned char *refsha1) +{ + return hash_sha1_file((void *) path, strlen(path), typename(OBJ_BLOB), refsha1); +} -- 2.11.4.GIT