Skip to content

Commit

Permalink
Add push --set-upstream
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ilari Liusvaara authored and Junio C Hamano committed Jan 17, 2010
1 parent 1f73566 commit e9fcd1e
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 1 deletion.
9 changes: 8 additions & 1 deletion Documentation/git-push.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions builtin-push.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
};

Expand Down
69 changes: 69 additions & 0 deletions t/t5523-push-upstream.sh
Original file line number Diff line number Diff line change
@@ -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 changes: 56 additions & 0 deletions transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "bundle.h"
#include "dir.h"
#include "refs.h"
#include "branch.h"

/* rsync support */

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 =
Expand All @@ -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)
Expand 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)
Expand Down
1 change: 1 addition & 0 deletions transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down

0 comments on commit e9fcd1e

Please sign in to comment.