diff options
author | Jay Soffian <jaysoffian@gmail.com> | 2008-02-19 11:24:37 -0500 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2008-02-19 21:17:45 -0800 |
commit | 9ed36cfa35cfbd09c454f12194a91cd50ba284d1 (patch) | |
tree | db9d61a4a4e47cf8fe6f442f1c46f1d6cce09ae4 /branch.c | |
parent | 569012bf91ddb25220483e8912e079ce8a501525 (diff) | |
download | git-9ed36cfa35cfbd09c454f12194a91cd50ba284d1.tar.gz |
branch: optionally setup branch.*.merge from upstream local branches
"git branch" and "git checkout -b" now honor --track option even when
the upstream branch is local. Previously --track was silently ignored
when forking from a local branch. Also the command did not error out
when --track was explicitly asked for but the forked point specified
was not an existing branch (i.e. when there is no way to set up the
tracking configuration), but now it correctly does.
The configuration setting branch.autosetupmerge can now be set to
"always", which is equivalent to using --track from the command line.
Setting branch.autosetupmerge to "true" will retain the former behavior
of only setting up branch.*.merge for remote upstream branches.
Includes test cases for the new functionality.
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'branch.c')
-rw-r--r-- | branch.c | 44 |
1 files changed, 24 insertions, 20 deletions
@@ -37,7 +37,8 @@ static int find_tracked_branch(struct remote *remote, void *priv) * to infer the settings for branch.<new_ref>.{remote,merge} from the * config. */ -static int setup_tracking(const char *new_ref, const char *orig_ref) +static int setup_tracking(const char *new_ref, const char *orig_ref, + enum branch_track track) { char key[1024]; struct tracking tracking; @@ -48,30 +49,36 @@ static int setup_tracking(const char *new_ref, const char *orig_ref) memset(&tracking, 0, sizeof(tracking)); tracking.spec.dst = (char *)orig_ref; - if (for_each_remote(find_tracked_branch, &tracking) || - !tracking.matches) + if (for_each_remote(find_tracked_branch, &tracking)) return 1; + if (!tracking.matches) + switch (track) { + case BRANCH_TRACK_ALWAYS: + case BRANCH_TRACK_EXPLICIT: + break; + default: + return 1; + } + if (tracking.matches > 1) return error("Not tracking: ambiguous information for ref %s", orig_ref); - if (tracking.matches == 1) { - sprintf(key, "branch.%s.remote", new_ref); - git_config_set(key, tracking.remote ? tracking.remote : "."); - sprintf(key, "branch.%s.merge", new_ref); - git_config_set(key, tracking.src); - free(tracking.src); - printf("Branch %s set up to track remote branch %s.\n", - new_ref, orig_ref); - } + sprintf(key, "branch.%s.remote", new_ref); + git_config_set(key, tracking.remote ? tracking.remote : "."); + sprintf(key, "branch.%s.merge", new_ref); + git_config_set(key, tracking.src ? tracking.src : orig_ref); + free(tracking.src); + printf("Branch %s set up to track %s branch %s.\n", new_ref, + tracking.remote ? "remote" : "local", orig_ref); return 0; } void create_branch(const char *head, const char *name, const char *start_name, - int force, int reflog, int track) + int force, int reflog, enum branch_track track) { struct ref_lock *lock; struct commit *commit; @@ -98,7 +105,8 @@ void create_branch(const char *head, switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) { case 0: /* Not branching from any existing branch */ - real_ref = NULL; + if (track == BRANCH_TRACK_EXPLICIT) + die("Cannot setup tracking information; starting point is not a branch."); break; case 1: /* Unique completion -- good */ @@ -126,17 +134,13 @@ void create_branch(const char *head, snprintf(msg, sizeof msg, "branch: Created from %s", start_name); - /* When branching off a remote branch, set up so that git-pull - automatically merges from there. So far, this is only done for - remotes registered via .git/config. */ if (real_ref && track) - setup_tracking(name, real_ref); + setup_tracking(name, real_ref, track); if (write_ref_sha1(lock, sha1, msg) < 0) die("Failed to write ref: %s.", strerror(errno)); - if (real_ref) - free(real_ref); + free(real_ref); } void remove_branch_state(void) |