diff options
-rw-r--r-- | builtin/receive-pack.c | 16 | ||||
-rw-r--r-- | sha1-array.c | 16 | ||||
-rw-r--r-- | sha1-array.h | 6 |
3 files changed, 35 insertions, 3 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 6bb1281666..e1a687ad07 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -10,6 +10,7 @@ #include "remote.h" #include "transport.h" #include "string-list.h" +#include "sha1-array.h" static const char receive_pack_usage[] = "git receive-pack <git-dir>"; @@ -731,14 +732,23 @@ static int delete_only(struct command *commands) return 1; } -static void add_one_alternate_ref(const struct ref *ref, void *unused) +static void add_one_alternate_sha1(const unsigned char sha1[20], void *unused) { - add_extra_ref(".have", ref->old_sha1, 0); + add_extra_ref(".have", sha1, 0); +} + +static void collect_one_alternate_ref(const struct ref *ref, void *data) +{ + struct sha1_array *sa = data; + sha1_array_append(sa, ref->old_sha1); } static void add_alternate_refs(void) { - for_each_alternate_ref(add_one_alternate_ref, NULL); + struct sha1_array sa = SHA1_ARRAY_INIT; + for_each_alternate_ref(collect_one_alternate_ref, &sa); + sha1_array_for_each_unique(&sa, add_one_alternate_sha1, NULL); + sha1_array_clear(&sa); } int cmd_receive_pack(int argc, const char **argv, const char *prefix) diff --git a/sha1-array.c b/sha1-array.c index 5b75a5a35d..b2f47f98fb 100644 --- a/sha1-array.c +++ b/sha1-array.c @@ -41,3 +41,19 @@ void sha1_array_clear(struct sha1_array *array) array->alloc = 0; array->sorted = 0; } + +void sha1_array_for_each_unique(struct sha1_array *array, + for_each_sha1_fn fn, + void *data) +{ + int i; + + if (!array->sorted) + sha1_array_sort(array); + + for (i = 0; i < array->nr; i++) { + if (i > 0 && !hashcmp(array->sha1[i], array->sha1[i-1])) + continue; + fn(array->sha1[i], data); + } +} diff --git a/sha1-array.h b/sha1-array.h index 15d3b6b984..4499b5dad4 100644 --- a/sha1-array.h +++ b/sha1-array.h @@ -15,4 +15,10 @@ void sha1_array_sort(struct sha1_array *array); int sha1_array_lookup(struct sha1_array *array, const unsigned char *sha1); void sha1_array_clear(struct sha1_array *array); +typedef void (*for_each_sha1_fn)(const unsigned char sha1[20], + void *data); +void sha1_array_for_each_unique(struct sha1_array *array, + for_each_sha1_fn fn, + void *data); + #endif /* SHA1_ARRAY_H */ |