Merge branch 'mh/war-on-extra-refs'
* mh/war-on-extra-refs: refs: remove the extra_refs API clone: do not add alternate references to extra_refs everything_local(): mark alternate refs as complete fetch-pack.c: inline insert_alternate_refs() fetch-pack.c: rename some parameters from "path" to "refname" clone.c: move more code into the "if (refs)" conditional t5700: document a failure of alternates to affect fetch
This commit is contained in:
commit
d31f3785dc
@ -232,9 +232,6 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
|
||||
{
|
||||
char *ref_git;
|
||||
struct strbuf alternate = STRBUF_INIT;
|
||||
struct remote *remote;
|
||||
struct transport *transport;
|
||||
const struct ref *extra;
|
||||
|
||||
/* Beware: real_path() and mkpath() return static buffer */
|
||||
ref_git = xstrdup(real_path(item->string));
|
||||
@ -249,14 +246,6 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
|
||||
strbuf_addf(&alternate, "%s/objects", ref_git);
|
||||
add_to_alternates_file(alternate.buf);
|
||||
strbuf_release(&alternate);
|
||||
|
||||
remote = remote_get(ref_git);
|
||||
transport = transport_get(remote, ref_git);
|
||||
for (extra = transport_get_remote_refs(transport); extra;
|
||||
extra = extra->next)
|
||||
add_extra_ref(extra->name, extra->old_sha1, 0);
|
||||
|
||||
transport_disconnect(transport);
|
||||
free(ref_git);
|
||||
return 0;
|
||||
}
|
||||
@ -500,7 +489,6 @@ static void update_remote_refs(const struct ref *refs,
|
||||
const char *msg)
|
||||
{
|
||||
if (refs) {
|
||||
clear_extra_refs();
|
||||
write_remote_refs(mapped_refs);
|
||||
if (option_single_branch)
|
||||
write_followtags(refs, msg);
|
||||
@ -813,28 +801,28 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
|
||||
refs = transport_get_remote_refs(transport);
|
||||
mapped_refs = refs ? wanted_peer_refs(refs, refspec) : NULL;
|
||||
|
||||
/*
|
||||
* transport_get_remote_refs() may return refs with null sha-1
|
||||
* in mapped_refs (see struct transport->get_refs_list
|
||||
* comment). In that case we need fetch it early because
|
||||
* remote_head code below relies on it.
|
||||
*
|
||||
* for normal clones, transport_get_remote_refs() should
|
||||
* return reliable ref set, we can delay cloning until after
|
||||
* remote HEAD check.
|
||||
*/
|
||||
for (ref = refs; ref; ref = ref->next)
|
||||
if (is_null_sha1(ref->old_sha1)) {
|
||||
complete_refs_before_fetch = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_local && !complete_refs_before_fetch && refs)
|
||||
transport_fetch_refs(transport, mapped_refs);
|
||||
|
||||
if (refs) {
|
||||
mapped_refs = wanted_peer_refs(refs, refspec);
|
||||
/*
|
||||
* transport_get_remote_refs() may return refs with null sha-1
|
||||
* in mapped_refs (see struct transport->get_refs_list
|
||||
* comment). In that case we need fetch it early because
|
||||
* remote_head code below relies on it.
|
||||
*
|
||||
* for normal clones, transport_get_remote_refs() should
|
||||
* return reliable ref set, we can delay cloning until after
|
||||
* remote HEAD check.
|
||||
*/
|
||||
for (ref = refs; ref; ref = ref->next)
|
||||
if (is_null_sha1(ref->old_sha1)) {
|
||||
complete_refs_before_fetch = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_local && !complete_refs_before_fetch)
|
||||
transport_fetch_refs(transport, mapped_refs);
|
||||
|
||||
remote_head = find_ref_by_name(refs, "HEAD");
|
||||
remote_head_points_at =
|
||||
guess_remote_head(remote_head, mapped_refs, 0);
|
||||
@ -852,6 +840,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
else {
|
||||
warning(_("You appear to have cloned an empty repository."));
|
||||
mapped_refs = NULL;
|
||||
our_head_points_at = NULL;
|
||||
remote_head_points_at = NULL;
|
||||
remote_head = NULL;
|
||||
|
@ -58,9 +58,9 @@ static void rev_list_push(struct commit *commit, int mark)
|
||||
}
|
||||
}
|
||||
|
||||
static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
|
||||
static int rev_list_insert_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
struct object *o = deref_tag(parse_object(sha1), path, 0);
|
||||
struct object *o = deref_tag(parse_object(sha1), refname, 0);
|
||||
|
||||
if (o && o->type == OBJ_COMMIT)
|
||||
rev_list_push((struct commit *)o, SEEN);
|
||||
@ -68,9 +68,9 @@ static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clear_marks(const char *path, const unsigned char *sha1, int flag, void *cb_data)
|
||||
static int clear_marks(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
struct object *o = deref_tag(parse_object(sha1), path, 0);
|
||||
struct object *o = deref_tag(parse_object(sha1), refname, 0);
|
||||
|
||||
if (o && o->type == OBJ_COMMIT)
|
||||
clear_commit_marks((struct commit *)o,
|
||||
@ -256,11 +256,6 @@ static void insert_one_alternate_ref(const struct ref *ref, void *unused)
|
||||
rev_list_insert_ref(NULL, ref->old_sha1, 0, NULL);
|
||||
}
|
||||
|
||||
static void insert_alternate_refs(void)
|
||||
{
|
||||
for_each_alternate_ref(insert_one_alternate_ref, NULL);
|
||||
}
|
||||
|
||||
#define INITIAL_FLUSH 16
|
||||
#define PIPESAFE_FLUSH 32
|
||||
#define LARGE_FLUSH 1024
|
||||
@ -295,7 +290,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
||||
marked = 1;
|
||||
|
||||
for_each_ref(rev_list_insert_ref, NULL);
|
||||
insert_alternate_refs();
|
||||
for_each_alternate_ref(insert_one_alternate_ref, NULL);
|
||||
|
||||
fetching = 0;
|
||||
for ( ; refs ; refs = refs->next) {
|
||||
@ -493,7 +488,7 @@ done:
|
||||
|
||||
static struct commit_list *complete;
|
||||
|
||||
static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data)
|
||||
static int mark_complete(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
struct object *o = parse_object(sha1);
|
||||
|
||||
@ -586,6 +581,11 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
|
||||
*refs = newlist;
|
||||
}
|
||||
|
||||
static void mark_alternate_complete(const struct ref *ref, void *unused)
|
||||
{
|
||||
mark_complete(NULL, ref->old_sha1, 0, NULL);
|
||||
}
|
||||
|
||||
static int everything_local(struct ref **refs, int nr_match, char **match)
|
||||
{
|
||||
struct ref *ref;
|
||||
@ -614,6 +614,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
|
||||
|
||||
if (!args.depth) {
|
||||
for_each_ref(mark_complete, NULL);
|
||||
for_each_alternate_ref(mark_alternate_complete, NULL);
|
||||
if (cutoff)
|
||||
mark_recent_complete_commits(cutoff);
|
||||
}
|
||||
|
23
refs.c
23
refs.c
@ -183,12 +183,6 @@ static struct ref_cache {
|
||||
|
||||
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 void clear_ref_array(struct ref_array *array)
|
||||
{
|
||||
int i;
|
||||
@ -289,16 +283,6 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
|
||||
}
|
||||
}
|
||||
|
||||
void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
|
||||
{
|
||||
add_ref(&extra_refs, create_ref_entry(refname, sha1, flag, 0));
|
||||
}
|
||||
|
||||
void clear_extra_refs(void)
|
||||
{
|
||||
clear_ref_array(&extra_refs);
|
||||
}
|
||||
|
||||
static struct ref_array *get_packed_refs(struct ref_cache *refs)
|
||||
{
|
||||
if (!refs->did_packed) {
|
||||
@ -733,16 +717,11 @@ fallback:
|
||||
static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn,
|
||||
int trim, int flags, void *cb_data)
|
||||
{
|
||||
int retval = 0, i, p = 0, l = 0;
|
||||
int retval = 0, p = 0, l = 0;
|
||||
struct ref_cache *refs = get_ref_cache(submodule);
|
||||
struct ref_array *packed = get_packed_refs(refs);
|
||||
struct ref_array *loose = get_loose_refs(refs);
|
||||
|
||||
struct ref_array *extra = &extra_refs;
|
||||
|
||||
for (i = 0; i < extra->nr; 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) {
|
||||
|
8
refs.h
8
refs.h
@ -56,14 +56,6 @@ extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refn
|
||||
*/
|
||||
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
|
||||
* for the duration of this process or until clear_extra_refs() is
|
||||
* called. Only extra refs added before for_each_ref() is called will
|
||||
* be listed on a given call of for_each_ref().
|
||||
*/
|
||||
extern void add_extra_ref(const char *refname, const unsigned char *sha1, int flags);
|
||||
extern void clear_extra_refs(void);
|
||||
extern int ref_exists(const char *);
|
||||
|
||||
extern int peel_ref(const char *refname, unsigned char *sha1);
|
||||
|
@ -52,13 +52,13 @@ test_cmp expected current'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
rm -f "$U"
|
||||
rm -f "$U.D"
|
||||
|
||||
test_expect_success 'cloning with reference (no -l -s)' \
|
||||
'GIT_DEBUG_SEND_PACK=3 git clone --reference B "file://$(pwd)/A" D 3>"$U"'
|
||||
'GIT_DEBUG_SEND_PACK=3 git clone --reference B "file://$(pwd)/A" D 3>"$U.D"'
|
||||
|
||||
test_expect_success 'fetched no objects' \
|
||||
'! grep "^want" "$U"'
|
||||
'! grep "^want" "$U.D"'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
@ -153,4 +153,32 @@ test_expect_success 'clone with reference from a tagged repository' '
|
||||
git clone --reference=A A I
|
||||
'
|
||||
|
||||
test_expect_success 'prepare branched repository' '
|
||||
git clone A J &&
|
||||
(
|
||||
cd J &&
|
||||
git checkout -b other master^ &&
|
||||
echo other >otherfile &&
|
||||
git add otherfile &&
|
||||
git commit -m other &&
|
||||
git checkout master
|
||||
)
|
||||
'
|
||||
|
||||
rm -f "$U.K"
|
||||
|
||||
test_expect_success 'fetch with incomplete alternates' '
|
||||
git init K &&
|
||||
echo "$base_dir/A/.git/objects" >K/.git/objects/info/alternates &&
|
||||
(
|
||||
cd K &&
|
||||
git remote add J "file://$base_dir/J" &&
|
||||
GIT_DEBUG_SEND_PACK=3 git fetch J 3>"$U.K"
|
||||
) &&
|
||||
master_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/master) &&
|
||||
! grep "^want $master_object" "$U.K" &&
|
||||
tag_object=$(cd A && git for-each-ref --format="%(objectname)" refs/tags/HEAD) &&
|
||||
! grep "^want $tag_object" "$U.K"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user