mirror of
https://github.com/git/git.git
synced 2024-11-01 23:07:55 +01:00
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
5 changed files with 65 additions and 76 deletions
|
@ -232,9 +232,6 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
|
||||||
{
|
{
|
||||||
char *ref_git;
|
char *ref_git;
|
||||||
struct strbuf alternate = STRBUF_INIT;
|
struct strbuf alternate = STRBUF_INIT;
|
||||||
struct remote *remote;
|
|
||||||
struct transport *transport;
|
|
||||||
const struct ref *extra;
|
|
||||||
|
|
||||||
/* Beware: real_path() and mkpath() return static buffer */
|
/* Beware: real_path() and mkpath() return static buffer */
|
||||||
ref_git = xstrdup(real_path(item->string));
|
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);
|
strbuf_addf(&alternate, "%s/objects", ref_git);
|
||||||
add_to_alternates_file(alternate.buf);
|
add_to_alternates_file(alternate.buf);
|
||||||
strbuf_release(&alternate);
|
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);
|
free(ref_git);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -500,7 +489,6 @@ static void update_remote_refs(const struct ref *refs,
|
||||||
const char *msg)
|
const char *msg)
|
||||||
{
|
{
|
||||||
if (refs) {
|
if (refs) {
|
||||||
clear_extra_refs();
|
|
||||||
write_remote_refs(mapped_refs);
|
write_remote_refs(mapped_refs);
|
||||||
if (option_single_branch)
|
if (option_single_branch)
|
||||||
write_followtags(refs, msg);
|
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);
|
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) {
|
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 = find_ref_by_name(refs, "HEAD");
|
||||||
remote_head_points_at =
|
remote_head_points_at =
|
||||||
guess_remote_head(remote_head, mapped_refs, 0);
|
guess_remote_head(remote_head, mapped_refs, 0);
|
||||||
|
@ -852,6 +840,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
warning(_("You appear to have cloned an empty repository."));
|
warning(_("You appear to have cloned an empty repository."));
|
||||||
|
mapped_refs = NULL;
|
||||||
our_head_points_at = NULL;
|
our_head_points_at = NULL;
|
||||||
remote_head_points_at = NULL;
|
remote_head_points_at = NULL;
|
||||||
remote_head = 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)
|
if (o && o->type == OBJ_COMMIT)
|
||||||
rev_list_push((struct commit *)o, SEEN);
|
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;
|
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)
|
if (o && o->type == OBJ_COMMIT)
|
||||||
clear_commit_marks((struct commit *)o,
|
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);
|
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 INITIAL_FLUSH 16
|
||||||
#define PIPESAFE_FLUSH 32
|
#define PIPESAFE_FLUSH 32
|
||||||
#define LARGE_FLUSH 1024
|
#define LARGE_FLUSH 1024
|
||||||
|
@ -295,7 +290,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
||||||
marked = 1;
|
marked = 1;
|
||||||
|
|
||||||
for_each_ref(rev_list_insert_ref, NULL);
|
for_each_ref(rev_list_insert_ref, NULL);
|
||||||
insert_alternate_refs();
|
for_each_alternate_ref(insert_one_alternate_ref, NULL);
|
||||||
|
|
||||||
fetching = 0;
|
fetching = 0;
|
||||||
for ( ; refs ; refs = refs->next) {
|
for ( ; refs ; refs = refs->next) {
|
||||||
|
@ -493,7 +488,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
||||||
|
|
||||||
static struct commit_list *complete;
|
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);
|
struct object *o = parse_object(sha1);
|
||||||
|
|
||||||
|
@ -586,6 +581,11 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
|
||||||
*refs = newlist;
|
*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)
|
static int everything_local(struct ref **refs, int nr_match, char **match)
|
||||||
{
|
{
|
||||||
struct ref *ref;
|
struct ref *ref;
|
||||||
|
@ -614,6 +614,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
|
||||||
|
|
||||||
if (!args.depth) {
|
if (!args.depth) {
|
||||||
for_each_ref(mark_complete, NULL);
|
for_each_ref(mark_complete, NULL);
|
||||||
|
for_each_alternate_ref(mark_alternate_complete, NULL);
|
||||||
if (cutoff)
|
if (cutoff)
|
||||||
mark_recent_complete_commits(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;
|
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)
|
static void clear_ref_array(struct ref_array *array)
|
||||||
{
|
{
|
||||||
int i;
|
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)
|
static struct ref_array *get_packed_refs(struct ref_cache *refs)
|
||||||
{
|
{
|
||||||
if (!refs->did_packed) {
|
if (!refs->did_packed) {
|
||||||
|
@ -733,16 +717,11 @@ int peel_ref(const char *refname, unsigned char *sha1)
|
||||||
static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn,
|
static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn,
|
||||||
int trim, int flags, void *cb_data)
|
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_cache *refs = get_ref_cache(submodule);
|
||||||
struct ref_array *packed = get_packed_refs(refs);
|
struct ref_array *packed = get_packed_refs(refs);
|
||||||
struct ref_array *loose = get_loose_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(packed);
|
||||||
sort_ref_array(loose);
|
sort_ref_array(loose);
|
||||||
while (p < packed->nr && l < loose->nr) {
|
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);
|
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 ref_exists(const char *);
|
||||||
|
|
||||||
extern int peel_ref(const char *refname, unsigned char *sha1);
|
extern int peel_ref(const char *refname, unsigned char *sha1);
|
||||||
|
|
|
@ -52,13 +52,13 @@ test_cmp expected current'
|
||||||
|
|
||||||
cd "$base_dir"
|
cd "$base_dir"
|
||||||
|
|
||||||
rm -f "$U"
|
rm -f "$U.D"
|
||||||
|
|
||||||
test_expect_success 'cloning with reference (no -l -s)' \
|
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' \
|
test_expect_success 'fetched no objects' \
|
||||||
'! grep "^want" "$U"'
|
'! grep "^want" "$U.D"'
|
||||||
|
|
||||||
cd "$base_dir"
|
cd "$base_dir"
|
||||||
|
|
||||||
|
@ -153,4 +153,32 @@ test_expect_success 'clone with reference from a tagged repository' '
|
||||||
git clone --reference=A A I
|
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
|
test_done
|
||||||
|
|
Loading…
Reference in a new issue