Merge branch 'fc/fetch-with-import-fix' into maint

Code restructuring during 2.20 period broke fetching tags via
"import" based transports.

* fc/fetch-with-import-fix:
  fetch: fix regression with transport helpers
  fetch: make the code more understandable
  fetch: trivial cleanup
  t5801 (remote-helpers): add test to fetch tags
  t5801 (remote-helpers): cleanup refspec stuff
This commit is contained in:
Junio C Hamano 2019-07-29 12:38:23 -07:00
commit 7011ce12b8
3 changed files with 45 additions and 23 deletions

View file

@ -239,6 +239,7 @@ static int will_fetch(struct ref **head, const unsigned char *sha1)
struct refname_hash_entry { struct refname_hash_entry {
struct hashmap_entry ent; /* must be the first member */ struct hashmap_entry ent; /* must be the first member */
struct object_id oid; struct object_id oid;
int ignore;
char refname[FLEX_ARRAY]; char refname[FLEX_ARRAY];
}; };
@ -287,6 +288,11 @@ static int refname_hash_exists(struct hashmap *map, const char *refname)
return !!hashmap_get_from_hash(map, strhash(refname), refname); return !!hashmap_get_from_hash(map, strhash(refname), refname);
} }
static void clear_item(struct refname_hash_entry *item)
{
item->ignore = 1;
}
static void find_non_local_tags(const struct ref *refs, static void find_non_local_tags(const struct ref *refs,
struct ref **head, struct ref **head,
struct ref ***tail) struct ref ***tail)
@ -319,7 +325,7 @@ static void find_non_local_tags(const struct ref *refs,
!will_fetch(head, ref->old_oid.hash) && !will_fetch(head, ref->old_oid.hash) &&
!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) && !has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
!will_fetch(head, item->oid.hash)) !will_fetch(head, item->oid.hash))
oidclr(&item->oid); clear_item(item);
item = NULL; item = NULL;
continue; continue;
} }
@ -333,7 +339,7 @@ static void find_non_local_tags(const struct ref *refs,
if (item && if (item &&
!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) && !has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
!will_fetch(head, item->oid.hash)) !will_fetch(head, item->oid.hash))
oidclr(&item->oid); clear_item(item);
item = NULL; item = NULL;
@ -354,7 +360,7 @@ static void find_non_local_tags(const struct ref *refs,
if (item && if (item &&
!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) && !has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
!will_fetch(head, item->oid.hash)) !will_fetch(head, item->oid.hash))
oidclr(&item->oid); clear_item(item);
/* /*
* For all the tags in the remote_refs_list, * For all the tags in the remote_refs_list,
@ -362,19 +368,21 @@ static void find_non_local_tags(const struct ref *refs,
*/ */
for_each_string_list_item(remote_ref_item, &remote_refs_list) { for_each_string_list_item(remote_ref_item, &remote_refs_list) {
const char *refname = remote_ref_item->string; const char *refname = remote_ref_item->string;
struct ref *rm;
item = hashmap_get_from_hash(&remote_refs, strhash(refname), refname); item = hashmap_get_from_hash(&remote_refs, strhash(refname), refname);
if (!item) if (!item)
BUG("unseen remote ref?"); BUG("unseen remote ref?");
/* Unless we have already decided to ignore this item... */ /* Unless we have already decided to ignore this item... */
if (!is_null_oid(&item->oid)) { if (item->ignore)
struct ref *rm = alloc_ref(item->refname); continue;
rm->peer_ref = alloc_ref(item->refname);
oidcpy(&rm->old_oid, &item->oid); rm = alloc_ref(item->refname);
**tail = rm; rm->peer_ref = alloc_ref(item->refname);
*tail = &rm->next; oidcpy(&rm->old_oid, &item->oid);
} **tail = rm;
*tail = &rm->next;
} }
hashmap_free(&remote_refs, 1); hashmap_free(&remote_refs, 1);
string_list_clear(&remote_refs_list, 0); string_list_clear(&remote_refs_list, 0);

View file

