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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.