Skip to content

Commit 90e6255

Browse files
committed
Merge branch 'fc/transport-helper-fixes'
Updates transport-helper, fast-import and fast-export to allow the ref mapping and ref deletion in a way similar to the natively supported transports. * fc/transport-helper-fixes: remote-bzr: support the new 'force' option test-hg.sh: tests are now expected to pass transport-helper.c: do not overwrite forced bit transport-helper: check for 'forced update' message transport-helper: add 'force' to 'export' helpers transport-helper: don't update refs in dry-run transport-helper: mismerge fix
2 parents decba94 + a7cb127 commit 90e6255

File tree

7 files changed

+105
-12
lines changed

7 files changed

+105
-12
lines changed

Documentation/gitremote-helpers.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,10 @@ set by Git if the remote helper has the 'option' capability.
437437
'option check-connectivity' \{'true'|'false'\}::
438438
Request the helper to check connectivity of a clone.
439439

440+
'option force' \{'true'|'false'\}::
441+
Request the helper to perform a force update. Defaults to
442+
'false'.
443+
440444
'option cloning \{'true'|'false'\}::
441445
Notify the helper this is a clone request (i.e. the current
442446
repository is guaranteed empty).

contrib/remote-helpers/git-remote-bzr

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,8 @@ def do_export(parser):
684684
peer = bzrlib.branch.Branch.open(peers[name],
685685
possible_transports=transports)
686686
try:
687-
peer.bzrdir.push_branch(branch, revision_id=revid)
687+
peer.bzrdir.push_branch(branch, revision_id=revid,
688+
overwrite=force)
688689
except bzrlib.errors.DivergedBranches:
689690
print "error %s non-fast forward" % ref
690691
continue
@@ -718,8 +719,32 @@ def do_capabilities(parser):
718719
print "*import-marks %s" % path
719720
print "*export-marks %s" % path
720721

722+
print "option"
721723
print
722724

725+
class InvalidOptionValue(Exception):
726+
pass
727+
728+
def get_bool_option(val):
729+
if val == 'true':
730+
return True
731+
elif val == 'false':
732+
return False
733+
else:
734+
raise InvalidOptionValue()
735+
736+
def do_option(parser):
737+
global force
738+
opt, val = parser[1:3]
739+
try:
740+
if opt == 'force':
741+
force = get_bool_option(val)
742+
print 'ok'
743+
else:
744+
print 'unsupported'
745+
except InvalidOptionValue:
746+
print "error '%s' is not a valid value for option '%s'" % (val, opt)
747+
723748
def ref_is_valid(name):
724749
return not True in [c in name for c in '~^: \\']
725750

@@ -882,6 +907,7 @@ def main(args):
882907
global is_tmp
883908
global branches, peers
884909
global transports
910+
global force
885911

886912
marks = None
887913
is_tmp = False
@@ -904,6 +930,7 @@ def main(args):
904930
branches = {}
905931
peers = {}
906932
transports = []
933+
force = False
907934

908935
if alias[5:] == url:
909936
is_tmp = True
@@ -936,6 +963,8 @@ def main(args):
936963
do_import(parser)
937964
elif parser.check('export'):
938965
do_export(parser)
966+
elif parser.check('option'):
967+
do_option(parser)
939968
else:
940969
die('unhandled command: %s' % line)
941970
sys.stdout.flush()

contrib/remote-helpers/test-bzr.sh

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,33 @@ test_expect_success 'pushing' '
6666
test_cmp expected actual
6767
'
6868

69+
test_expect_success 'forced pushing' '
70+
(
71+
cd gitrepo &&
72+
echo three-new >content &&
73+
git commit -a --amend -m three-new &&
74+
git push -f
75+
) &&
76+
77+
(
78+
cd bzrrepo &&
79+
# the forced update overwrites the bzr branch but not the bzr
80+
# working directory (it tries to merge instead)
81+
bzr revert
82+
) &&
83+
84+
echo three-new >expected &&
85+
cat bzrrepo/content >actual &&
86+
test_cmp expected actual
87+
'
88+
6989
test_expect_success 'roundtrip' '
7090
(
7191
cd gitrepo &&
7292
git pull &&
7393
git log --format="%s" -1 origin/master >actual
7494
) &&
75-
echo three >expected &&
95+
echo three-new >expected &&
7696
test_cmp expected actual &&
7797
7898
(cd gitrepo && git push && git pull) &&

contrib/remote-helpers/test-hg.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ test_expect_success 'remote big push fetch first' '
680680
)
681681
'
682682

683-
test_expect_failure 'remote big push force' '
683+
test_expect_success 'remote big push force' '
684684
test_when_finished "rm -rf hgrepo gitrepo*" &&
685685
686686
setup_big_push
@@ -710,7 +710,7 @@ test_expect_failure 'remote big push force' '
710710
check_bookmark hgrepo new_bmark six
711711
'
712712

713-
test_expect_failure 'remote big push dry-run' '
713+
test_expect_success 'remote big push dry-run' '
714714
test_when_finished "rm -rf hgrepo gitrepo*" &&
715715
716716
setup_big_push

git-remote-testgit.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ test -z "$refspec" && prefix="refs"
1515

1616
export GIT_DIR="$url/.git"
1717

18+
force=
19+
1820
mkdir -p "$dir"
1921