@ -126,7 +126,7 @@ test_expect_success 'forced push' '
' '
test_expect_success 'cloning without refspec' ' test_expect_success 'cloning without refspec' '
GIT_REMOTE_TESTGIT_REFSPEC="" \ GIT_REMOTE_TESTGIT_NOREFSPEC=1 \
git clone "testgit::${PWD}/server" local2 2>error && git clone "testgit::${PWD}/server" local2 2>error &&
test_i18ngrep "this remote helper should implement refspec capability" error && test_i18ngrep "this remote helper should implement refspec capability" error &&
compare_refs local2 HEAD server HEAD compare_refs local2 HEAD server HEAD
@ -135,7 +135,7 @@ test_expect_success 'cloning without refspec' '
test_expect_success 'pulling without refspecs' ' test_expect_success 'pulling without refspecs' '
(cd local2 && (cd local2 &&
git reset --hard && git reset --hard &&
GIT_REMOTE_TESTGIT_REFSPEC="" git pull 2>../error) && GIT_REMOTE_TESTGIT_NOREFSPEC=1 git pull 2>../error) &&
test_i18ngrep "this remote helper should implement refspec capability" error && test_i18ngrep "this remote helper should implement refspec capability" error &&
compare_refs local2 HEAD server HEAD compare_refs local2 HEAD server HEAD
' '
@ -145,8 +145,8 @@ test_expect_success 'pushing without refspecs' '
(cd local2 && (cd local2 &&
echo content >>file && echo content >>file &&
git commit -a -m ten && git commit -a -m ten &&
GIT_REMOTE_TESTGIT_REFSPEC="" && GIT_REMOTE_TESTGIT_NOREFSPEC=1 &&
export GIT_REMOTE_TESTGIT_REFSPEC && export GIT_REMOTE_TESTGIT_NOREFSPEC &&
test_must_fail git push 2>../error) && test_must_fail git push 2>../error) &&
test_i18ngrep "remote-helper doesn.t support push; refspec needed" error test_i18ngrep "remote-helper doesn.t support push; refspec needed" error
' '
@ -303,4 +303,14 @@ test_expect_success 'fetch url' '
compare_refs server HEAD local FETCH_HEAD compare_refs server HEAD local FETCH_HEAD
' '
test_expect_success 'fetch tag' '
(cd server &&
git tag v1.0
) &&
(cd local &&
git fetch
) &&
compare_refs local v1.0 server v1.0
'
test_done test_done

View file

@ -11,13 +11,15 @@ fi
url=$2 url=$2
dir="$GIT_DIR/testgit/$alias" dir="$GIT_DIR/testgit/$alias"
prefix="refs/testgit/$alias"
default_refspec="refs/heads/*:${prefix}/heads/*" h_refspec="refs/heads/*:refs/testgit/$alias/heads/*"
t_refspec="refs/tags/*:refs/testgit/$alias/tags/*"
refspec="${GIT_REMOTE_TESTGIT_REFSPEC-$default_refspec}" if test -n "$GIT_REMOTE_TESTGIT_NOREFSPEC"
then
test -z "$refspec" && prefix="refs" h_refspec=""
t_refspec=""
fi
GIT_DIR="$url/.git" GIT_DIR="$url/.git"
export GIT_DIR export GIT_DIR
@ -40,7 +42,8 @@ do
capabilities) capabilities)
echo 'import' echo 'import'
echo 'export' echo 'export'
test -n "$refspec" && echo "refspec $refspec" test -n "$h_refspec" && echo "refspec $h_refspec"
test -n "$t_refspec" && echo "refspec $t_refspec"
if test -n "$gitmarks" if test -n "$gitmarks"
then then
echo "*import-marks $gitmarks" echo "*import-marks $gitmarks"
@ -52,7 +55,7 @@ do
echo echo
;; ;;
list) list)
git for-each-ref --format='? %(refname)' 'refs/heads/' git for-each-ref --format='? %(refname)' 'refs/heads/' 'refs/tags/'
head=$(git symbolic-ref HEAD) head=$(git symbolic-ref HEAD)
echo "@$head HEAD" echo "@$head HEAD"
echo echo
@ -81,10 +84,11 @@ do
echo "feature done" echo "feature done"
git fast-export \ git fast-export \
${h_refspec:+"--refspec=$h_refspec"} \
${t_refspec:+"--refspec=$t_refspec"} \
${testgitmarks:+"--import-marks=$testgitmarks"} \ ${testgitmarks:+"--import-marks=$testgitmarks"} \
${testgitmarks:+"--export-marks=$testgitmarks"} \ ${testgitmarks:+"--export-marks=$testgitmarks"} \
$refs | $refs
sed -e "s#refs/heads/#${prefix}/heads/#g"
echo "done" echo "done"
;; ;;
export) export)