Merge branch 'mh/ref-clone-without-extra-refs'
* mh/ref-clone-without-extra-refs: write_remote_refs(): create packed (rather than extra) refs add_packed_ref(): new function in the refs API. ref_array: keep track of whether references are sorted pack_refs(): remove redundant check
This commit is contained in:
commit
a734e7ef6c
@ -464,11 +464,10 @@ static void write_remote_refs(const struct ref *local_refs)
|
|||||||
for (r = local_refs; r; r = r->next) {
|
for (r = local_refs; r; r = r->next) {
|
||||||
if (!r->peer_ref)
|
if (!r->peer_ref)
|
||||||
continue;
|
continue;
|
||||||
add_extra_ref(r->peer_ref->name, r->old_sha1, 0);
|
add_packed_ref(r->peer_ref->name, r->old_sha1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pack_refs(PACK_REFS_ALL);
|
pack_refs(PACK_REFS_ALL);
|
||||||
clear_extra_refs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_followtags(const struct ref *refs, const char *msg)
|
static void write_followtags(const struct ref *refs, const char *msg)
|
||||||
|
@ -143,7 +143,6 @@ int pack_refs(unsigned int flags)
|
|||||||
packed.fd = -1;
|
packed.fd = -1;
|
||||||
if (commit_lock_file(&packed) < 0)
|
if (commit_lock_file(&packed) < 0)
|
||||||
die_errno("unable to overwrite old ref-pack file");
|
die_errno("unable to overwrite old ref-pack file");
|
||||||
if (cbdata.flags & PACK_REFS_PRUNE)
|
|
||||||
prune_refs(cbdata.ref_to_prune);
|
prune_refs(cbdata.ref_to_prune);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
39
refs.c
39
refs.c
@ -17,6 +17,15 @@ struct ref_entry {
|
|||||||
|
|
||||||
struct ref_array {
|
struct ref_array {
|
||||||
int nr, alloc;
|
int nr, alloc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Entries with index 0 <= i < sorted are sorted by name. New
|
||||||
|
* entries are appended to the list unsorted, and are sorted
|
||||||
|
* only when required; thus we avoid the need to sort the list
|
||||||
|
* after the addition of every reference.
|
||||||
|
*/
|
||||||
|
int sorted;
|
||||||
|
|
||||||
struct ref_entry **refs;
|
struct ref_entry **refs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -105,12 +114,18 @@ static int is_dup_ref(const struct ref_entry *ref1, const struct ref_entry *ref2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sort the entries in array (if they are not already sorted).
|
||||||
|
*/
|
||||||
static void sort_ref_array(struct ref_array *array)
|
static void sort_ref_array(struct ref_array *array)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
/* Nothing to sort unless there are at least two entries */
|
/*
|
||||||
if (array->nr < 2)
|
* This check also prevents passing a zero-length array to qsort(),
|
||||||
|
* which is a problem on some platforms.
|
||||||
|
*/
|
||||||
|
if (array->sorted == array->nr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qsort(array->refs, array->nr, sizeof(*array->refs), ref_entry_cmp);
|
qsort(array->refs, array->nr, sizeof(*array->refs), ref_entry_cmp);
|
||||||
@ -124,7 +139,7 @@ static void sort_ref_array(struct ref_array *array)
|
|||||||
}
|
}
|
||||||
array->refs[++i] = array->refs[j];
|
array->refs[++i] = array->refs[j];
|
||||||
}
|
}
|
||||||
array->nr = i + 1;
|
array->sorted = array->nr = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ref_entry *search_ref_array(struct ref_array *array, const char *refname)
|
static struct ref_entry *search_ref_array(struct ref_array *array, const char *refname)
|
||||||
@ -137,7 +152,7 @@ static struct ref_entry *search_ref_array(struct ref_array *array, const char *r
|
|||||||
|
|
||||||
if (!array->nr)
|
if (!array->nr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
sort_ref_array(array);
|
||||||
len = strlen(refname) + 1;
|
len = strlen(refname) + 1;
|
||||||
e = xmalloc(sizeof(struct ref_entry) + len);
|
e = xmalloc(sizeof(struct ref_entry) + len);
|
||||||
memcpy(e->name, refname, len);
|
memcpy(e->name, refname, len);
|
||||||
@ -168,6 +183,10 @@ static struct ref_cache {
|
|||||||
|
|
||||||
static struct ref_entry *current_ref;
|
static struct ref_entry *current_ref;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Never call sort_ref_array() on the extra_refs, because it is
|
||||||
|
* allowed to contain entries with duplicate names.
|
||||||
|
*/
|
||||||
static struct ref_array extra_refs;
|
static struct ref_array extra_refs;
|
||||||
|
|
||||||
static void clear_ref_array(struct ref_array *array)
|
static void clear_ref_array(struct ref_array *array)
|
||||||
@ -176,7 +195,7 @@ static void clear_ref_array(struct ref_array *array)
|
|||||||
for (i = 0; i < array->nr; i++)
|
for (i = 0; i < array->nr; i++)
|
||||||
free(array->refs[i]);
|
free(array->refs[i]);
|
||||||
free(array->refs);
|
free(array->refs);
|
||||||
array->nr = array->alloc = 0;
|
array->sorted = array->nr = array->alloc = 0;
|
||||||
array->refs = NULL;
|
array->refs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +287,6 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
|
|||||||
!get_sha1_hex(refline + 1, sha1))
|
!get_sha1_hex(refline + 1, sha1))
|
||||||
hashcpy(last->peeled, sha1);
|
hashcpy(last->peeled, sha1);
|
||||||
}
|
}
|
||||||
sort_ref_array(array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
|
void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
|
||||||
@ -301,6 +319,12 @@ static struct ref_array *get_packed_refs(struct ref_cache *refs)
|
|||||||
return &refs->packed;
|
return &refs->packed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_packed_ref(const char *refname, const unsigned char *sha1)
|
||||||
|
{
|
||||||
|
add_ref(get_packed_refs(get_ref_cache(NULL)),
|
||||||
|
create_ref_entry(refname, sha1, REF_ISPACKED, 1));
|
||||||
|
}
|
||||||
|
|
||||||
static void get_ref_dir(struct ref_cache *refs, const char *base,
|
static void get_ref_dir(struct ref_cache *refs, const char *base,
|
||||||
struct ref_array *array)
|
struct ref_array *array)
|
||||||
{
|
{
|
||||||
@ -404,7 +428,6 @@ static struct ref_array *get_loose_refs(struct ref_cache *refs)
|
|||||||
{
|
{
|
||||||
if (!refs->did_loose) {
|
if (!refs->did_loose) {
|
||||||
get_ref_dir(refs, "refs", &refs->loose);
|
get_ref_dir(refs, "refs", &refs->loose);
|
||||||
sort_ref_array(&refs->loose);
|
|
||||||
refs->did_loose = 1;
|
refs->did_loose = 1;
|
||||||
}
|
}
|
||||||
return &refs->loose;
|
return &refs->loose;
|
||||||
@ -720,6 +743,8 @@ static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn
|
|||||||
for (i = 0; i < extra->nr; i++)
|
for (i = 0; i < extra->nr; i++)
|
||||||
retval = do_one_ref(base, fn, trim, flags, cb_data, extra->refs[i]);
|
retval = do_one_ref(base, fn, trim, flags, cb_data, extra->refs[i]);
|
||||||
|
|
||||||
|
sort_ref_array(packed);
|
||||||
|
sort_ref_array(loose);
|
||||||
while (p < packed->nr && l < loose->nr) {
|
while (p < packed->nr && l < loose->nr) {
|
||||||
struct ref_entry *entry;
|
struct ref_entry *entry;
|
||||||
int cmp = strcmp(packed->refs[p]->name, loose->refs[l]->name);
|
int cmp = strcmp(packed->refs[p]->name, loose->refs[l]->name);
|
||||||
|
6
refs.h
6
refs.h
@ -50,6 +50,12 @@ extern int for_each_rawref(each_ref_fn, void *);
|
|||||||
|
|
||||||
extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname);
|
extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a reference to the in-memory packed reference cache. To actually
|
||||||
|
* write the reference to the packed-refs file, call pack_refs().
|
||||||
|
*/
|
||||||
|
extern void add_packed_ref(const char *refname, const unsigned char *sha1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extra refs will be listed by for_each_ref() before any actual refs
|
* Extra refs will be listed by for_each_ref() before any actual refs
|
||||||
* for the duration of this process or until clear_extra_refs() is
|
* for the duration of this process or until clear_extra_refs() is
|
||||||
|
Loading…
Reference in New Issue
Block a user