|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2010 Sverre Rabbelier
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='Test remote-helper import and export commands'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
. "$TEST_DIRECTORY"/lib-gpg.sh
|
|
|
|
|
|
|
|
PATH="$TEST_DIRECTORY/t5801:$PATH"
|
|
|
|
|
|
|
|
compare_refs() {
|
|
|
|
fail= &&
|
|
|
|
if test "x$1" = 'x!'
|
|
|
|
then
|
|
|
|
fail='!' &&
|
|
|
|
shift
|
|
|
|
fi &&
|
|
|
|
git --git-dir="$1/.git" rev-parse --verify $2 >expect &&
|
|
|
|
git --git-dir="$3/.git" rev-parse --verify $4 >actual &&
|
|
|
|
eval $fail test_cmp expect actual
|
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'setup repository' '
|
|
|
|
git init server &&
|
|
|
|
(cd server &&
|
|
|
|
echo content >file &&
|
|
|
|
git add file &&
|
|
|
|
git commit -m one)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'cloning from local repo' '
|
|
|
|
git clone "testgit::${PWD}/server" local &&
|
|
|
|
test_cmp server/file local/file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'create new commit on remote' '
|
|
|
|
(cd server &&
|
|
|
|
echo content >>file &&
|
|
|
|
git commit -a -m two)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pulling from local repo' '
|
|
|
|
(cd local && git pull) &&
|
|
|
|
test_cmp server/file local/file
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pushing to local repo' '
|
|
|
|
(cd local &&
|
|
|
|
echo content >>file &&
|
|
|
|
git commit -a -m three &&
|
|
|
|
git push) &&
|
|
|
|
compare_refs local HEAD server HEAD
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'fetch new branch' '
|
|
|
|
(cd server &&
|
|
|
|
git reset --hard &&
|
|
|
|
git checkout -b new &&
|
|
|
|
echo content >>file &&
|
|
|
|
git commit -a -m five
|
|
|
|
) &&
|
|
|
|
(cd local &&
|
|
|
|
git fetch origin new
|
|
|
|
) &&
|
|
|
|
compare_refs server HEAD local FETCH_HEAD
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'fetch multiple branches' '
|
|
|
|
(cd local &&
|
|
|
|
git fetch
|
|
|
|
) &&
|
|
|
|
compare_refs server master local refs/remotes/origin/master &&
|
|
|
|
compare_refs server new local refs/remotes/origin/new
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push when remote has extra refs' '
|
|
|
|
(cd local &&
|
|
|
|
git reset --hard origin/master &&
|
|
|
|
echo content >>file &&
|
|
|
|
git commit -a -m six &&
|
|
|
|
git push
|
|
|
|
) &&
|
|
|
|
compare_refs local master server master
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push new branch by name' '
|
|
|
|
(cd local &&
|
|
|
|
git checkout -b new-name &&
|
|
|
|
echo content >>file &&
|
|
|
|
git commit -a -m seven &&
|
|
|
|
git push origin new-name
|
|
|
|
) &&
|
|
|
|
compare_refs local HEAD server refs/heads/new-name
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push new branch with old:new refspec' '
|
|
|
|
(cd local &&
|
|
|
|
git push origin new-name:new-refspec
|
|
|
|
) &&
|
|
|
|
compare_refs local HEAD server refs/heads/new-refspec
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push new branch with HEAD:new refspec' '
|
|
|
|
(cd local &&
|
|
|
|
git checkout new-name &&
|
|
|
|
git push origin HEAD:new-refspec-2
|
|
|
|
) &&
|
|
|
|
compare_refs local HEAD server refs/heads/new-refspec-2
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push delete branch' '
|
|
|
|
(cd local &&
|
|
|
|
git push origin :new-name
|
|
|
|
) &&
|
|
|
|
test_must_fail git --git-dir="server/.git" \
|
|
|
|
rev-parse --verify refs/heads/new-name
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'forced push' '
|
|
|
|
(cd local &&
|
|
|
|
git checkout -b force-test &&
|
|
|
|
echo content >> file &&
|
|
|
|
git commit -a -m eight &&
|
|
|
|
git push origin force-test &&
|
|
|
|
echo content >> file &&
|
|
|
|
git commit -a --amend -m eight-modified &&
|
|
|
|
git push --force origin force-test
|
|
|
|
) &&
|
|
|
|
compare_refs local refs/heads/force-test server refs/heads/force-test
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'cloning without refspec' '
|
|
|
|
GIT_REMOTE_TESTGIT_NOREFSPEC=1 \
|
|
|
|
git clone "testgit::${PWD}/server" local2 2>error &&
|
|
|
|
test_i18ngrep "this remote helper should implement refspec capability" error &&
|
|
|
|
compare_refs local2 HEAD server HEAD
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pulling without refspecs' '
|
|
|
|
(cd local2 &&
|
|
|
|
git reset --hard &&
|
|
|
|
GIT_REMOTE_TESTGIT_NOREFSPEC=1 git pull 2>../error) &&
|
|
|
|
test_i18ngrep "this remote helper should implement refspec capability" error &&
|
|
|
|
compare_refs local2 HEAD server HEAD
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pushing without refspecs' '
|
|
|
|
test_when_finished "(cd local2 && git reset --hard origin)" &&
|
|
|
|
(cd local2 &&
|
|
|
|
echo content >>file &&
|
|
|
|
git commit -a -m ten &&
|
|
|
|
GIT_REMOTE_TESTGIT_NOREFSPEC=1 &&
|
|
|
|
export GIT_REMOTE_TESTGIT_NOREFSPEC &&
|
|
|
|
test_must_fail git push 2>../error) &&
|
|
|
|
test_i18ngrep "remote-helper doesn.t support push; refspec needed" error
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pulling without marks' '
|
|
|
|
(cd local2 &&
|
|
|
|
GIT_REMOTE_TESTGIT_NO_MARKS=1 git pull) &&
|
|
|
|
compare_refs local2 HEAD server HEAD
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_failure 'pushing without marks' '
|
|
|
|
test_when_finished "(cd local2 && git reset --hard origin)" &&
|
|
|
|
(cd local2 &&
|
|
|
|
echo content >>file &&
|
|
|
|
git commit -a -m twelve &&
|
|
|
|
GIT_REMOTE_TESTGIT_NO_MARKS=1 git push) &&
|
|
|
|
compare_refs local2 HEAD server HEAD
|
|
|
|
'
|
|
|
|
|
fast-export: don't handle uninteresting refs
They have been marked as UNINTERESTING for a reason, lets respect
that. Currently the first ref is handled properly, but not the
rest. Assuming that all the refs point at the same commit in the
following example:
% git fast-export master ^uninteresting ^foo ^bar
reset refs/heads/bar
from :0
reset refs/heads/foo
from :0
reset refs/heads/uninteresting
from :0
% git fast-export ^uninteresting ^foo ^bar master
reset refs/heads/master
from :0
reset refs/heads/bar
from :0
reset refs/heads/foo
from :0
Clearly this is wrong; the negative refs should be ignored.
After this patch:
% git fast-export ^uninteresting ^foo ^bar master
# nothing
% git fast-export master ^uninteresting ^foo ^bar
# nothing
And even more, it would only happen if the ref is pointing to exactly
the same commit, but not otherwise:
% git fast-export ^next next
reset refs/heads/next
from :0
% git fast-export ^next next^{commit}
# nothing
% git fast-export ^next next~0
# nothing
% git fast-export ^next next~1
# nothing
% git fast-export ^next next~2
# nothing
The reason this happens is that before traversing the commits,
fast-export checks if any of the refs point to the same object, and any
duplicated ref gets added to a list in order to issue 'reset' commands
after the traversing. Unfortunately, it's not even checking if the
commit is flagged as UNINTERESTING. The fix of course, is to check it.
However, in order to do it properly we need to get the UNINTERESTING
flag from the command line, not from the commit object, because
"^foo bar" will mark the commit 'bar' uninteresting if foo and bar
points at the same commit. rev_cmdline_info, which was introduced
exactly to handle this situation, contains all the information we
need for get_tags_and_duplicates(), plus the ref flag. This way the
rest of the positive refs will remain untouched; it's only the
negative ones that change in behavior.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
12 years ago
|
|
|
test_expect_success 'push all with existing object' '
|
|
|
|
(cd local &&
|
|
|
|
git branch dup2 master &&
|
|
|
|
git push origin --all
|
|
|
|
) &&
|
|
|
|
compare_refs local dup2 server dup2
|
|
|
|
'
|
|
|
|
|
fast-export: make sure updated refs get updated
When an object has already been exported (and thus is in the marks) it's
flagged as SHOWN, so it will not be exported again, even if in a later
time it's exported through a different ref.
We don't need the object to be exported again, but we want the ref
updated, which doesn't happen.
Since we can't know if a ref was exported or not, let's just assume that
if the commit was marked (flags & SHOWN), the user still wants the ref
updated.
IOW: If it's specified in the command line, it will get updated,
regardless of whether or not the object was marked.
So:
% git branch test master
% git fast-export $mark_flags master
% git fast-export $mark_flags test
Would export 'test' properly.
Additionally, this fixes issues with remote helpers; now they can push
refs whose objects have already been exported, and a few other issues as
well. Update the tests accordingly.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
12 years ago
|
|
|
test_expect_success 'push ref with existing object' '
|
|
|
|
(cd local &&
|
|
|
|
git branch dup master &&
|
|
|
|
git push origin dup
|
|
|
|
) &&
|
|
|
|
compare_refs local dup server dup
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success GPG 'push signed tag' '
|
|
|
|
(cd local &&
|
|
|
|
git checkout master &&
|
|
|
|
git tag -s -m signed-tag signed-tag &&
|
|
|
|
git push origin signed-tag
|
|
|
|
) &&
|
|
|
|
compare_refs local signed-tag^{} server signed-tag^{} &&
|
|
|
|
compare_refs ! local signed-tag server signed-tag
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success GPG 'push signed tag with signed-tags capability' '
|
|
|
|
(cd local &&
|
|
|
|
git checkout master &&
|
|
|
|
git tag -s -m signed-tag signed-tag-2 &&
|
|
|
|
GIT_REMOTE_TESTGIT_SIGNED_TAGS=1 git push origin signed-tag-2
|
|
|
|
) &&
|
|
|
|
compare_refs local signed-tag-2 server signed-tag-2
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push update refs' '
|
|
|
|
(cd local &&
|
|
|
|
git checkout -b update master &&
|
|
|
|
echo update >>file &&
|
|
|
|
git commit -a -m update &&
|
|
|
|
git push origin update &&
|
|
|
|
git rev-parse --verify remotes/origin/update >expect &&
|
|
|
|
git rev-parse --verify testgit/origin/heads/update >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push update refs disabled by no-private-update' '
|
|
|
|
(cd local &&
|
|
|
|
echo more-update >>file &&
|
|
|
|
git commit -a -m more-update &&
|
|
|
|
git rev-parse --verify testgit/origin/heads/update >expect &&
|
|
|
|
GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE=t git push origin update &&
|
|
|
|
git rev-parse --verify testgit/origin/heads/update >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push update refs failure' '
|
|
|
|
(cd local &&
|
|
|
|
git checkout update &&
|
|
|
|
echo "update fail" >>file &&
|
|
|
|
git commit -a -m "update fail" &&
|
|
|
|
git rev-parse --verify testgit/origin/heads/update >expect &&
|
|
|
|
test_expect_code 1 env GIT_REMOTE_TESTGIT_FAILURE="non-fast forward" \
|
|
|
|
git push origin update &&
|
|
|
|
git rev-parse --verify testgit/origin/heads/update >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
clean_mark () {
|
|
|
|
cut -f 2 -d ' ' "$1" |
|
|
|
|
git cat-file --batch-check |
|
|
|
|
grep commit |
|
|
|
|
sort >$(basename "$1")
|
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'proper failure checks for fetching' '
|
|
|
|
(cd local &&
|
|
|
|
test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git fetch 2>error &&
|
|
|
|
test_i18ngrep -q "error while running fast-import" error
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'proper failure checks for pushing' '
|
|
|
|
test_when_finished "rm -rf local/git.marks local/testgit.marks" &&
|
|
|
|
(cd local &&
|
|
|
|
git checkout -b crash master &&
|
|
|
|
echo crash >>file &&
|
|
|
|
git commit -a -m crash &&
|
|
|
|
test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git push --all &&
|
|
|
|
clean_mark ".git/testgit/origin/git.marks" &&
|
|
|
|
clean_mark ".git/testgit/origin/testgit.marks" &&
|
|
|
|
test_cmp git.marks testgit.marks
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push messages' '
|
|
|
|
(cd local &&
|
|
|
|
git checkout -b new_branch master &&
|
|
|
|
echo new >>file &&
|
|
|
|
git commit -a -m new &&
|
|
|
|
git push origin new_branch &&
|
|
|
|
git fetch origin &&
|
|
|
|
echo new >>file &&
|
|
|
|
git commit -a -m new &&
|
|
|
|
git push origin new_branch 2> msg &&
|
|
|
|
! grep "\[new branch\]" msg
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
transport-helper: do not request symbolic refs to remote helpers
A typical remote helper will return a `list` of refs containing a symbolic
ref HEAD, pointing to, e.g. refs/heads/master. In the case of a clone, all
the refs are being requested through `fetch` or `import`, including the
symbolic ref.
While this works properly, in some cases of a fetch, like `git fetch url`
or `git fetch origin HEAD`, or any fetch command involving a symbolic ref
without also fetching the corresponding ref it points to, the fetch command
fails with:
fatal: bad object 0000000000000000000000000000000000000000
error: <remote> did not send all necessary objects
(in the case the remote helper returned '?' values to the `list` command).
This is because there is only one ref given to fetch(), and it's not
further resolved to something at the end of fetch_with_import().
While this can be somehow handled in the remote helper itself, by adding
a refspec for the symbolic ref, and storing an explicit ref in a private
namespace, and then handling the `import` for that symbolic ref
specifically, very few existing remote helpers are actually doing that.
So, instead of requesting the exact list of wanted refs to remote helpers,
treat symbolic refs differently and request the ref they point to instead.
Then, resolve the symbolic refs values based on the pointed ref.
This assumes there is no more than one level of indirection (a symbolic
ref doesn't point to another symbolic ref).
Signed-off-by: Mike Hommey <mh@glandium.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 years ago
|
|
|
test_expect_success 'fetch HEAD' '
|
|
|
|
(cd server &&
|
|
|
|
git checkout master &&
|
|
|
|
echo more >>file &&
|
|
|
|
git commit -a -m more
|
|
|
|
) &&
|
|
|
|
(cd local &&
|
|
|
|
git fetch origin HEAD
|
|
|
|
) &&
|
|
|
|
compare_refs server HEAD local FETCH_HEAD
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'fetch url' '
|
|
|
|
(cd server &&
|
|
|
|
git checkout master &&
|
|
|
|
echo more >>file &&
|
|
|
|
git commit -a -m more
|
|
|
|
) &&
|
|
|
|
(cd local &&
|
|
|
|
git fetch "testgit::${PWD}/../server"
|
|
|
|
) &&
|
|
|
|
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
|