summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Documentation/git-remote-testgit.txt2
-rw-r--r--Makefile2
-rw-r--r--builtin/fast-export.c27
-rwxr-xr-xgit-remote-testgit90
-rw-r--r--git-remote-testpy.py (renamed from git-remote-testgit.py)2
-rw-r--r--git_remote_helpers/git/importer.py2
-rwxr-xr-xt/t5800-remote-testpy.sh (renamed from t/t5800-remote-helpers.sh)14
-rwxr-xr-xt/t5801-remote-helpers.sh169
-rwxr-xr-xt/t9350-fast-export.sh65
10 files changed, 352 insertions, 23 deletions
diff --git a/.gitignore b/.gitignore
index f702415c12..956ae2260d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -124,7 +124,7 @@
/git-remote-ftps
/git-remote-fd
/git-remote-ext
-/git-remote-testgit
+/git-remote-testpy
/git-remote-testsvn
/git-repack
/git-replace
diff --git a/Documentation/git-remote-testgit.txt b/Documentation/git-remote-testgit.txt
index 2a67d456a3..612a625ced 100644
--- a/Documentation/git-remote-testgit.txt
+++ b/Documentation/git-remote-testgit.txt
@@ -19,7 +19,7 @@ testcase for the remote-helper functionality, and as an example to
show remote-helper authors one possible implementation.
The best way to learn more is to read the comments and source code in
-'git-remote-testgit.py'.
+'git-remote-testgit'.
SEE ALSO
--------
diff --git a/Makefile b/Makefile
index 186f127301..8e225cad7d 100644
--- a/Makefile
+++ b/Makefile
@@ -478,7 +478,7 @@ SCRIPT_PERL += git-relink.perl
SCRIPT_PERL += git-send-email.perl
SCRIPT_PERL += git-svn.perl
-SCRIPT_PYTHON += git-remote-testgit.py
+SCRIPT_PYTHON += git-remote-testpy.py
SCRIPT_PYTHON += git-p4.py
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 12220ad8da..77dffd1ce3 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -474,18 +474,21 @@ static void handle_tag(const char *name, struct tag *tag)
(int)message_size, (int)message_size, message ? message : "");
}
-static void get_tags_and_duplicates(struct object_array *pending,
+static void get_tags_and_duplicates(struct rev_cmdline_info *info,
struct string_list *extra_refs)
{
struct tag *tag;
int i;
- for (i = 0; i < pending->nr; i++) {
- struct object_array_entry *e = pending->objects + i;
+ for (i = 0; i < info->nr; i++) {
+ struct rev_cmdline_entry *e = info->rev + i;
unsigned char sha1[20];
- struct commit *commit = commit;
+ struct commit *commit;
char *full_name;
+ if (e->flags & UNINTERESTING)
+ continue;
+
if (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1)
continue;
@@ -523,10 +526,14 @@ static void get_tags_and_duplicates(struct object_array *pending,
typename(e->item->type));
continue;
}
- if (commit->util)
- /* more than one name for the same object */
+
+ /*
+ * This ref will not be updated through a commit, lets make
+ * sure it gets properly updated eventually.
+ */
+ if (commit->util || commit->object.flags & SHOWN)
string_list_append(extra_refs, full_name)->util = commit;
- else
+ if (!commit->util)
commit->util = full_name;
}
}
@@ -614,6 +621,10 @@ static void import_marks(char *input_file)
if (object->flags & SHOWN)
error("Object %s already has a mark", sha1_to_hex(sha1));
+ if (object->type != OBJ_COMMIT)
+ /* only commits */
+ continue;
+
mark_object(object, mark);
if (last_idnum < mark)
last_idnum = mark;
@@ -677,7 +688,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
if (import_filename && revs.prune_data.nr)
full_tree = 1;
- get_tags_and_duplicates(&revs.pending, &extra_refs);
+ get_tags_and_duplicates(&revs.cmdline, &extra_refs);
if (prepare_revision_walk(&revs))
die("revision walk setup failed");
diff --git a/git-remote-testgit b/git-remote-testgit
new file mode 100755
index 0000000000..b395c8de59
--- /dev/null
+++ b/git-remote-testgit
@@ -0,0 +1,90 @@
+#!/usr/bin/env bash
+# Copyright (c) 2012 Felipe Contreras
+
+alias=$1
+url=$2
+
+dir="$GIT_DIR/testgit/$alias"
+prefix="refs/testgit/$alias"
+
+default_refspec="refs/heads/*:${prefix}/heads/*"
+
+refspec="${GIT_REMOTE_TESTGIT_REFSPEC-$default_refspec}"
+
+test -z "$refspec" && prefix="refs"
+
+export GIT_DIR="$url/.git"
+
+mkdir -p "$dir"
+
+if test -z "$GIT_REMOTE_TESTGIT_NO_MARKS"
+then
+ gitmarks="$dir/git.marks"
+ testgitmarks="$dir/testgit.marks"
+ test -e "$gitmarks" || >"$gitmarks"
+ test -e "$testgitmarks" || >"$testgitmarks"
+ testgitmarks_args=( "--"{import,export}"-marks=$testgitmarks" )
+fi
+
+while read line
+do
+ case $line in
+ capabilities)
+ echo 'import'
+ echo 'export'
+ test -n "$refspec" && echo "refspec $refspec"
+ if test -n "$gitmarks"
+ then
+ echo "*import-marks $gitmarks"
+ echo "*export-marks $gitmarks"
+ fi
+ echo
+ ;;
+ list)
+ git for-each-ref --format='? %(refname)' 'refs/heads/'
+ head=$(git symbolic-ref HEAD)
+ echo "@$head HEAD"
+ echo
+ ;;
+ import*)
+ # read all import lines
+ while true
+ do
+ ref="${line#* }"
+ refs="$refs $ref"
+ read line
+ test "${line%% *}" != "import" && break
+ done
+
+ if test -n "$gitmarks"
+ then
+ echo "feature import-marks=$gitmarks"
+ echo "feature export-marks=$gitmarks"
+ fi
+ echo "feature done"
+ git fast-export "${testgitmarks_args[@]}" $refs |
+ sed -e "s#refs/heads/#${prefix}/heads/#g"
+ echo "done"
+ ;;
+ export)
+ before=$(git for-each-ref --format='%(refname) %(objectname)')
+
+ git fast-import "${testgitmarks_args[@]}" --quiet
+
+ after=$(git for-each-ref --format='%(refname) %(objectname)')
+
+ # figure out which refs were updated
+ join -e 0 -o '0 1.2 2.2' -a 2 <(echo "$before") <(echo "$after") |
+ while read ref a b
+ do
+ test $a == $b && continue
+ echo "ok $ref"
+ done
+
+ echo
+ ;;
+ '')
+ exit
+ ;;
+ esac
+done
diff --git a/git-remote-testgit.py b/git-remote-testpy.py
index 5f3ebd244d..ade797bbb0 100644
--- a/git-remote-testgit.py
+++ b/git-remote-testpy.py
@@ -91,7 +91,7 @@ def do_capabilities(repo, args):
if not os.path.exists(dirname):
os.makedirs(dirname)
- path = os.path.join(dirname, 'testgit.marks')
+ path = os.path.join(dirname, 'git.marks')
print "*export-marks %s" % path
if os.path.exists(path):
diff --git a/git_remote_helpers/git/importer.py b/git_remote_helpers/git/importer.py
index 5c6b595e16..e28cc8f986 100644
--- a/git_remote_helpers/git/importer.py
+++ b/git_remote_helpers/git/importer.py
@@ -39,7 +39,7 @@ class GitImporter(object):
gitdir = self.repo.gitpath
else:
gitdir = os.path.abspath(os.path.join(dirname, '.git'))
- path = os.path.abspath(os.path.join(dirname, 'git.marks'))
+ path = os.path.abspath(os.path.join(dirname, 'testgit.marks'))
if not os.path.exists(dirname):
os.makedirs(dirname)
diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-testpy.sh
index e7dc668cef..6750961507 100755
--- a/t/t5800-remote-helpers.sh
+++ b/t/t5800-remote-testpy.sh
@@ -3,12 +3,12 @@
# Copyright (c) 2010 Sverre Rabbelier
#
-test_description='Test remote-helper import and export commands'
+test_description='Test python remote-helper framework'
. ./test-lib.sh
if ! test_have_prereq PYTHON ; then
- skip_all='skipping git-remote-hg tests, python not available'
+ skip_all='skipping python remote-helper tests, python not available'
test_done
fi
@@ -17,7 +17,7 @@ import sys
if sys.hexversion < 0x02040000:
sys.exit(1)
' || {
- skip_all='skipping git-remote-hg tests, python version < 2.4'
+ skip_all='skipping python remote-helper tests, python version < 2.4'
test_done
}
@@ -38,12 +38,12 @@ test_expect_success 'setup repository' '
'
test_expect_success 'cloning from local repo' '
- git clone "testgit::${PWD}/server" localclone &&
+ git clone "testpy::${PWD}/server" localclone &&
test_cmp public/file localclone/file
'
test_expect_success 'cloning from remote repo' '
- git clone "testgit::file://${PWD}/server" clone &&
+ git clone "testpy::file://${PWD}/server" clone &&
test_cmp public/file clone/file
'
@@ -73,11 +73,11 @@ test_expect_success 'pushing to local repo' '
'
# Generally, skip this test. It demonstrates a now-fixed race in
-# git-remote-testgit, but is too slow to leave in for general use.
+# git-remote-testpy, but is too slow to leave in for general use.
: test_expect_success 'racily pushing to local repo' '
test_when_finished "rm -rf server2 localclone2" &&
cp -R server server2 &&
- git clone "testgit::${PWD}/server2" localclone2 &&
+ git clone "testpy::${PWD}/server2" localclone2 &&
(cd localclone2 &&
echo content >>file &&
git commit -a -m three &&
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
new file mode 100755
index 0000000000..f387027c05
--- /dev/null
+++ b/t/t5801-remote-helpers.sh
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Sverre Rabbelier
+#
+
+test_description='Test remote-helper import and export commands'
+
+. ./test-lib.sh
+
+if ! type "${BASH-bash}" >/dev/null 2>&1; then
+ skip_all='skipping remote-testgit tests, bash not available'
+ test_done
+fi
+
+compare_refs() {
+ git --git-dir="$1/.git" rev-parse --verify $2 >expect &&
+ git --git-dir="$3/.git" rev-parse --verify $4 >actual &&
+ 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_failure '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 'cloning without refspec' '
+ GIT_REMOTE_TESTGIT_REFSPEC="" \
+ git clone "testgit::${PWD}/server" local2 &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'pulling without refspecs' '
+ (cd local2 &&
+ git reset --hard &&
+ GIT_REMOTE_TESTGIT_REFSPEC="" git pull) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_failure '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_REFSPEC="" git push) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'pulling with straight refspec' '
+ (cd local2 &&
+ GIT_REMOTE_TESTGIT_REFSPEC="*:*" git pull) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_failure 'pushing with straight refspec' '
+ test_when_finished "(cd local2 && git reset --hard origin)" &&
+ (cd local2 &&
+ echo content >>file &&
+ git commit -a -m eleven &&
+ GIT_REMOTE_TESTGIT_REFSPEC="*:*" git push) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+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
+'
+
+test_expect_success 'push all with existing object' '
+ (cd local &&
+ git branch dup2 master &&
+ git push origin --all
+ ) &&
+ compare_refs local dup2 server dup2
+'
+
+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_done
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 3e821f958b..9320b4f94c 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -303,7 +303,7 @@ test_expect_success 'dropping tag of filtered out object' '
(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=drop mytag -- there > output &&
- test_cmp output expected
+ test_cmp expected output
)
'
@@ -320,7 +320,7 @@ test_expect_success 'rewriting tag of filtered out object' '
(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=rewrite mytag -- there > output &&
- test_cmp output expected
+ test_cmp expected output
)
'
@@ -351,7 +351,7 @@ test_expect_failure 'no exact-ref revisions included' '
(
cd limit-by-paths &&
git fast-export master~2..master~1 > output &&
- test_cmp output expected
+ test_cmp expected output
)
'
@@ -440,4 +440,63 @@ test_expect_success 'fast-export quotes pathnames' '
)
'
+test_expect_success 'test bidirectionality' '
+ >marks-cur &&
+ >marks-new &&
+ git init marks-test &&
+ git fast-export --export-marks=marks-cur --import-marks=marks-cur --branches | \
+ git --git-dir=marks-test/.git fast-import --export-marks=marks-new --import-marks=marks-new &&
+ (cd marks-test &&
+ git reset --hard &&
+ echo Wohlauf > file &&
+ git commit -a -m "back in time") &&
+ git --git-dir=marks-test/.git fast-export --export-marks=marks-new --import-marks=marks-new --branches | \
+ git fast-import --export-marks=marks-cur --import-marks=marks-cur
+'
+
+cat > expected << EOF
+blob
+mark :13
+data 5
+bump
+
+commit refs/heads/master
+mark :14
+author A U Thor <author@example.com> 1112912773 -0700
+committer C O Mitter <committer@example.com> 1112912773 -0700
+data 5
+bump
+from :12
+M 100644 :13 file
+
+EOF
+
+test_expect_success 'avoid uninteresting refs' '
+ > tmp-marks &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks master > /dev/null &&
+ git tag v1.0 &&
+ git branch uninteresting &&
+ echo bump > file &&
+ git commit -a -m bump &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks ^uninteresting ^v1.0 master > actual &&
+ test_cmp expected actual
+'
+
+cat > expected << EOF
+reset refs/heads/master
+from :14
+
+EOF
+
+test_expect_success 'refs are updated even if no commits need to be exported' '
+ > tmp-marks &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks master > /dev/null &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks master > actual &&
+ test_cmp expected actual
+'
+
test_done