From: Paolo Bonzini <bonzini@gnu.org>
To: <git@vger.kernel.org>
Subject: [PATCH 6/6] branch, checkout: introduce autosetuppush
Date: Sun, 12 Jul 2009 14:17:33 +0200 [thread overview]
Message-ID: <1247401053-20429-7-git-send-email-bonzini@gnu.org> (raw)
In-Reply-To: <1247401053-20429-1-git-send-email-bonzini@gnu.org>
The autosetuppush configuration arranges so that whenever
a merge configuration is setup, a push refspec is added for
the remote.
This is a step towards providing the functionality currently
enabled by push.default=tracking on a per-remote basis, and
without the restriction of pushing a single branch at a time.
Signed-off-by: Paolo Bonzini <bonzini@gnu.org>
---
Documentation/config.txt | 19 +++++++++++++++++++
branch.c | 38 ++++++++++++++++++++++++++++++++++++++
cache.h | 1 +
config.c | 4 ++++
environment.c | 3 ++-
t/t3200-branch.sh | 36 ++++++++++++++++++++++++++++++++++++
6 files changed, 100 insertions(+), 1 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 524a222..4c27e9d 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -475,6 +475,15 @@ branch.autosetupmerge::
done when the starting point is either a local branch or remote
branch. This option defaults to true.
+branch.autosetuppush::
+ Tells 'git-branch' and 'git-checkout' to setup new branches
+ so that linkgit:git-push[1] will push into the starting point
+ branch. Note that this option applies only to branches created
+ from a remote branch, and only if git is setting up merging
+ from the remote branch (via any one of branch.autosetupmerge,
+ remote.<name>.autosetupmerge, or `--track`). This option defaults
+ to false.
+
branch.autosetuprebase::
When a new branch is created with 'git-branch' or 'git-checkout'
that tracks another branch, this variable tells git to set
@@ -1369,6 +1378,16 @@ remote.<name>.autosetupmerge::
starting point branch. If present, this overrides the global
option branch.autosetupmerge, and can have the same settings.
+remote.<name>.autosetuppush::
+ Tells 'git-branch' and 'git-checkout' to setup new branches
+ so that linkgit:git-push[1] will push into the starting point
+ branch. If present, this overrides the global option
+ branch.autosetuppush, and can have the same settings.
+ Note that this option applies only if git is setting
+ up merging from the remote branch (via any one of
+ branch.autosetupmerge, remote.<name>.autosetupmerge, or
+ `--track`).
+
remote.<name>.autosetuprebase::
When a new branch is created with 'git-branch' or 'git-checkout'
that tracks another branch, this variable tells git to set
diff --git a/branch.c b/branch.c
index 8d3e8d8..dfde568 100644
--- a/branch.c
+++ b/branch.c
@@ -51,6 +51,7 @@ void install_branch_config(int flag, const char *local, struct remote *remote,
const char *merge)
{
struct strbuf key = STRBUF_INIT;
+ struct strbuf value = STRBUF_INIT;
int rebasing = should_setup_rebase(remote);
strbuf_addf(&key, "branch.%s.remote", local);
@@ -60,6 +61,13 @@ void install_branch_config(int flag, const char *local, struct remote *remote,
strbuf_addf(&key, "branch.%s.merge", local);
git_config_set(key.buf, merge);
+ if (remote && remote->track.push) {
+ strbuf_reset(&key);
+ strbuf_addf(&key, "remote.%s.push", remote->name);
+ strbuf_addf(&value, "refs/heads/%s:%s", local, merge);
+ git_config_set_multivar(key.buf, value.buf, "^$", 0);
+ }
+
if (rebasing) {
strbuf_reset(&key);
strbuf_addf(&key, "branch.%s.rebase", local);
@@ -83,16 +91,46 @@ void install_branch_config(int flag, const char *local, struct remote *remote,
rebasing ? " by rebasing" : "");
}
strbuf_release(&key);
+ strbuf_release(&value);
+}
+
+static void strbuf_addstr_escape_re (struct strbuf *buf, const char *add)
+{
+ const char *p = add;
+ while ((add = strpbrk(add, ".*?+^$(){}[]")) != NULL) {
+ strbuf_add(buf, p, add - p);
+ strbuf_addf(buf, "\\%c", *add++);
+ p = add;
+ }
+ strbuf_addstr(buf, p);
}
void delete_branch_config (const char *name)
{
struct strbuf buf = STRBUF_INIT;
+ struct strbuf push_re = STRBUF_INIT;
+ struct branch *branch;
+
if (prefixcmp(name, "refs/heads/"))
return;
+
+ /* git config --unset-all remote.foo.push ^\+?refs/heads/bar: */
+ branch = branch_get(name + 11);
+ strbuf_addf(&buf, "remote.%s.push", branch->remote_name);
+ strbuf_addstr(&push_re, "^\\+?");
+ strbuf_addstr_escape_re(&push_re, name);
+ strbuf_addch(&push_re, ':');
+ if (git_config_set_multivar(buf.buf, NULL, push_re.buf, 1) < 0) {
+ warning("Update of config-file failed");
+ goto fail;
+ }
+ strbuf_reset(&buf);
strbuf_addf(&buf, "branch.%s", name + 11);
if (git_config_rename_section(buf.buf, NULL) < 0)
warning("Update of config-file failed");
+
+fail:
+ strbuf_release(&push_re);
strbuf_release(&buf);
}
diff --git a/cache.h b/cache.h
index 703dc45..2d9a864 100644
--- a/cache.h
+++ b/cache.h
@@ -553,6 +553,7 @@ enum push_default_type {
struct tracking_config {
enum branch_track merge;
enum rebase_setup_type rebase;
+ int push;
};
extern struct tracking_config git_branch_track;
diff --git a/config.c b/config.c
index aa695d4..04380bb 100644
--- a/config.c
+++ b/config.c
@@ -556,6 +556,10 @@ int git_tracking_config(const char *var, const char *value, struct tracking_conf
cfg->merge = git_config_bool(var, value);
return 0;
}
+ if (!strcmp(var, ".autosetuppush")) {
+ cfg->push = git_config_bool(var, value);
+ return 0;
+ }
if (!strcmp(var, ".autosetuprebase")) {
if (!value)
value = "always";
diff --git a/environment.c b/environment.c
index 049d269..2b66ac6 100644
--- a/environment.c
+++ b/environment.c
@@ -42,7 +42,8 @@ enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
struct tracking_config git_branch_track = {
BRANCH_TRACK_REMOTE,
- AUTOREBASE_NEVER
+ AUTOREBASE_NEVER,
+ 0
};
enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
#ifndef OBJECT_CREATION_MODE
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 186ba56..5e23cf5 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -233,11 +233,47 @@ test_expect_success 'avoid ambiguous track' '
git branch all1 master &&
test -z "$(git config branch.all1.merge)"
'
+test_expect_success 'test push setup' \
+ 'git config branch.autosetupmerge true &&
+ git config branch.autosetuppush true &&
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch my11 local/master &&
+ test $(git config branch.my11.remote) = local &&
+ test $(git config branch.my11.merge) = refs/heads/master
+ test $(git config remote.local.push) = refs/heads/my11:refs/heads/master
+'
+
+test_expect_success 'test multiple push setups' \
+ 'git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch my12 local/master &&
+ test $(git config branch.my12.remote) = local &&
+ test $(git config branch.my12.merge) = refs/heads/master &&
+ (if git config remote.local.push; then exit 1; else test $? = 2; fi)
+'
+
+test_expect_success 'test push setup cleanup' \
+ 'git config branch.autosetupmerge true &&
+ git config branch.autosetuppush true &&
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ (git branch my11 local/master || :) &&
+ (git branch my12 local/master || :) &&
+ git branch -d my11 &&
+ test $(git config remote.local.push) = refs/heads/my12:refs/heads/master &&
+ git branch -d my12 &&
+ test z$(git config remote.local.push) = z
+'
test_expect_success 'autosetuprebase local on a tracked local branch' '
git config remote.local.url . &&
git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
git config branch.autosetuprebase local &&
+ git config branch.autosetuppush false &&
(git show-ref -q refs/remotes/local/o || git fetch local) &&
git branch mybase &&
git branch --track myr1 mybase &&
--
1.6.2.5
next prev parent reply other threads:[~2009-07-12 12:18 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-12 12:17 [PATCH 0/6] Tracking setup improvements: per-remote config, autosetuppush Paolo Bonzini
2009-07-12 12:17 ` [PATCH 1/6] config: allow false and true values for branch.autosetuprebase Paolo Bonzini
2009-07-12 12:17 ` [PATCH 2/6] branch: install_branch_config and struct tracking refactoring Paolo Bonzini
2009-07-12 12:17 ` [PATCH 3/6] introduce a struct tracking_config Paolo Bonzini
2009-07-12 12:17 ` [PATCH 4/6] remote: add per-remote autosetupmerge and autosetuprebase configuration Paolo Bonzini
2009-07-12 12:17 ` [PATCH 5/6] move deletion of merge configuration to branch.c Paolo Bonzini
2009-07-12 12:17 ` Paolo Bonzini [this message]
2009-07-12 21:17 ` [PATCH 0/6] Tracking setup improvements: per-remote config, autosetuppush Junio C Hamano
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=1247401053-20429-7-git-send-email-bonzini@gnu.org \
--to=bonzini@gnu.org \
--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).