From: Paolo Bonzini <paolo.bonzini@gmail.com>
To: Paolo Bonzini <paolo.bonzini@gmail.com>
Cc: Johannes Schindelin <Johannes.Schindelin@gmx.de>,
Junio C Hamano <junkio@cox.net>,
git@vger.kernel.org
Subject: [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch
Date: Fri, 02 Mar 2007 09:50:06 +0100 [thread overview]
Message-ID: <45E7E53E.5020704@gnu.org> (raw)
In-Reply-To: <45E7DC04.5010701@lu.unisi.ch>
A rather standard (in 1.5) procedure for branching off a remote archive
is:
git checkout -b branchname remote/upstreambranch
git config --add branch.branchname.remote remote
git config --add branch.branchname.merge refs/heads/upstreambranch
In this case, we can save the user some effort if "git branch" (and
"git checkout -b") automatically do the two "git-config --add"s when the
source branch is remote. There is a good chance that some user wants
to merge something different, but in that case they have to specify what
to merge _anyway_.
The behavior is controlled by core.trackremotebranches (off by default;
subject to review later), and can be fine-grained to a specific invocation
of "git branch" using the new --track and --no-track options.
Signed-off-by: Paolo Bonzini <bonzini@gnu.org>
---
Documentation/git-branch.txt | 9 ++++++
builtin-branch.c | 56 ++++++++++++++++++++++++++++++++++++-------
cache.h | 1
config.c | 5 +++
environment.c | 1
5 files changed, 63 insertions(+), 9 deletions(-)
Includes comments by Johannes Schindelin on not using xmalloc for
buffers, and better variable names. Default is "false" in this
version, unlike previous versions.
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index aa1fdd4..4ccbb3c 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git-branch' [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]
-'git-branch' [-l] [-f] <branchname> [<start-point>]
+'git-branch' [--track | --no-track] [-l] [-f] <branchname> [<start-point>]
'git-branch' (-m | -M) [<oldbranch>] <newbranch>
'git-branch' (-d | -D) [-r] <branchname>...
@@ -25,6 +25,13 @@ It will start out with a head equal to the one given as <start-point>.
If no <start-point> is given, the branch will be created with a head
equal to that of the currently checked out branch.
+When a local branch is started off a remote branch, git can setup
+the branch so that gitlink:git-pull[1] will appropriately merge from
+that remote branch. If this behavior is desired, it is possible
+to make it the default using the `core.trackremotebranches` option.
+Otherwise, it can be chosen per-branch using the `--track` and
+`--no-track` options.
+
With a '-m' or '-M' option, <oldbranch> will be renamed to <newbranch>.
If <oldbranch> had a corresponding reflog, it is renamed to match
<newbranch>, and a reflog entry is created to remember the branch
diff --git a/builtin-branch.c b/builtin-branch.c
index d0179b0..96658ff 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -12,7 +12,7 @@
#include "builtin.h"
static const char builtin_branch_usage[] =
- "git-branch [-r] (-d | -D) <branchname> | [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]";
+ "git-branch [-r] (-d | -D) <branchname> | [--track | --no-track] [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length>]]";
#define REF_UNKNOWN_TYPE 0x00
#define REF_LOCAL_BRANCH 0x01
@@ -308,15 +308,34 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
free_ref_list(&ref_list);
}
+static void register_pull (const char *name, const char *remote_branch_name)
+{
+ char *slash = strchr(remote_branch_name, '/');
+ char key[1024], value[1024];
+
+ if (strlen(remote_branch_name) >= 1024 - 11
+ || strlen(name) >= 1024 - 15)
+ die ("what a long branch name you have!");
+
+ snprintf(key, sizeof(key), "branch.%s.remote", name);
+ snprintf(value, sizeof(value), "%.*s", slash - remote_branch_name,
+ remote_branch_name);
+ git_config_set(key, value);
+
+ snprintf(key, sizeof(key), "branch.%s.merge", name);
+ snprintf(value, sizeof(value), "refs/heads/%s", slash + 1);
+ git_config_set(key, value);
+}
+
static void create_branch(const char *name, const char *start_name,
unsigned char *start_sha1,
- int force, int reflog)
+ int force, int reflog, int track)
{
struct ref_lock *lock;
struct commit *commit;
unsigned char sha1[20];
- char ref[PATH_MAX], msg[PATH_MAX + 20];
- int forcing = 0;
+ char *real_ref = NULL, ref[PATH_MAX], msg[PATH_MAX + 20];
+ int forcing = 0, remote = 0;
snprintf(ref, sizeof ref, "refs/heads/%s", name);
if (check_ref_format(ref))
@@ -333,7 +354,9 @@ static void create_branch(const char *name, const char *start_name,
if (start_sha1)
/* detached HEAD */
hashcpy(sha1, start_sha1);
- else if (get_sha1(start_name, sha1))
+ else if (dwim_ref(start_name, strlen (start_name), sha1, &real_ref))
+ remote = !prefixcmp(real_ref, "refs/remotes/");
+ else
die("Not a valid object name: '%s'.", start_name);
if ((commit = lookup_commit_reference(sha1)) == NULL)
@@ -354,8 +377,16 @@ static void create_branch(const char *name, const char *start_name,
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. */
+ if (remote && track)
+ register_pull (name, real_ref + 13);
+
if (write_ref_sha1(lock, sha1, msg) < 0)
die("Failed to write ref: %s.", strerror(errno));
+
+ if (real_ref)
+ free (real_ref);
}
static void rename_branch(const char *oldname, const char *newname, int force)
@@ -397,11 +428,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
int delete = 0, force_delete = 0, force_create = 0;
int rename = 0, force_rename = 0;
int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
- int reflog = 0;
+ int reflog = 0, track;
int kinds = REF_LOCAL_BRANCH;
int i;
git_config(git_branch_config);
+ track = track_remote_branches;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@@ -412,6 +444,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
i++;
break;
}
+ if (!strcmp(arg, "--track")) {
+ track = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--no-track")) {
+ track = 0;
+ continue;
+ }
if (!strcmp(arg, "-d")) {
delete = 1;
continue;
@@ -490,9 +530,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
else if (rename && (i == argc - 2))
rename_branch(argv[i], argv[i + 1], force_rename);
else if (i == argc - 1)
- create_branch(argv[i], head, head_sha1, force_create, reflog);
+ create_branch(argv[i], head, head_sha1, force_create, reflog,
+ track);
else if (i == argc - 2)
- create_branch(argv[i], argv[i+1], NULL, force_create, reflog);
+ create_branch(argv[i], argv[i+1], NULL, force_create, reflog,
+ track);
else
usage(builtin_branch_usage);
diff --git a/cache.h b/cache.h
index 8bbc142..585a9b4 100644
--- a/cache.h
+++ b/cache.h
@@ -205,6 +205,7 @@ extern int trust_executable_bit;
extern int assume_unchanged;
extern int prefer_symlink_refs;
extern int log_all_ref_updates;
+extern int track_remote_branches;
extern int warn_ambiguous_refs;
extern int shared_repository;
extern const char *apply_default_whitespace;
diff --git a/config.c b/config.c
index 0ff413b..49df7bd 100644
--- a/config.c
+++ b/config.c
@@ -294,6 +294,11 @@ int git_default_config(const char *var, const char *value)
return 0;
}
+ if (!strcmp(var, "core.trackremotebranches")) {
+ track_remote_branches = git_config_bool(var, value);
+ return 0;
+ }
+
if (!strcmp(var, "core.legacyheaders")) {
use_legacy_headers = git_config_bool(var, value);
return 0;
diff --git a/environment.c b/environment.c
index 570e32a..e440d05 100644
--- a/environment.c
+++ b/environment.c
@@ -17,6 +17,7 @@ int assume_unchanged;
int prefer_symlink_refs;
int is_bare_repository_cfg = -1; /* unspecified */
int log_all_ref_updates = -1; /* unspecified */
+int track_remote_branches = 0;
int warn_ambiguous_refs = 1;
int repository_format_version;
char *git_commit_encoding;
next prev parent reply other threads:[~2007-03-02 8:50 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-28 14:53 defaults for where to merge from Paolo Bonzini
2007-02-28 15:13 ` Johannes Schindelin
2007-02-28 15:22 ` Andy Parkins
2007-02-28 15:30 ` Paolo Bonzini
2007-02-28 15:43 ` Andy Parkins
2007-02-28 15:30 ` Julian Phillips
2007-02-28 15:46 ` Johannes Schindelin
2007-02-28 17:11 ` Paolo Bonzini
2007-02-28 18:06 ` Johannes Schindelin
2007-03-01 7:52 ` [PATCH] defaults for where to merge from (take 2) Paolo Bonzini
2007-02-28 18:45 ` defaults for where to merge from Alex Riesen
2007-02-28 19:56 ` Paolo Bonzini
2007-03-01 0:07 ` Alex Riesen
2007-03-01 1:25 ` Johannes Schindelin
2007-03-01 7:55 ` Alex Riesen
2007-03-01 8:02 ` Paolo Bonzini
2007-03-01 8:10 ` Alex Riesen
2007-03-01 8:18 ` Junio C Hamano
2007-03-02 15:53 ` J. Bruce Fields
2007-03-01 8:29 ` Paolo Bonzini
2007-03-01 8:33 ` Alex Riesen
2007-03-01 8:45 ` Paolo Bonzini
2007-03-01 8:59 ` Alex Riesen
2007-03-01 9:37 ` [PATCH] defaults for where to merge from (take 3) Paolo Bonzini
2007-03-01 10:12 ` Alex Riesen
2007-03-01 10:17 ` Paolo Bonzini
2007-03-01 10:27 ` Junio C Hamano
2007-03-01 10:42 ` Alex Riesen
2007-03-02 4:49 ` Junio C Hamano
2007-03-02 9:05 ` Alex Riesen
2007-03-02 9:57 ` Junio C Hamano
2007-03-01 10:47 ` Alex Riesen
2007-03-01 16:33 ` [PATCH] defaults for where to merge from (take 3, inline) Paolo Bonzini
2007-03-01 22:01 ` Johannes Schindelin
2007-03-02 8:10 ` Paolo Bonzini
2007-03-02 8:50 ` Paolo Bonzini [this message]
2007-03-02 9:52 ` [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch Junio C Hamano
2007-03-02 9:55 ` Junio C Hamano
2007-03-02 10:32 ` Jeff King
2007-03-02 11:15 ` Paolo Bonzini
2007-03-02 11:21 ` Jeff King
2007-03-02 11:14 ` Paolo Bonzini
2007-03-02 15:54 ` Johannes Schindelin
2007-03-02 16:33 ` Paolo Bonzini
2007-03-02 19:06 ` Johannes Schindelin
2007-03-02 11:19 ` [PATCH] defaults for where to merge from (take 3, inline) Johannes Schindelin
2007-03-02 14:10 ` Jakub Narebski
2007-02-28 17:31 ` defaults for where to merge from Peter Baumann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45E7E53E.5020704@gnu.org \
--to=paolo.bonzini@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).