summaryrefslogtreecommitdiff
path: root/transport.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2010-01-20 22:40:48 (GMT)
committerJunio C Hamano <gitster@pobox.com>2010-01-20 22:40:48 (GMT)
commit533e8af50ed6e89eabc421478c9021c4da5f404d (patch)
tree3eb2af3a9800ee068363e3e267dd2347b884c2bd /transport.c
parent0877510ad4e8b951b08f9cbb25cfc0d994468979 (diff)
parente9fcd1e2121100d43d2d212eb6c6f1fc82aade1d (diff)
downloadgit-533e8af50ed6e89eabc421478c9021c4da5f404d.zip
git-533e8af50ed6e89eabc421478c9021c4da5f404d.tar.gz
git-533e8af50ed6e89eabc421478c9021c4da5f404d.tar.bz2
Merge branch 'il/push-set-upstream'
* il/push-set-upstream: Add push --set-upstream Conflicts: transport.c
Diffstat (limited to 'transport.c')
-rw-r--r--transport.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/transport.c b/transport.c
index d7db294..7714fdb 100644
--- a/transport.c
+++ b/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, err;
if (flags & TRANSPORT_PUSH_ALL)
@@ -1009,6 +1062,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)