From: Paolo Bonzini <paolo.bonzini@gmail.com>
To: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Cc: git@vger.kernel.org
Subject: [PATCH] defaults for where to merge from (take 2)
Date: Thu, 01 Mar 2007 08:52:40 +0100 [thread overview]
Message-ID: <45E68648.6090407@lu.unisi.ch> (raw)
In-Reply-To: <Pine.LNX.4.63.0702281903470.22628@wbgn013.biozentrum.uni-wuerzburg.de>
[-- Attachment #1: Type: text/plain, Size: 480 bytes --]
> I'd rather remove the complete section (However, that means that you have
> to introduce a function to do that in config.c)
No problem.
> Also, the second part of your patch would be clearer (methinks) if you
> replaced the call to get_sha1() with dwim_ref(). You'd get the real
> refname for free...
Not only that, my previous version did not work if somebody specified
remotes/remote/upstreambranch instead of remote/upstreambranch.
Updated version attached.
Paolo
[-- Attachment #2: git-builtin-branch-config-2.patch --]
[-- Type: text/plain, Size: 7749 bytes --]
* git-branch: register where to merge from, when branching off a remote branch.
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_.
Dually, we remove the branch.branchname section when the user does
"git branch -d".
diff --git a/builtin-branch.c b/builtin-branch.c
index d0179b0..c1563cf 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -147,8 +147,16 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
error("Error deleting %sbranch '%s'", remote,
argv[i]);
ret = 1;
- } else
+ } else {
+ /* Remove git-config keys. */
+ if (kinds == REF_LOCAL_BRANCH) {
+ char *config_key = xmalloc(strlen(argv[i]) + 8);
+ sprintf(config_key, "branch.%s", argv[i]);
+ git_config_remove_section(config_key);
+ }
+
printf("Deleted %sbranch %s.\n", remote, argv[i]);
+ }
}
@@ -308,6 +316,27 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
free_ref_list(&ref_list);
}
+static void register_branch_pull (const char *name, const char *remote_name)
+{
+ char *slash = strchr(remote_name, '/');
+
+ char *config_key = xmalloc(strlen(name) + 15);
+ char *merge_value = xmalloc(strlen(remote_name) + 10);
+
+ char *remote_value = xstrdup(remote_name);
+ remote_value[slash - remote_name] = 0;
+ sprintf(config_key, "branch.%s.remote", name);
+ git_config_set(config_key, remote_value);
+
+ sprintf(merge_value, "refs/heads/%s", slash + 1);
+ sprintf(config_key, "branch.%s.merge", name);
+ git_config_set(config_key, merge_value);
+
+ free (config_key);
+ free (remote_value);
+ free (merge_value);
+}
+
static void create_branch(const char *name, const char *start_name,
unsigned char *start_sha1,
int force, int reflog)
@@ -315,8 +344,8 @@ static void create_branch(const char *name, const char *start_name,
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 +362,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 +385,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)
+ register_branch_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)
diff --git a/cache.h b/cache.h
index 8bbc142..797483b 100644
--- a/cache.h
+++ b/cache.h
@@ -438,6 +438,7 @@ extern int git_config_bool(const char *, const char *);
extern int git_config_set(const char *, const char *);
extern int git_config_set_multivar(const char *, const char *, const char *, int);
extern int git_config_rename_section(const char *, const char *);
+extern int git_config_remove_section(const char *);
extern int check_repository_format_version(const char *var, const char *value);
#define MAX_GITNAME (1000)
diff --git a/config.c b/config.c
index 0ff413b..acd83aa 100644
--- a/config.c
+++ b/config.c
@@ -854,6 +854,33 @@ write_err_out:
}
+static int section_name_match (const char *buf, const char *name)
+{
+ int i = 0, j = 0, dot = 0;
+ for (; buf[i] && buf[i] != ']'; i++) {
+ if (!dot && isspace(buf[i])) {
+ dot = 1;
+ if (name[j++] != '.')
+ break;
+ for (i++; isspace(buf[i]); i++)
+ ; /* do nothing */
+ if (buf[i] != '"')
+ break;
+ continue;
+ }
+ if (buf[i] == '\\' && dot)
+ i++;
+ else if (buf[i] == '"' && dot) {
+ for (i++; isspace(buf[i]); i++)
+ ; /* do_nothing */
+ break;
+ }
+ if (buf[i] != name[j++])
+ break;
+ }
+ return (buf[i] == ']' && name[j] == 0);
+}
+
int git_config_rename_section(const char *old_name, const char *new_name)
{
int ret = 0;
@@ -885,40 +912,15 @@ int git_config_rename_section(const char *old_name, const char *new_name)
int length;
for (i = 0; buf[i] && isspace(buf[i]); i++)
; /* do nothing */
- if (buf[i] == '[') {
+ if (buf[i] == '[' && section_name_match (&buf[i+1], old_name)) {
/* it's a section */
- int j = 0, dot = 0;
- for (i++; buf[i] && buf[i] != ']'; i++) {
- if (!dot && isspace(buf[i])) {
- dot = 1;
- if (old_name[j++] != '.')
- break;
- for (i++; isspace(buf[i]); i++)
- ; /* do nothing */
- if (buf[i] != '"')
- break;
- continue;
- }
- if (buf[i] == '\\' && dot)
- i++;
- else if (buf[i] == '"' && dot) {
- for (i++; isspace(buf[i]); i++)
- ; /* do_nothing */
- break;
- }
- if (buf[i] != old_name[j++])
- break;
- }
- if (buf[i] == ']' && old_name[j] == 0) {
- /* old_name matches */
- ret++;
- store.baselen = strlen(new_name);
- if (!store_write_section(out_fd, new_name)) {
- ret = write_error();
- goto out;
- }
- continue;
+ ret++;
+ store.baselen = strlen(new_name);
+ if (!store_write_section(out_fd, new_name)) {
+ ret = write_error();
+ goto out;
}
+ continue;
}
length = strlen(buf);
if (write_in_full(out_fd, buf, length) != length) {
@@ -934,3 +936,58 @@ int git_config_rename_section(const char *old_name, const char *new_name)
return ret;
}
+int git_config_remove_section(const char *name)
+{
+ int ret = 0;
+ char *config_filename;
+ struct lock_file *lock = xcalloc(sizeof(struct lock_file), 1);
+ int out_fd;
+ int removing = 0;
+ char buf[1024];
+
+ config_filename = getenv(CONFIG_ENVIRONMENT);
+ if (!config_filename) {
+ config_filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
+ if (!config_filename)
+ config_filename = git_path("config");
+ }
+ config_filename = xstrdup(config_filename);
+ out_fd = hold_lock_file_for_update(lock, config_filename, 0);
+ if (out_fd < 0) {
+ ret = error("Could not lock config file!");
+ goto out;
+ }
+
+ if (!(config_file = fopen(config_filename, "rb"))) {
+ ret = error("Could not open config file!");
+ goto out;
+ }
+
+ while (fgets(buf, sizeof(buf), config_file)) {
+ int i;
+ int length;
+ for (i = 0; buf[i] && isspace(buf[i]); i++)
+ ; /* do nothing */
+ if (buf[i] == '[') {
+ if (section_name_match (&buf[i + 1], name)) {
+ /* name matches */
+ ret++;
+ removing = 1;
+ } else
+ removing = 0;
+ }
+ if (removing)
+ continue;
+ length = strlen(buf);
+ if (write_in_full(out_fd, buf, length) != length) {
+ ret = write_error();
+ goto out;
+ }
+ }
+ fclose(config_file);
+ if (close(out_fd) || commit_lock_file(lock) < 0)
+ ret = error("Cannot commit config file!");
+ out:
+ free(config_filename);
+ return ret;
+}
next prev parent reply other threads:[~2007-03-01 7:53 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 ` Paolo Bonzini [this message]
2007-02-28 18:45 ` 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 ` [PATCH, 4th version] git-branch: register where to merge from, when branching off a remote branch Paolo Bonzini
2007-03-02 9:52 ` 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=45E68648.6090407@lu.unisi.ch \
--to=paolo.bonzini@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
/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).