mirror of
https://github.com/git/git
synced 2024-10-28 19:25:47 +00:00
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:
commit
7011ce12b8
3 changed files with 45 additions and 23 deletions
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue