Hi,
I'd like a feature to automatically "transform" a non-tracking local branch into a tracking branch on push. A patch to do that is attached.
Usage:
git branch mybranch git checkout mybranch ... git push --track origin mybranch:mybranch
will not just perform the push, but also write a block
[branch "mybranch"]
remote = origin
merge = refs/heads/mybranchto the git configuration so the branch becomes tracking.
This should be a simpler alternative to the otherwise usual procedure
git push origin mybranch:mybranch git config branch.mybranch.remote origin git config branch.mybranch.merge refs/heads/mybranch
Are there any chances for this getting added to official git - or an alternate convenient way convert a local to a tracking branch?
Best regards,
Rudolf
Show changes to 2 files +31 −0
builtin-push.c, transport.h
diff --git a/builtin-push.c b/builtin-push.c index 28a26e7..8d68646 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -7,6 +7,7 @@ #include "builtin.h" #include "remote.h" #include "transport.h" +#include "branch.h" #include "parse-options.h" static const char * const push_usage[] = { @@ -115,6 +116,33 @@ static int push_with_options(struct transport *transport, int flags) fprintf(stderr, "Pushing to %s\n", transport->url); err = transport_push(transport, refspec_nr, refspec, flags, &nonfastforward); + if (err == 0 && flags & TRANSPORT_PUSH_TRACK) + { + struct ref *remote_refs = + transport->get_refs_list(transport, 1); + struct ref *local_refs = get_local_heads(); + int match_flags = 0; + if (flags & TRANSPORT_PUSH_ALL) + match_flags |= MATCH_REFS_ALL; + if (flags & TRANSPORT_PUSH_MIRROR) + match_flags |= MATCH_REFS_MIRROR; + if(!(flags & TRANSPORT_PUSH_DRY_RUN)) + if(!match_refs(local_refs, &remote_refs, refspec_nr, refspec, match_flags)) + { + struct ref *next = remote_refs; + while(next) + { + if(next->peer_ref && *next->peer_ref->name && *next->name && next->peer_ref->new_sha1 && !is_null_sha1(next->peer_ref->new_sha1)) + { + if (!prefixcmp(next->peer_ref->name, "refs/heads/")) + { + install_branch_config(BRANCH_CONFIG_VERBOSE, next->peer_ref->name + 11, transport->remote->name, next->name); + } + } + next = next->next; + } + } + } if (err != 0) error("failed to push some refs to '%s'", transport->url); @@ -218,6 +246,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('t', "track", &flags, "set up tracking mode (see git-pull(1))", + TRANSPORT_PUSH_TRACK), OPT_END() }; diff --git a/transport.h b/transport.h index 9e74406..8a9c776 100644 --- a/transport.h +++ b/transport.h @@ -74,6 +74,7 @@ struct transport { #define TRANSPORT_PUSH_VERBOSE 16 #define TRANSPORT_PUSH_PORCELAIN 32 #define TRANSPORT_PUSH_QUIET 64 +#define TRANSPORT_PUSH_TRACK 128 /* Returns a transport suitable for the url */ struct transport *transport_get(struct remote *, const char *);