push: add shorthand for --force-with-lease branch creation

Allow the empty string to stand in for the null SHA-1 when pushing a new
branch, like we do when deleting branches.

This means that the following command ensures that `new-branch` is
created on the remote (that is, is must not already exist):

	git push --force-with-lease=new-branch: origin new-branch

Signed-off-by: John Keeping <john@keeping.me.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
John Keeping 2016-07-26 21:44:44 +01:00 committed by Junio C Hamano
parent d132b32b4e
commit eee98e74f9
3 changed files with 30 additions and 1 deletions

View File

@ -201,7 +201,8 @@ if it is going to be updated, by requiring its current value to be
the same as the specified value `<expect>` (which is allowed to be
different from the remote-tracking branch we have for the refname,
or we do not even have to have such a remote-tracking branch when
this form is used).
this form is used). If `<expect>` is the empty string, then the named ref
must not already exist.
+
Note that all forms other than `--force-with-lease=<refname>:<expect>`
that specifies the expected current value of the ref explicitly are

View File

@ -2304,6 +2304,8 @@ int parse_push_cas_option(struct push_cas_option *cas, const char *arg, int unse
entry = add_cas_entry(cas, arg, colon - arg);
if (!*colon)
entry->use_tracking = 1;
else if (!colon[1])
hashclr(entry->expect);
else if (get_sha1(colon + 1, entry->expect))
return error("cannot parse expected object name '%s'", colon + 1);
return 0;

View File

@ -191,4 +191,30 @@ test_expect_success 'cover everything with default force-with-lease (allowed)' '
test_cmp expect actual
'
test_expect_success 'new branch covered by force-with-lease (explicit)' '
setup_srcdst_basic &&
(
cd dst &&
git branch branch master &&
git push --force-with-lease=branch: origin branch
) &&
git ls-remote dst refs/heads/branch >expect &&
git ls-remote src refs/heads/branch >actual &&
test_cmp expect actual
'
test_expect_success 'new branch already exists' '
setup_srcdst_basic &&
(
cd src &&
git checkout -b branch master &&
test_commit c
) &&
(
cd dst &&
git branch branch master &&
test_must_fail git push --force-with-lease=branch: origin branch
)
'
test_done