2022
if test -z "$GIT_REMOTE_TESTGIT_NO_MARKS"
@@ -39,6 +41,7 @@ do
3941
fi
4042
test -n "$GIT_REMOTE_TESTGIT_SIGNED_TAGS" && echo "signed-tags"
4143
test -n "$GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE" && echo "no-private-update"
44+
echo 'option'
4245
echo
4346
;;
4447
list)
@@ -93,6 +96,7 @@ do
9396
before=$(git for-each-ref --format=' %(refname) %(objectname) ')
9497

9598
git fast-import \
99+
${force:+--force} \
96100
${testgitmarks:+"--import-marks=$testgitmarks"} \
97101
${testgitmarks:+"--export-marks=$testgitmarks"} \
98102
--quiet
@@ -115,6 +119,20 @@ do
115119

116120
echo
117121
;;
122+
option\ *)
123+
read cmd opt val <<-EOF
124+
$line
125+
EOF
126+
case $opt in
127+
force)
128+
test $val = "true" && force="true" || force=
129+
echo "ok"
130+
;;
131+
*)
132+
echo "unsupported"
133+
;;
134+
esac
135+
;;
118136
'')
119137
exit
120138
;;

t/t5801-remote-helpers.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,19 @@ test_expect_failure 'push new branch with old:new refspec' '
9494
compare_refs local HEAD server refs/heads/new-refspec
9595
'
9696

97+
test_expect_success 'forced push' '
98+
(cd local &&
99+
git checkout -b force-test &&
100+
echo content >> file &&
101+
git commit -a -m eight &&
102+
git push origin force-test &&
103+
echo content >> file &&
104+
git commit -a --amend -m eight-modified &&
105+
git push --force origin force-test
106+
) &&
107+
compare_refs local refs/heads/force-test server refs/heads/force-test
108+
'
109+
97110
test_expect_success 'cloning without refspec' '
98111
GIT_REMOTE_TESTGIT_REFSPEC="" \
99112
git clone "testgit::${PWD}/server" local2 2>error &&

transport-helper.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ static int push_update_ref_status(struct strbuf *buf,
650650
struct ref *remote_refs)
651651
{
652652
char *refname, *msg;
653-
int status;
653+
int status, forced = 0;
654654

655655
if (starts_with(buf->buf, "ok ")) {
656656
status = REF_STATUS_OK;
@@ -708,6 +708,11 @@ static int push_update_ref_status(struct strbuf *buf,
708708
free(msg);
709709
msg = NULL;
710710
}
711+
else if (!strcmp(msg, "forced update")) {
712+
forced = 1;
713+
free(msg);
714+
msg = NULL;
715+
}
711716
}
712717

713718
if (*ref)
@@ -729,12 +734,14 @@ static int push_update_ref_status(struct strbuf *buf,
729734
}
730735

731736
(*ref)->status = status;
737+
(*ref)->forced_update |= forced;
732738
(*ref)->remote_status = msg;
733739
return !(status == REF_STATUS_OK);
734740
}
735741

736742
static void push_update_refs_status(struct helper_data *data,
737-
struct ref *remote_refs)
743+
struct ref *remote_refs,
744+
int flags)
738745
{
739746
struct strbuf buf = STRBUF_INIT;
740747
struct ref *ref = remote_refs;
@@ -748,7 +755,7 @@ static void push_update_refs_status(struct helper_data *data,
748755
if (push_update_ref_status(&buf, &ref, remote_refs))
749756
continue;
750757

751-
if (!data->refspecs || data->no_private_update)
758+
if (flags & TRANSPORT_PUSH_DRY_RUN || !data->refspecs || data->no_private_update)
752759
continue;
753760

754761
/* propagate back the update to the remote namespace */
@@ -839,7 +846,7 @@ static int push_refs_with_push(struct transport *transport,
839846
sendline(data, &buf);
840847
strbuf_release(&buf);
841848

842-
push_update_refs_status(data, remote_refs);
849+
push_update_refs_status(data, remote_refs, flags);
843850
return 0;
844851
}
845852

@@ -860,6 +867,11 @@ static int push_refs_with_export(struct transport *transport,
860867
die("helper %s does not support dry-run", data->name);
861868
}
862869

870+
if (flags & TRANSPORT_PUSH_FORCE) {
871+
if (set_helper_option(transport, "force", "true") != 0)
872+
warning("helper %s does not support 'force'", data->name);
873+
}
874+
863875
helper = get_helper(transport);
864876

865877
write_constant(helper->in, "export\n");
@@ -881,9 +893,6 @@ static int push_refs_with_export(struct transport *transport,
881893
}
882894
free(private);
883895

884-
if (ref->deletion)
885-
die("remote-helpers do not support ref deletion");
886-
887896
if (ref->peer_ref) {
888897
if (strcmp(ref->peer_ref->name, ref->name))
889898
die("remote-helpers do not support old:new syntax");
@@ -896,7 +905,7 @@ static int push_refs_with_export(struct transport *transport,
896905

897906
if (finish_command(&exporter))
898907
die("Error while running fast-export");
899-
push_update_refs_status(data, remote_refs);
908+
push_update_refs_status(data, remote_refs, flags);
900909
return 0;
901910
}
902911

0 commit comments

Comments
 (0)