mirror of
https://github.com/git/git
synced 2024-08-25 02:35:46 +00:00
Add push --set-upstream
Frequent complaint is lack of easy way to set up upstream (tracking) references for git pull to work as part of push command. So add switch --set-upstream (-u) to do just that. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
1f73566af5
commit
e9fcd1e212
|
@ -10,7 +10,7 @@ SYNOPSIS
|
|||
--------
|
||||
[verse]
|
||||
'git push' [--all | --mirror | --tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
|
||||
[--repo=<repository>] [-f | --force] [-v | --verbose]
|
||||
[--repo=<repository>] [-f | --force] [-v | --verbose] [-u | --set-upstream]
|
||||
[<repository> <refspec>...]
|
||||
|
||||
DESCRIPTION
|
||||
|
@ -122,6 +122,13 @@ nor in any Push line of the corresponding remotes file---see below).
|
|||
the name "origin" is used. For this latter case, this option
|
||||
can be used to override the name "origin". In other words,
|
||||
the difference between these two commands
|
||||
|
||||
-u::
|
||||
--set-upstream::
|
||||
For every branch that is up to date or successfully pushed, add
|
||||
upstream (tracking) reference, used by argument-less
|
||||
linkgit:git-pull[1] and other commands. For more information,
|
||||
see 'branch.<name>.merge' in linkgit:git-config[1].
|
||||
+
|
||||
--------------------------
|
||||
git push public #1
|
||||
|
|
|
@ -218,6 +218,8 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
|||
OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
|
||||
OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
|
||||
OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
|
||||
OPT_BIT('u', "set-upstream", &flags, "set upstream for git pull/status",
|
||||
TRANSPORT_PUSH_SET_UPSTREAM),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
|
69
t/t5523-push-upstream.sh
Executable file
69
t/t5523-push-upstream.sh
Executable file
|
@ -0,0 +1,69 @@
|
|||
#!/bin/sh
|
||||
|
||||
test_description='push with --set-upstream'
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'setup bare parent' '
|
||||
git init --bare parent &&
|
||||
git remote add upstream parent
|
||||
'
|
||||
|
||||
test_expect_success 'setup local commit' '
|
||||
echo content >file &&
|
||||
git add file &&
|
||||
git commit -m one
|
||||
'
|
||||
|
||||
check_config() {
|
||||
(echo $2; echo $3) >expect.$1
|
||||
(git config branch.$1.remote
|
||||
git config branch.$1.merge) >actual.$1
|
||||
test_cmp expect.$1 actual.$1
|
||||
}
|
||||
|
||||
test_expect_success 'push -u master:master' '
|
||||
git push -u upstream master:master &&
|
||||
check_config master upstream refs/heads/master
|
||||
'
|
||||
|
||||
test_expect_success 'push -u master:other' '
|
||||
git push -u upstream master:other &&
|
||||
check_config master upstream refs/heads/other
|
||||
'
|
||||
|
||||
test_expect_success 'push -u --dry-run master:otherX' '
|
||||
git push -u --dry-run upstream master:otherX &&
|
||||
check_config master upstream refs/heads/other
|
||||
'
|
||||
|
||||
test_expect_success 'push -u master2:master2' '
|
||||
git branch master2 &&
|
||||
git push -u upstream master2:master2 &&
|
||||
check_config master2 upstream refs/heads/master2
|
||||
'
|
||||
|
||||
test_expect_success 'push -u master2:other2' '
|
||||
git push -u upstream master2:other2 &&
|
||||
check_config master2 upstream refs/heads/other2
|
||||
'
|
||||
|
||||
test_expect_success 'push -u :master2' '
|
||||
git push -u upstream :master2 &&
|
||||
check_config master2 upstream refs/heads/other2
|
||||
'
|
||||
|
||||
test_expect_success 'push -u --all' '
|
||||
git branch all1 &&
|
||||
git branch all2 &&
|
||||
git push -u --all &&
|
||||
check_config all1 upstream refs/heads/all1 &&
|
||||
check_config all2 upstream refs/heads/all2
|
||||
'
|
||||
|
||||
test_expect_success 'push -u HEAD' '
|
||||
git checkout -b headbranch &&
|
||||
git push -u upstream HEAD &&
|
||||
check_config headbranch upstream refs/heads/headbranch
|
||||
'
|
||||
|
||||
test_done
|
56
transport.c
56
transport.c
|
@ -8,6 +8,7 @@
|
|||
#include "bundle.h"
|
||||
#include "dir.h"
|
||||
#include "refs.h"
|
||||
#include "branch.h"
|
||||
|
||||
/* rsync support */
|
||||
|
||||
|
@ -135,6 +136,53 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
|
|||
}
|
||||
}
|
||||
|
||||
static void set_upstreams(struct transport *transport, struct ref *refs,
|
||||
int pretend)
|
||||
{
|
||||
struct ref *ref;
|
||||
for (ref = refs; ref; ref = ref->next) {
|
||||
const char *localname;
|
||||
const char *tmp;
|
||||
const char *remotename;
|
||||
unsigned char sha[20];
|
||||
int flag = 0;
|
||||
/*
|
||||
* Check suitability for tracking. Must be successful /
|
||||
* already up-to-date ref create/modify (not delete).
|
||||
*/
|
||||
if (ref->status != REF_STATUS_OK &&
|
||||
ref->status != REF_STATUS_UPTODATE)
|
||||
continue;
|
||||
if (!ref->peer_ref)
|
||||
continue;
|
||||
if (!ref->new_sha1 || is_null_sha1(ref->new_sha1))
|
||||
continue;
|
||||
|
||||
/* Follow symbolic refs (mainly for HEAD). */
|
||||
localname = ref->peer_ref->name;
|
||||
remotename = ref->name;
|
||||
tmp = resolve_ref(localname, sha, 1, &flag);
|
||||
if (tmp && flag & REF_ISSYMREF &&
|
||||
!prefixcmp(tmp, "refs/heads/"))
|
||||
localname = tmp;
|
||||
|
||||
/* Both source and destination must be local branches. */
|
||||
if (!localname || prefixcmp(localname, "refs/heads/"))
|
||||
continue;
|
||||
if (!remotename || prefixcmp(remotename, "refs/heads/"))
|
||||
continue;
|
||||
|
||||
if (!pretend)
|
||||
install_branch_config(BRANCH_CONFIG_VERBOSE,
|
||||
localname + 11, transport->remote->name,
|
||||
remotename);
|
||||
else
|
||||
printf("Would set upstream of '%s' to '%s' of '%s'\n",
|
||||
localname + 11, remotename + 11,
|
||||
transport->remote->name);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *rsync_url(const char *url)
|
||||
{
|
||||
return prefixcmp(url, "rsync://") ? skip_prefix(url, "rsync:") : url;
|
||||
|
@ -974,6 +1022,10 @@ int transport_push(struct transport *transport,
|
|||
verify_remote_names(refspec_nr, refspec);
|
||||
|
||||
if (transport->push) {
|
||||
/* Maybe FIXME. But no important transport uses this case. */
|
||||
if (flags & TRANSPORT_PUSH_SET_UPSTREAM)
|
||||
die("This transport does not support using --set-upstream");
|
||||
|
||||
return transport->push(transport, refspec_nr, refspec, flags);
|
||||
} else if (transport->push_refs) {
|
||||
struct ref *remote_refs =
|
||||
|
@ -983,6 +1035,7 @@ int transport_push(struct transport *transport,
|
|||
int verbose = flags & TRANSPORT_PUSH_VERBOSE;
|
||||
int quiet = flags & TRANSPORT_PUSH_QUIET;
|
||||
int porcelain = flags & TRANSPORT_PUSH_PORCELAIN;
|
||||
int pretend = flags & TRANSPORT_PUSH_DRY_RUN;
|
||||
int ret;
|
||||
|
||||
if (flags & TRANSPORT_PUSH_ALL)
|
||||
|
@ -1002,6 +1055,9 @@ int transport_push(struct transport *transport,
|
|||
verbose | porcelain, porcelain,
|
||||
nonfastforward);
|
||||
|
||||
if (flags & TRANSPORT_PUSH_SET_UPSTREAM)
|
||||
set_upstreams(transport, remote_refs, pretend);
|
||||
|
||||
if (!(flags & TRANSPORT_PUSH_DRY_RUN)) {
|
||||
struct ref *ref;
|
||||
for (ref = remote_refs; ref; ref = ref->next)
|
||||
|
|
|
@ -91,6 +91,7 @@ struct transport {
|
|||
#define TRANSPORT_PUSH_VERBOSE 16
|
||||
#define TRANSPORT_PUSH_PORCELAIN 32
|
||||
#define TRANSPORT_PUSH_QUIET 64
|
||||
#define TRANSPORT_PUSH_SET_UPSTREAM 128
|
||||
|
||||
/* Returns a transport suitable for the url */
|
||||
struct transport *transport_get(struct remote *, const char *);
|
||||
|
|
Loading…
Reference in a new issue