git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] branch: optionally setup branch.*.merge from upstream local branches

From
Jay Soffian <jaysoffian@gmail.com>
Date
Feb 18, 2008, 12:04 UTC
Message-ID
<1203336248-9308-1-git-send-email-jaysoffian@gmail.com>

git branch / git checkout -b now honor --track when the upstream branch is local. Previously --track was silently ignored for local upstream branches.

The configuration setting branch.autosetupmerge can now be set to "always" which is equivalent to using --track. Setting branch.autosetupmerge to boolean true will retains the former behavior of only setting up branch.*.merge for remote upstream branches.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
---
On Feb 16, 2008 6:45 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
Show 15 quoted lines
> Hi,
> 
> On Fri, 15 Feb 2008, Junio C Hamano wrote:
> 
> > This area was last cleaned up in 6f084a5 (branch --track: code cleanup
> > and saner handling of local branches).  I do not know if the original
> > intention of the code was to allow a hack like this to work, or it is
> > just an unintended accident that it happens to work.  Dscho, any ideas?
> 
> AFAIR the problem was that you were (rightfully) annoyed when you were
> setting up your local branches, and all of a sudden, they were set up with
> loads of tracking information, cluttering your config.
> 
> Basically, that is the reason why we disallowed tracking information to be
> set up for local branching.

Hopefully this is an acceptable compromise? Junio suggested making this implicit:

   [remote "."]
      fetch = refs/*:refs/*
But I thought that might affect other areas, and I don't think this is too bad.
 branch.c           |   12 ++++++++++--
 branch.h           |    8 +++++++-
 builtin-branch.c   |   11 ++++++++---
 builtin-checkout.c |   15 ++++++++++-----
 4 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/branch.c b/branch.c
index 1fc8788..24e98dd 100644
--- a/branch.c
+++ b/branch.c
@@ -71,7 +71,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)
 
 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;
@@ -130,7 +130,15 @@ void create_branch(const char *head,
 	   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);
+		if (setup_tracking(name, real_ref) == 1 && track == BRANCH_TRACK_ALWAYS) {
+			char key[1024];
+			sprintf(key, "branch.%s.remote", name);
+			git_config_set(key, ".");
+			sprintf(key, "branch.%s.merge", name);
+			git_config_set(key, real_ref);
+			printf("Branch %s set up with upstream branch %s.\n",
+			       name, real_ref);
+		}
 
 	if (write_ref_sha1(lock, sha1, msg) < 0)
 		die("Failed to write ref: %s.", strerror(errno));
diff --git a/branch.h b/branch.h
index d30abe0..771d6ce 100644
--- a/branch.h
+++ b/branch.h
@@ -1,6 +1,12 @@
 #ifndef BRANCH_H
 #define BRANCH_H
 
+enum branch_track {
+	BRANCH_TRACK_FALSE = 0,
+	BRANCH_TRACK_TRUE = 1,
+	BRANCH_TRACK_ALWAYS = 2,
+};
+
 /* Functions for acting on the information about branches. */
 
 /*
@@ -13,7 +19,7 @@
  * branch for (if any).
  */
 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);
 
 /*
  * Remove information about the state of working on the current
diff --git a/builtin-branch.c b/builtin-branch.c
index 5094e0d..231bff4 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -30,7 +30,7 @@ static const char * const builtin_branch_usage[] = {
 static const char *head;
 static unsigned char head_sha1[20];
 
-static int branch_track = 1;
+static enum branch_track branch_track = BRANCH_TRACK_FALSE;
 
 static int branch_use_color;
 static char branch_colors[][COLOR_MAXLEN] = {
@@ -77,6 +77,10 @@ static int git_branch_config(const char *var, const char *value)
 		return 0;
 	}
 	if (!strcmp(var, "branch.autosetupmerge")) {
+		if (value && !strcasecmp(value, "always")) {
+			branch_track = BRANCH_TRACK_ALWAYS;
+			return 0;
+		}
 		branch_track = git_config_bool(var, value);
 		return 0;
 	}
@@ -420,14 +424,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 {
 	int delete = 0, rename = 0, force_create = 0;
 	int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
-	int reflog = 0, track;
+	int reflog = 0;
+	enum branch_track track;
 	int kinds = REF_LOCAL_BRANCH;
 	struct commit_list *with_commit = NULL;
 
 	struct option options[] = {
 		OPT_GROUP("Generic options"),
 		OPT__VERBOSE(&verbose),
-		OPT_BOOLEAN( 0 , "track",  &track, "set up tracking mode (see git-pull(1))"),
+		OPT_SET_INT( 0 , "track",  &track, "set up tracking mode (see git-pull(1))", BRANCH_TRACK_ALWAYS),
 		OPT_BOOLEAN( 0 , "color",  &branch_use_color, "use colored output"),
 		OPT_SET_INT('r', NULL,     &kinds, "act on remote-tracking branches",
 			REF_REMOTE_BRANCH),
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 0d19835..d77ee9c 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -186,7 +186,7 @@ struct checkout_opts {
 
 	char *new_branch;
 	int new_branch_log;
-	int track;
+	enum branch_track track;
 };
 
 struct branch_info {
@@ -521,13 +521,18 @@ static int switch_branches(struct checkout_opts *opts,
 	return post_checkout_hook(old.commit, new->commit, 1);
 }
 
-static int branch_track = 0;
+static enum branch_track branch_track = BRANCH_TRACK_FALSE;
 
 static int git_checkout_config(const char *var, const char *value)
 {
-	if (!strcmp(var, "branch.autosetupmerge"))
+	if (!strcmp(var, "branch.autosetupmerge")) {
+		if (value && !strcasecmp(value, "always")) {
+			branch_track = BRANCH_TRACK_ALWAYS;
+			return 0;
+		}
 		branch_track = git_config_bool(var, value);
-
+		return 0;
+	}
 	return git_default_config(var, value);
 }
 
@@ -542,7 +547,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		OPT__QUIET(&opts.quiet),
 		OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
 		OPT_BOOLEAN('l', NULL, &opts.new_branch_log, "log for new branch"),
-		OPT_BOOLEAN( 0 , "track", &opts.track, "track"),
+		OPT_SET_INT( 0 , "track",  &opts.track, "track", BRANCH_TRACK_ALWAYS),
 		OPT_BOOLEAN('f', NULL, &opts.force, "force"),
 		OPT_BOOLEAN('m', NULL, &opts.merge, "merge"),
 		OPT_END(),
-- 
1.5.4.2.183.g9fe5b
Next: Johannes Schindelin
Message 1 of 4 in “branch: optionally setup branch.*.merge from upstream local branches”
  1. branch: optionally setup branch.*.merge from upstream local branchesJay Soffian, Feb 18, 2008
  2. Johannes SchindelinFeb 18, 2008
  3. Jay SoffianFeb 18, 2008
  4. Johannes SchindelinFeb 18, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.