From: Junio C Hamano Date: Wed, 20 Jan 2010 22:40:48 +0000 (-0800) Subject: Merge branch 'il/push-set-upstream' X-Git-Tag: v1.7.0-rc0~71 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/533e8af50ed6e89eabc421478c9021c4da5f404d?ds=inline;hp=-c Merge branch 'il/push-set-upstream' * il/push-set-upstream: Add push --set-upstream Conflicts: transport.c --- 533e8af50ed6e89eabc421478c9021c4da5f404d diff --combined transport.c index d7db2941fb,8cc287d442..7714fdb6c6 --- a/transport.c +++ b/transport.c @@@ -8,6 -8,7 +8,7 @@@ #include "bundle.h" #include "dir.h" #include "refs.h" + #include "branch.h" /* rsync support */ @@@ -135,6 -136,53 +136,53 @@@ static void insert_packed_refs(const ch } } + 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; @@@ -143,7 -191,7 +191,7 @@@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push) { struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT; - struct ref dummy, *tail = &dummy; + struct ref dummy = {0}, *tail = &dummy; struct child_process rsync; const char *args[5]; int temp_dir_len; @@@ -478,7 -526,7 +526,7 @@@ static int fetch_refs_via_pack(struct t args.include_tag = data->options.followtags; args.verbose = (transport->verbose > 0); args.quiet = (transport->verbose < 0); - args.no_progress = args.quiet || (!transport->progress && !isatty(1)); + args.no_progress = args.quiet || (!transport->progress && !isatty(2)); args.depth = data->options.depth; for (i = 0; i < nr_heads; i++) @@@ -974,6 -1022,10 +1022,10 @@@ int transport_push(struct transport *tr 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,7 -1035,8 +1035,8 @@@ 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; + int ret, err; if (flags & TRANSPORT_PUSH_ALL) match_flags |= MATCH_REFS_ALL; @@@ -995,20 -1048,16 +1048,23 @@@ return -1; } + set_ref_status_for_push(remote_refs, + flags & TRANSPORT_PUSH_MIRROR, + flags & TRANSPORT_PUSH_FORCE); + ret = transport->push_refs(transport, remote_refs, flags); + err = push_had_errors(remote_refs); + + ret |= err; - if (!quiet || push_had_errors(remote_refs)) + if (!quiet || err) print_push_status(transport->url, remote_refs, 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) diff --combined transport.h index 7a242fe3bd,c4314dd59b..7cea5cc723 --- a/transport.h +++ b/transport.h @@@ -74,7 -74,7 +74,7 @@@ struct transport int (*disconnect)(struct transport *connection); char *pack_lockfile; signed verbose : 3; - /* Force progress even if the output is not a tty */ + /* Force progress even if stderr is not a tty */ unsigned progress : 1; /* * If transport is at least potentially smart, this points to @@@ -91,6 -91,7 +91,7 @@@ #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 *);