* [PATCH] Allow local branching to set up rebase by default.
@ 2008-04-29 20:49 Dustin Sallings
2008-04-29 21:56 ` Jay Soffian
2008-05-07 16:22 ` Junio C Hamano
0 siblings, 2 replies; 12+ messages in thread
From: Dustin Sallings @ 2008-04-29 20:49 UTC (permalink / raw)
To: git; +Cc: Dustin Sallings
Change cd67e4d4 introduced a new configuration parameter that told
pull to automatically perform a rebase instead of a merge. I use this
feature quite a bit in topic branches and would like it to be the
default behavior for a topic branch.
If the parameter branch.autosetuprebase applies for a branch that's
being created, that branch will have branch.<name>.rebase set to true.
See the documentation for how this may be applied.
New model.
---
Documentation/config.txt | 14 +++++++
branch.c | 26 ++++++++++++-
cache.h | 8 ++++
config.c | 14 +++++++
environment.c | 1 +
t/t3200-branch.sh | 92 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 154 insertions(+), 1 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7a24f6e..1994895 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -393,6 +393,20 @@ branch.autosetupmerge::
done when the starting point is either a local branch or remote
branch. This option defaults to true.
+branch.autosetuprebase::
+ When a new branch is created with `git-branch` or `git-checkout`
+ that tracks another branch, this parameter tells git to set
+ up pull to rebase instead of merge (see "branch.<name>.rebase")
+ below.
+ When `never`, rebase is never automatically set to true.
+ When `local`, rebase is set to true for tracked branches of
+ other local branches.
+ When `remote`, rebase is set to true for tracked branches of
+ remote branches.
+ When `always`, rebase will be set to true for all tracking
+ branches.
+ This option defaults to never.
+
branch.<name>.remote::
When in branch <name>, it tells `git fetch` which remote to fetch.
If this option is not given, `git fetch` defaults to remote "origin".
diff --git a/branch.c b/branch.c
index daf862e..2a731e4 100644
--- a/branch.c
+++ b/branch.c
@@ -32,6 +32,25 @@ static int find_tracked_branch(struct remote *remote, void *priv)
return 0;
}
+static int should_setup_rebase(struct tracking tracking) {
+ int rv=0;
+ switch(autorebase) {
+ case AUTOREBASE_NEVER:
+ rv = 0;
+ break;
+ case AUTOREBASE_LOCAL:
+ rv = tracking.matches == 0;
+ break;
+ case AUTOREBASE_REMOTE:
+ rv = tracking.matches > 0;
+ break;
+ case AUTOREBASE_ALWAYS:
+ rv = 1;
+ break;
+ }
+ return rv;
+}
+
/*
* This is called when new_ref is branched off of orig_ref, and tries
* to infer the settings for branch.<new_ref>.{remote,merge} from the
@@ -69,9 +88,14 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
git_config_set(key, tracking.remote ? tracking.remote : ".");
sprintf(key, "branch.%s.merge", new_ref);
git_config_set(key, tracking.src ? tracking.src : orig_ref);
- free(tracking.src);
printf("Branch %s set up to track %s branch %s.\n", new_ref,
tracking.remote ? "remote" : "local", orig_ref);
+ if (should_setup_rebase(tracking)) {
+ sprintf(key, "branch.%s.rebase", new_ref);
+ git_config_set(key, "true");
+ printf("This branch will rebase on pull.\n");
+ }
+ free(tracking.src);
return 0;
}
diff --git a/cache.h b/cache.h
index 3fcc283..5c9aff8 100644
--- a/cache.h
+++ b/cache.h
@@ -433,7 +433,15 @@ enum branch_track {
BRANCH_TRACK_EXPLICIT,
};
+enum rebase_setup_type {
+ AUTOREBASE_NEVER = 0,
+ AUTOREBASE_LOCAL,
+ AUTOREBASE_REMOTE,
+ AUTOREBASE_ALWAYS,
+};
+
extern enum branch_track git_branch_track;
+extern enum rebase_setup_type autorebase;
#define GIT_REPO_VERSION 0
extern int repository_format_version;
diff --git a/config.c b/config.c
index b0ada51..2959087 100644
--- a/config.c
+++ b/config.c
@@ -487,6 +487,20 @@ int git_default_config(const char *var, const char *value)
git_branch_track = git_config_bool(var, value);
return 0;
}
+ if (!strcmp(var, "branch.autosetuprebase")) {
+ if (!strcmp(value, "never"))
+ autorebase = AUTOREBASE_NEVER;
+ else if (!strcmp(value, "local"))
+ autorebase = AUTOREBASE_LOCAL;
+ else if (!strcmp(value, "remote"))
+ autorebase = AUTOREBASE_REMOTE;
+ else if (!strcmp(value, "always"))
+ autorebase = AUTOREBASE_ALWAYS;
+ else
+ die_bad_config(
+ "Invalid value for branch.autosetupmerge");
+ return 0;
+ }
/* Add other config variables here and to Documentation/config.txt. */
return 0;
diff --git a/environment.c b/environment.c
index 6739a3f..6fb3b97 100644
--- a/environment.c
+++ b/environment.c
@@ -38,6 +38,7 @@ int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */
enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
+enum rebase_setup_type autorebase = 0;
/* This is set by setup_git_dir_gently() and/or git_default_config() */
char *git_work_tree_cfg;
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index cb5f7a4..10bb429 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -224,4 +224,96 @@ test_expect_success 'avoid ambiguous track' '
test -z "$(git config branch.all1.merge)"
'
+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 show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase &&
+ git branch --track myr1 mybase &&
+ test "$(git config branch.myr1.remote)" = . &&
+ test "$(git config branch.myr1.merge)" = refs/heads/mybase &&
+ test "$(git config branch.myr1.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase always on a tracked local branch' \
+ 'git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase always &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase2 &&
+ git branch --track myr2 mybase &&
+ test "$(git config branch.myr2.remote)" = . &&
+ test "$(git config branch.myr2.merge)" = refs/heads/mybase &&
+ test "$(git config branch.myr2.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase remote on a tracked local branch' \
+ 'git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase remote &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase3 &&
+ git branch --track myr3 mybase2 &&
+ test "$(git config branch.myr3.remote)" = . &&
+ test "$(git config branch.myr3.merge)" = refs/heads/mybase2 &&
+ ! test "$(git config branch.myr3.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase never on a tracked local branch' \
+ 'git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase never &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase4 &&
+ git branch --track myr4 mybase2 &&
+ test "$(git config branch.myr4.remote)" = . &&
+ test "$(git config branch.myr4.merge)" = refs/heads/mybase2 &&
+ ! test "$(git config branch.myr4.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase local on a tracked remote branch' \
+ 'git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase local &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr5 local/master &&
+ test "$(git config branch.myr5.remote)" = local &&
+ test "$(git config branch.myr5.merge)" = refs/heads/master &&
+ ! test "$(git config branch.myr5.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase never on a tracked remote branch' \
+ 'git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase never &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr6 local/master &&
+ test "$(git config branch.myr6.remote)" = local &&
+ test "$(git config branch.myr6.merge)" = refs/heads/master &&
+ ! test "$(git config branch.myr6.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase remote on a tracked remote branch' \
+ 'git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase remote &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr7 local/master &&
+ test "$(git config branch.myr7.remote)" = local &&
+ test "$(git config branch.myr7.merge)" = refs/heads/master &&
+ test "$(git config branch.myr7.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase always on a tracked remote branch' \
+ 'git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase remote &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr8 local/master &&
+ test "$(git config branch.myr8.remote)" = local &&
+ test "$(git config branch.myr8.merge)" = refs/heads/master &&
+ test "$(git config branch.myr8.rebase)" = true
+'
+
test_done
--
1.5.5.1.100.g65b98
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] Allow local branching to set up rebase by default.
2008-04-29 20:49 [PATCH] Allow local branching to set up rebase by default Dustin Sallings
@ 2008-04-29 21:56 ` Jay Soffian
[not found] ` <02471C27-C99D-43E7-BC58-50F2B86ED159@spy.net>
2008-05-07 16:22 ` Junio C Hamano
1 sibling, 1 reply; 12+ messages in thread
From: Jay Soffian @ 2008-04-29 21:56 UTC (permalink / raw)
To: Dustin Sallings; +Cc: git
On Tue, Apr 29, 2008 at 4:49 PM, Dustin Sallings <dustin@spy.net> wrote:
> Change cd67e4d4 introduced a new configuration parameter that told
> pull to automatically perform a rebase instead of a merge. I use this
> feature quite a bit in topic branches and would like it to be the
> default behavior for a topic branch.
>
> If the parameter branch.autosetuprebase applies for a branch that's
> being created, that branch will have branch.<name>.rebase set to true.
>
> See the documentation for how this may be applied.
>
I've had this change parked in one of my branches forever. Consider
this a UI suggestion to go with the new config option?
[WIP] new --rebase option to set branch.*.rebase for new branches
Add a --rebase option to git-branch and git-checkout. If given, it
implies --track but additionally sets branch.<newbranch>.rebase to true.
[NOTE TO SELF: this is based off the old next branch, and also it sitting on
top of my old --track changes, so it will need to be reworked.]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Allow local branching to set up rebase by default.
[not found] ` <02471C27-C99D-43E7-BC58-50F2B86ED159@spy.net>
@ 2008-05-07 6:01 ` Dustin Sallings
2008-05-07 15:19 ` Junio C Hamano
0 siblings, 1 reply; 12+ messages in thread
From: Dustin Sallings @ 2008-05-07 6:01 UTC (permalink / raw)
To: Dustin Sallings; +Cc: git
On Apr 29, 2008, at 14:49, Dustin Sallings wrote:
[a patch]
I haven't seen any activity related to this in a week. This
functionality is interesting to my coworkers and a small sampling I've
polled. Does it require any kind of cleanup, will it be completely
rejected, or should I just be more patient? :)
--
Dustin Sallings
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Allow local branching to set up rebase by default.
2008-05-07 6:01 ` Dustin Sallings
@ 2008-05-07 15:19 ` Junio C Hamano
0 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2008-05-07 15:19 UTC (permalink / raw)
To: Dustin Sallings; +Cc: git
Dustin Sallings <dustin@spy.net> writes:
> On Apr 29, 2008, at 14:49, Dustin Sallings wrote:
>
> [a patch]
>
> I haven't seen any activity related to this in a week. This
> functionality is interesting to my coworkers and a small sampling I've
> polled. Does it require any kind of cleanup, will it be completely
> rejected, or should I just be more patient? :)
What happened probably is that nobody on the list found it interesting. I
do not offhand recall what the patch was about.
You cited <02471C27-C99D-43E7-BC58-50F2B86ED159@spy.net> as the original
message that your message is a reply to, but I do not seem to be able to
get it via mail archives. I am guessing you meant this one:
Message-ID: <1209502182-39800-1-git-send-email-dustin@spy.net>
http://news.gmane.org/gmane.comp.version-control.git/80732
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Allow local branching to set up rebase by default.
2008-04-29 20:49 [PATCH] Allow local branching to set up rebase by default Dustin Sallings
2008-04-29 21:56 ` Jay Soffian
@ 2008-05-07 16:22 ` Junio C Hamano
2008-05-08 17:32 ` Dustin Sallings
` (2 more replies)
1 sibling, 3 replies; 12+ messages in thread
From: Junio C Hamano @ 2008-05-07 16:22 UTC (permalink / raw)
To: Dustin Sallings; +Cc: git
Dustin Sallings <dustin@spy.net> writes:
> Change cd67e4d4 introduced a new configuration parameter that told
> pull to automatically perform a rebase instead of a merge. I use this
> feature quite a bit in topic branches and would like it to be the
> default behavior for a topic branch.
>
> If the parameter branch.autosetuprebase applies for a branch that's
> being created, that branch will have branch.<name>.rebase set to true.
>
> See the documentation for how this may be applied.
>
> New model.
> ---
The commit log message is both a sales pitch to get people interested in
your change and an explanation of why the change was needed once it gets
etched into the history.
The above starts out very nicely by stating the background of the change
in the first sentence. However, "I use this ..." is too subjective and
makes others on the list who would comment on it go "Huh, you do? So
what?" and lose interest in the patch. You got no reactions, neither
positive nor negative, partly due to this sentence, I suspect. It would
be better received if you make it less subjective (e.g. 'This can be used
to maintain tidy history of topic branches until they get merged, but
having to say "git pull --rebase" every time is a nuisance.").
With the background and motivation clearly explained, then you would
describe what the change solves and how. The second paragraph is fine.
"See the documentation" is a key phrase to turn off people's interest; you
would never want to say it, for two reasons:
(1) people are busy and first scan only the commit log message without
reading diffs, so that they do not have to waste time on patches that
are ill conceived.
(2) once the change is committed, people read "git log" output to get
overview of the history, and expect the commit log messages to be
sufficient for that purpose.
"See the doc" tells the reader that "What I have here in the commit log is
insufficient and useless; you need to go to the documentation". But that
is not the case for your commit log message --- you gave a very good
overview and ruined it by having this needless sentence. Drop it.
"New model."???
I certainly went "Huh?" and stopped reading when I hit that line.
Please sign-off your patches (see Documentation/SubmittingPatches).
> diff --git a/Documentation/config.txt b/Documentation/config.txt
> index 7a24f6e..1994895 100644
> --- a/Documentation/config.txt
> +++ b/Documentation/config.txt
> @@ -393,6 +393,20 @@ branch.autosetupmerge::
> done when the starting point is either a local branch or remote
> branch. This option defaults to true.
>
> +branch.autosetuprebase::
> + When a new branch is created with `git-branch` or `git-checkout`
> + that tracks another branch, this parameter tells git to set
This is probably not a "parameter" but a "variable".
> + up pull to rebase instead of merge (see "branch.<name>.rebase")
> + below.
"below"?
> + When `never`, rebase is never automatically set to true.
> + When `local`, rebase is set to true for tracked branches of
> + other local branches.
> + When `remote`, rebase is set to true for tracked branches of
> + remote branches.
> + When `always`, rebase will be set to true for all tracking
> + branches.
> + This option defaults to never.
How does this interact with a similarly named configuration option,
autosetupmerge, whose settings can be false, true, and always?
> branch.<name>.remote::
> When in branch <name>, it tells `git fetch` which remote to fetch.
> If this option is not given, `git fetch` defaults to remote "origin".
This is not your fault, but can anybody guess what the exact command
sequence to cause the named branch to be advanced by rebasing, only by
reading this entry?
branch.<name>.rebase::
When true, rebase the branch <name> on top of the fetched branch,
instead of merging the default branch from the default remote.
I can't. Perhaps we would need "when "git pull" is run" or something at
the end.
> diff --git a/branch.c b/branch.c
> index daf862e..2a731e4 100644
> --- a/branch.c
> +++ b/branch.c
> @@ -32,6 +32,25 @@ static int find_tracked_branch(struct remote *remote, void *priv)
> return 0;
> }
>
> +static int should_setup_rebase(struct tracking tracking) {
Style.
- The "{" to start a function body comes at the beginning on its own
line.
- Pass struct (especially a read-only one) by a (const) pointer, not by
value:
static int foo(const struct tracking *tracking)
{
...
> + int rv=0;
Style. s/=/ = /;
> + switch(autorebase) {
Style. s/(/ (/;
> + case AUTOREBASE_NEVER:
> + rv = 0;
> + break;
> + case AUTOREBASE_LOCAL:
> + rv = tracking.matches == 0;
> + break;
Is this correct? Earlier you said "local" is about a branch that trails
other local branches, but this seems to be checking only if the branch is
not tracking anything remote. Would it be possible for this branch to be
not trailing anything, not even local?
The answer turns out to be "no", only because this function
implicitly relies on the fact that setup_tracking() never calls it
if the branch does not track anything, but it was hard to guess
during the first pass.
You might want to check how the setup_tracking() decides when to say
remote/local in its printf().
> + case AUTOREBASE_REMOTE:
> + rv = tracking.matches > 0;
> + break;
This somehow feels awkward because (tracking->matches > 1) is an ambiguous
situation (perhaps a misconfiguration) that setup_tracking() rejects but
you are allowing it here. Admittedly, the former would never call you
when it detects the case, but it still feels awkward...
> + case AUTOREBASE_ALWAYS:
> + rv = 1;
> + break;
> + }
> + return rv;
> +}
After all you might be better off without a temporary variable rv and
return from within the switch().
> diff --git a/cache.h b/cache.h
> index 3fcc283..5c9aff8 100644
> --- a/cache.h
> +++ b/cache.h
> @@ -433,7 +433,15 @@ enum branch_track {
> BRANCH_TRACK_EXPLICIT,
> };
>
> +enum rebase_setup_type {
> + AUTOREBASE_NEVER = 0,
> + AUTOREBASE_LOCAL,
> + AUTOREBASE_REMOTE,
> + AUTOREBASE_ALWAYS,
> +};
> +
> extern enum branch_track git_branch_track;
> +extern enum rebase_setup_type autorebase;
>
> #define GIT_REPO_VERSION 0
> extern int repository_format_version;
> diff --git a/config.c b/config.c
> index b0ada51..2959087 100644
> --- a/config.c
> +++ b/config.c
> @@ -487,6 +487,20 @@ int git_default_config(const char *var, const char *value)
> git_branch_track = git_config_bool(var, value);
> return 0;
> }
> + if (!strcmp(var, "branch.autosetuprebase")) {
> + if (!strcmp(value, "never"))
> + autorebase = AUTOREBASE_NEVER;
Have this in your .git/config:
[branch]
autosetuprebase
and you will strcmp(NULL, "never") here.
> + else if (!strcmp(value, "local"))
> + autorebase = AUTOREBASE_LOCAL;
> + else if (!strcmp(value, "remote"))
> + autorebase = AUTOREBASE_REMOTE;
> + else if (!strcmp(value, "always"))
> + autorebase = AUTOREBASE_ALWAYS;
> + else
> + die_bad_config(
> + "Invalid value for branch.autosetupmerge");
A line slightly longer than 80-cols is better than this artificial line
split, I think.
> diff --git a/environment.c b/environment.c
> index 6739a3f..6fb3b97 100644
> --- a/environment.c
> +++ b/environment.c
> @@ -38,6 +38,7 @@ int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */
> enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
> unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
> enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
> +enum rebase_setup_type autorebase = 0;
Do not initialize to 0; BSS takes care of it. Explicitly initializing to
a symbolic constant, by using AUTOREBASE_NEVER, is very much Ok.
> diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
> index cb5f7a4..10bb429 100755
> --- a/t/t3200-branch.sh
> +++ b/t/t3200-branch.sh
> @@ -224,4 +224,96 @@ test_expect_success 'avoid ambiguous track' '
> test -z "$(git config branch.all1.merge)"
> '
>
> +test_expect_success 'autosetuprebase local on a tracked local branch' \
> + 'git config remote.local.url . &&
Move the opening "'" to the end of the first line so you can lose
backslash there and it becomes easier to read.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Allow local branching to set up rebase by default.
2008-05-07 16:22 ` Junio C Hamano
@ 2008-05-08 17:32 ` Dustin Sallings
2008-05-08 18:23 ` Junio C Hamano
2008-05-08 18:28 ` [PATCH] Allow tracking branches " Dustin Sallings
2008-05-08 18:28 ` [PATCH] Doc: Mention branch.<name>.rebase applies to "git pull" Dustin Sallings
2 siblings, 1 reply; 12+ messages in thread
From: Dustin Sallings @ 2008-05-08 17:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Hi, thanks for the response.
On May 7, 2008, at 9:22, Junio C Hamano wrote:
> You got no reactions, neither
> positive nor negative, partly due to this sentence, I suspect.
I got one response from someone who said he had implemented the same
thing in one of his branches. That seemed to confirm the idea for
me. Some additional features were suggested to be built on top of
this, but I didn't read it as necessary for proceeding.
> Please sign-off your patches (see Documentation/SubmittingPatches).
Oh thanks, I hadn't seen this. I read it as well as the
CodingGuidelines document.
>> + When `never`, rebase is never automatically set to true.
>> + When `local`, rebase is set to true for tracked branches of
>> + other local branches.
>> + When `remote`, rebase is set to true for tracked branches of
>> + remote branches.
>> + When `always`, rebase will be set to true for all tracking
>> + branches.
>> + This option defaults to never.
>
> How does this interact with a similarly named configuration option,
> autosetupmerge, whose settings can be false, true, and always?
I can direct the user to the autosetupmerge config documentation
since it also documents the flags that override its behavior. Is this
acceptable?
>> branch.<name>.remote::
>> When in branch <name>, it tells `git fetch` which remote to fetch.
>> If this option is not given, `git fetch` defaults to remote
>> "origin".
>
> This is not your fault, but can anybody guess what the exact command
> sequence to cause the named branch to be advanced by rebasing, only by
> reading this entry?
>
> branch.<name>.rebase::
> When true, rebase the branch <name> on top of the fetched
> branch,
> instead of merging the default branch from the default
> remote.
>
> I can't. Perhaps we would need "when "git pull" is run" or
> something at
> the end.
I'll submit this as a separate patch.
> Is this correct?
[...]
> You might want to check how the setup_tracking() decides when to say
> remote/local in its printf().
Oh thanks, I clearly didn't understand this and just relied on my
tests passing by coincidence.
I'll resubmit my patch with your recommendations, thanks.
--
Dustin Sallings
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Allow local branching to set up rebase by default.
2008-05-08 17:32 ` Dustin Sallings
@ 2008-05-08 18:23 ` Junio C Hamano
0 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2008-05-08 18:23 UTC (permalink / raw)
To: Dustin Sallings; +Cc: git
Dustin Sallings <dustin@spy.net> writes:
>>> + When `never`, rebase is never automatically set to true.
>>> + When `local`, rebase is set to true for tracked branches of
>>> + other local branches.
>>> + When `remote`, rebase is set to true for tracked branches of
>>> + remote branches.
>>> + When `always`, rebase will be set to true for all tracking
>>> + branches.
>>> + This option defaults to never.
>>
>> How does this interact with a similarly named configuration option,
>> autosetupmerge, whose settings can be false, true, and always?
>
> I can direct the user to the autosetupmerge config
> documentation since it also documents the flags that override its
> behavior. Is this acceptable?
Oh, it was not a request to change the description quoted above but a pure
question -- asking for information. "This new configuration variable is
orthogonal and does not interact with the autosetupmerge", "This takes
effect only the other one decides (or --track is given from the command
line) to make it track", etc. were the expected answers. It might not
hurt to insert "(see branch.<name>.autosetupmerge)" before the comma in
"tracks another branch," below, though...
+branch.autosetuprebase::
+ When a new branch is created with `git-branch` or `git-checkout`
+ that tracks another branch, this parameter tells git to set
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] Allow tracking branches to set up rebase by default.
2008-05-07 16:22 ` Junio C Hamano
2008-05-08 17:32 ` Dustin Sallings
@ 2008-05-08 18:28 ` Dustin Sallings
2008-05-10 18:41 ` Junio C Hamano
2008-05-08 18:28 ` [PATCH] Doc: Mention branch.<name>.rebase applies to "git pull" Dustin Sallings
2 siblings, 1 reply; 12+ messages in thread
From: Dustin Sallings @ 2008-05-08 18:28 UTC (permalink / raw)
To: git; +Cc: gitster, Dustin Sallings
Change cd67e4d4 introduced a new configuration parameter that told
pull to automatically perform a rebase instead of a merge. This
change provides a configuration option to enable this feature
automatically when creating a new branch.
If the variable branch.autosetuprebase applies for a branch that's
being created, that branch will have branch.<name>.rebase set to true.
Signed-off-by: Dustin Sallings <dustin@spy.net>
---
Documentation/config.txt | 15 +++++++
branch.c | 22 ++++++++++-
cache.h | 8 ++++
config.c | 13 ++++++
environment.c | 1 +
t/t3200-branch.sh | 92 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 150 insertions(+), 1 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 00f089f..6413f70 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -399,6 +399,21 @@ branch.autosetupmerge::
done when the starting point is either a local branch or remote
branch. This option defaults to true.
+branch.autosetuprebase::
+ When a new branch is created with `git-branch` or `git-checkout`
+ that tracks another branch, this variable tells git to set
+ up pull to rebase instead of merge (see "branch.<name>.rebase").
+ When `never`, rebase is never automatically set to true.
+ When `local`, rebase is set to true for tracked branches of
+ other local branches.
+ When `remote`, rebase is set to true for tracked branches of
+ remote branches.
+ When `always`, rebase will be set to true for all tracking
+ branches.
+ See "branch.autosetupmerge" for details on how to set up a
+ branch to track another branch.
+ This option defaults to never.
+
branch.<name>.remote::
When in branch <name>, it tells `git fetch` which remote to fetch.
If this option is not given, `git fetch` defaults to remote "origin".
diff --git a/branch.c b/branch.c
index daf862e..56e9492 100644
--- a/branch.c
+++ b/branch.c
@@ -32,6 +32,21 @@ static int find_tracked_branch(struct remote *remote, void *priv)
return 0;
}
+static int should_setup_rebase(const struct tracking *tracking)
+{
+ switch (autorebase) {
+ case AUTOREBASE_NEVER:
+ return 0;
+ case AUTOREBASE_LOCAL:
+ return tracking->remote == NULL;
+ case AUTOREBASE_REMOTE:
+ return tracking->remote != NULL;
+ case AUTOREBASE_ALWAYS:
+ return 1;
+ }
+ return 0;
+}
+
/*
* This is called when new_ref is branched off of orig_ref, and tries
* to infer the settings for branch.<new_ref>.{remote,merge} from the
@@ -69,9 +84,14 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
git_config_set(key, tracking.remote ? tracking.remote : ".");
sprintf(key, "branch.%s.merge", new_ref);
git_config_set(key, tracking.src ? tracking.src : orig_ref);
- free(tracking.src);
printf("Branch %s set up to track %s branch %s.\n", new_ref,
tracking.remote ? "remote" : "local", orig_ref);
+ if (should_setup_rebase(&tracking)) {
+ sprintf(key, "branch.%s.rebase", new_ref);
+ git_config_set(key, "true");
+ printf("This branch will rebase on pull.\n");
+ }
+ free(tracking.src);
return 0;
}
diff --git a/cache.h b/cache.h
index d5d5dad..19f2930 100644
--- a/cache.h
+++ b/cache.h
@@ -434,7 +434,15 @@ enum branch_track {
BRANCH_TRACK_EXPLICIT,
};
+enum rebase_setup_type {
+ AUTOREBASE_NEVER = 0,
+ AUTOREBASE_LOCAL,
+ AUTOREBASE_REMOTE,
+ AUTOREBASE_ALWAYS,
+};
+
extern enum branch_track git_branch_track;
+extern enum rebase_setup_type autorebase;
#define GIT_REPO_VERSION 0
extern int repository_format_version;
diff --git a/config.c b/config.c
index b0ada51..7d76986 100644
--- a/config.c
+++ b/config.c
@@ -487,6 +487,19 @@ int git_default_config(const char *var, const char *value)
git_branch_track = git_config_bool(var, value);
return 0;
}
+ if (value && !strcmp(var, "branch.autosetuprebase")) {
+ if (!strcmp(value, "never"))
+ autorebase = AUTOREBASE_NEVER;
+ else if (!strcmp(value, "local"))
+ autorebase = AUTOREBASE_LOCAL;
+ else if (!strcmp(value, "remote"))
+ autorebase = AUTOREBASE_REMOTE;
+ else if (!strcmp(value, "always"))
+ autorebase = AUTOREBASE_ALWAYS;
+ else
+ die_bad_config("Invalid value for branch.autosetupmerge");
+ return 0;
+ }
/* Add other config variables here and to Documentation/config.txt. */
return 0;
diff --git a/environment.c b/environment.c
index fcd1ee5..4892a30 100644
--- a/environment.c
+++ b/environment.c
@@ -38,6 +38,7 @@ int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */
enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
+enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
/* This is set by setup_git_dir_gently() and/or git_default_config() */
char *git_work_tree_cfg;
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index cb5f7a4..d11dd41 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -224,4 +224,96 @@ test_expect_success 'avoid ambiguous track' '
test -z "$(git config branch.all1.merge)"
'
+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 show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase &&
+ git branch --track myr1 mybase &&
+ test "$(git config branch.myr1.remote)" = . &&
+ test "$(git config branch.myr1.merge)" = refs/heads/mybase &&
+ test "$(git config branch.myr1.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase always on a tracked local branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase always &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase2 &&
+ git branch --track myr2 mybase &&
+ test "$(git config branch.myr2.remote)" = . &&
+ test "$(git config branch.myr2.merge)" = refs/heads/mybase &&
+ test "$(git config branch.myr2.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase remote on a tracked local branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase remote &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase3 &&
+ git branch --track myr3 mybase2 &&
+ test "$(git config branch.myr3.remote)" = . &&
+ test "$(git config branch.myr3.merge)" = refs/heads/mybase2 &&
+ ! test "$(git config branch.myr3.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase never on a tracked local branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase never &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase4 &&
+ git branch --track myr4 mybase2 &&
+ test "$(git config branch.myr4.remote)" = . &&
+ test "$(git config branch.myr4.merge)" = refs/heads/mybase2 &&
+ ! test "$(git config branch.myr4.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase local on a tracked remote branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase local &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr5 local/master &&
+ test "$(git config branch.myr5.remote)" = local &&
+ test "$(git config branch.myr5.merge)" = refs/heads/master &&
+ ! test "$(git config branch.myr5.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase never on a tracked remote branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase never &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr6 local/master &&
+ test "$(git config branch.myr6.remote)" = local &&
+ test "$(git config branch.myr6.merge)" = refs/heads/master &&
+ ! test "$(git config branch.myr6.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase remote on a tracked remote branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase remote &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr7 local/master &&
+ test "$(git config branch.myr7.remote)" = local &&
+ test "$(git config branch.myr7.merge)" = refs/heads/master &&
+ test "$(git config branch.myr7.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase always on a tracked remote branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase remote &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr8 local/master &&
+ test "$(git config branch.myr8.remote)" = local &&
+ test "$(git config branch.myr8.merge)" = refs/heads/master &&
+ test "$(git config branch.myr8.rebase)" = true
+'
+
test_done
--
1.5.5.1.100.g65b98
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH] Doc: Mention branch.<name>.rebase applies to "git pull"
2008-05-07 16:22 ` Junio C Hamano
2008-05-08 17:32 ` Dustin Sallings
2008-05-08 18:28 ` [PATCH] Allow tracking branches " Dustin Sallings
@ 2008-05-08 18:28 ` Dustin Sallings
2 siblings, 0 replies; 12+ messages in thread
From: Dustin Sallings @ 2008-05-08 18:28 UTC (permalink / raw)
To: git; +Cc: gitster, Dustin Sallings
Signed-off-by: Dustin Sallings <dustin@spy.net>
---
Documentation/config.txt | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 6413f70..44bd20b 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -441,7 +441,8 @@ branch.<name>.mergeoptions::
branch.<name>.rebase::
When true, rebase the branch <name> on top of the fetched branch,
- instead of merging the default branch from the default remote.
+ instead of merging the default branch from the default remote when
+ "git pull" is run.
*NOTE*: this is a possibly dangerous operation; do *not* use
it unless you understand the implications (see linkgit:git-rebase[1]
for details).
--
1.5.5.1.100.g65b98
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] Allow tracking branches to set up rebase by default.
2008-05-08 18:28 ` [PATCH] Allow tracking branches " Dustin Sallings
@ 2008-05-10 18:41 ` Junio C Hamano
2008-05-10 22:36 ` Dustin Sallings
2008-05-10 22:36 ` Dustin Sallings
0 siblings, 2 replies; 12+ messages in thread
From: Junio C Hamano @ 2008-05-10 18:41 UTC (permalink / raw)
To: Dustin Sallings; +Cc: git
The patch is looking better.
I'd suggest further fixes like the attached patch to address the following
issues:
- Do not ignore misconfiguration, but diagnose it.
- die_bad_config() takes a variable name without surrounding explanatory
text. If you actually tested your patch and looked at the error
message, it would have been blatantly obvious and you would have
noticed it. Not a good sign.
- Test not just the success cases but failure cases; test not just
explicitly configured cases but also default cases.
The last one is something everybody tends to forget, but is very
important. It is human nature that anybody would eagerly want to
demonstrate what new things their shiny new toy does, but would forget to
make sure that it does not take effect when people do not want it (either
saying 'never' which you do have test, which is good, or not asking for it
by not setting the variable, which you didn't). You'd notice that I
played lazy and added a check for only the "tracked remote" case when the
new variable is left unspecified, but you might want to add tests for
other variants. Also I suspect that we would want to test cases where
autosetuprebase is given but autosetupmerge is not.
Another thing we might want to address is to move parsing of branch.*
configuration variables out of git_default_config(). They are unnecessary
for majority of commands that do not create new branches. But that would
be a separate topic if we were to do so.
config.c | 8 +++++---
t/t3200-branch.sh | 24 ++++++++++++++++++++++++
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/config.c b/config.c
index 7d76986..cf2bfd3 100644
--- a/config.c
+++ b/config.c
@@ -487,8 +487,10 @@ int git_default_config(const char *var, const char *value)
git_branch_track = git_config_bool(var, value);
return 0;
}
- if (value && !strcmp(var, "branch.autosetuprebase")) {
- if (!strcmp(value, "never"))
+ if (!strcmp(var, "branch.autosetuprebase")) {
+ if (!value)
+ return config_error_nonbool(var);
+ else if (!strcmp(value, "never"))
autorebase = AUTOREBASE_NEVER;
else if (!strcmp(value, "local"))
autorebase = AUTOREBASE_LOCAL;
@@ -497,7 +499,7 @@ int git_default_config(const char *var, const char *value)
else if (!strcmp(value, "always"))
autorebase = AUTOREBASE_ALWAYS;
else
- die_bad_config("Invalid value for branch.autosetupmerge");
+ return error("Malformed value for %s", var);
return 0;
}
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index d11dd41..5cfeaa7 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -144,6 +144,18 @@ test_expect_success 'test tracking setup (non-wildcard, not matching)' \
! test "$(git config branch.my5.remote)" = local &&
! test "$(git config branch.my5.merge)" = refs/heads/master'
+test_expect_success 'detect misconfigured autosetuprebase' '
+ git config branch.autosetuprebase garbage &&
+ test_must_fail git branch
+'
+
+test_expect_success 'detect misconfigured autosetuprebase' '
+ git config --unset branch.autosetuprebase &&
+ echo "[branch] autosetuprebase" >>.git/config &&
+ test_must_fail git branch &&
+ git config --unset branch.autosetuprebase
+'
+
test_expect_success 'test tracking setup via config' \
'git config branch.autosetupmerge true &&
git config remote.local.url . &&
@@ -316,4 +328,16 @@ test_expect_success 'autosetuprebase always on a tracked remote branch' '
test "$(git config branch.myr8.rebase)" = true
'
+test_expect_success 'without autosetuprebase' '
+ git config --unset branch.autosetuprebase
+
+ 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 --track myr9 local/master &&
+ test "$(git config branch.myr9.remote)" = local &&
+ test "$(git config branch.myr9.merge)" = refs/heads/master &&
+ test "z$(git config branch.myr9.rebase)" = "z"
+'
+
test_done
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] Allow tracking branches to set up rebase by default.
2008-05-10 18:41 ` Junio C Hamano
@ 2008-05-10 22:36 ` Dustin Sallings
2008-05-10 22:36 ` Dustin Sallings
1 sibling, 0 replies; 12+ messages in thread
From: Dustin Sallings @ 2008-05-10 22:36 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On May 10, 2008, at 11:41, Junio C Hamano wrote:
> - die_bad_config() takes a variable name without surrounding
> explanatory
> text. If you actually tested your patch and looked at the error
> message, it would have been blatantly obvious and you would have
> noticed it. Not a good sign.
>
> - Test not just the success cases but failure cases; test not just
> explicitly configured cases but also default cases.
You're right, I didn't test misconfiguration cases. I've updated the
patch per your recommendations with a lot more tests and have manually
tested the error messages to ensure they make sense.
Does it make sense in the cases where a value is bad to list the
valid values? I don't see a precedent (so I don't know what format
would be most desirable), but it might be friendly.
> Also I suspect that we would want to test cases where
> autosetuprebase is given but autosetupmerge is not.
This code isn't so much dependent on that variable, but on the
effects of that variable, which may be overridden by the --track and --
no-track parameters. I think it'd be best to leave the effects of
that variable in its own tests wrt tracking since this code doesn't
kick in until after the tracking is set up.
> Another thing we might want to address is to move parsing of branch.*
> configuration variables out of git_default_config(). They are
> unnecessary
> for majority of commands that do not create new branches. But that
> would
> be a separate topic if we were to do so.
I agree with this. I tried initially to not have it be part of the
default config parser, but it seemed a lot more disruptive, so I just
followed autosetupmerge.
Thanks for your input again. New patch to follow.
--
Dustin Sallings
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] Allow tracking branches to set up rebase by default.
2008-05-10 18:41 ` Junio C Hamano
2008-05-10 22:36 ` Dustin Sallings
@ 2008-05-10 22:36 ` Dustin Sallings
1 sibling, 0 replies; 12+ messages in thread
From: Dustin Sallings @ 2008-05-10 22:36 UTC (permalink / raw)
To: git; +Cc: gitster, Dustin Sallings
Change cd67e4d4 introduced a new configuration parameter that told
pull to automatically perform a rebase instead of a merge. This
change provides a configuration option to enable this feature
automatically when creating a new branch.
If the variable branch.autosetuprebase applies for a branch that's
being created, that branch will have branch.<name>.rebase set to true.
Signed-off-by: Dustin Sallings <dustin@spy.net>
---
Documentation/config.txt | 15 +++
branch.c | 22 ++++-
cache.h | 8 ++
config.c | 15 +++
environment.c | 1 +
t/t3200-branch.sh | 234 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 294 insertions(+), 1 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index a6fc5a2..217980f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -399,6 +399,21 @@ branch.autosetupmerge::
done when the starting point is either a local branch or remote
branch. This option defaults to true.
+branch.autosetuprebase::
+ When a new branch is created with `git-branch` or `git-checkout`
+ that tracks another branch, this variable tells git to set
+ up pull to rebase instead of merge (see "branch.<name>.rebase").
+ When `never`, rebase is never automatically set to true.
+ When `local`, rebase is set to true for tracked branches of
+ other local branches.
+ When `remote`, rebase is set to true for tracked branches of
+ remote branches.
+ When `always`, rebase will be set to true for all tracking
+ branches.
+ See "branch.autosetupmerge" for details on how to set up a
+ branch to track another branch.
+ This option defaults to never.
+
branch.<name>.remote::
When in branch <name>, it tells `git fetch` which remote to fetch.
If this option is not given, `git fetch` defaults to remote "origin".
diff --git a/branch.c b/branch.c
index daf862e..56e9492 100644
--- a/branch.c
+++ b/branch.c
@@ -32,6 +32,21 @@ static int find_tracked_branch(struct remote *remote, void *priv)
return 0;
}
+static int should_setup_rebase(const struct tracking *tracking)
+{
+ switch (autorebase) {
+ case AUTOREBASE_NEVER:
+ return 0;
+ case AUTOREBASE_LOCAL:
+ return tracking->remote == NULL;
+ case AUTOREBASE_REMOTE:
+ return tracking->remote != NULL;
+ case AUTOREBASE_ALWAYS:
+ return 1;
+ }
+ return 0;
+}
+
/*
* This is called when new_ref is branched off of orig_ref, and tries
* to infer the settings for branch.<new_ref>.{remote,merge} from the
@@ -69,9 +84,14 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
git_config_set(key, tracking.remote ? tracking.remote : ".");
sprintf(key, "branch.%s.merge", new_ref);
git_config_set(key, tracking.src ? tracking.src : orig_ref);
- free(tracking.src);
printf("Branch %s set up to track %s branch %s.\n", new_ref,
tracking.remote ? "remote" : "local", orig_ref);
+ if (should_setup_rebase(&tracking)) {
+ sprintf(key, "branch.%s.rebase", new_ref);
+ git_config_set(key, "true");
+ printf("This branch will rebase on pull.\n");
+ }
+ free(tracking.src);
return 0;
}
diff --git a/cache.h b/cache.h
index 7fb8f33..3442130 100644
--- a/cache.h
+++ b/cache.h
@@ -434,7 +434,15 @@ enum branch_track {
BRANCH_TRACK_EXPLICIT,
};
+enum rebase_setup_type {
+ AUTOREBASE_NEVER = 0,
+ AUTOREBASE_LOCAL,
+ AUTOREBASE_REMOTE,
+ AUTOREBASE_ALWAYS,
+};
+
extern enum branch_track git_branch_track;
+extern enum rebase_setup_type autorebase;
#define GIT_REPO_VERSION 0
extern int repository_format_version;
diff --git a/config.c b/config.c
index b0ada51..cf2bfd3 100644
--- a/config.c
+++ b/config.c
@@ -487,6 +487,21 @@ int git_default_config(const char *var, const char *value)
git_branch_track = git_config_bool(var, value);
return 0;
}
+ if (!strcmp(var, "branch.autosetuprebase")) {
+ if (!value)
+ return config_error_nonbool(var);
+ else if (!strcmp(value, "never"))
+ autorebase = AUTOREBASE_NEVER;
+ else if (!strcmp(value, "local"))
+ autorebase = AUTOREBASE_LOCAL;
+ else if (!strcmp(value, "remote"))
+ autorebase = AUTOREBASE_REMOTE;
+ else if (!strcmp(value, "always"))
+ autorebase = AUTOREBASE_ALWAYS;
+ else
+ return error("Malformed value for %s", var);
+ return 0;
+ }
/* Add other config variables here and to Documentation/config.txt. */
return 0;
diff --git a/environment.c b/environment.c
index fcd1ee5..4892a30 100644
--- a/environment.c
+++ b/environment.c
@@ -38,6 +38,7 @@ int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */
enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
+enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
/* This is set by setup_git_dir_gently() and/or git_default_config() */
char *git_work_tree_cfg;
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index cb5f7a4..8d87686 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -224,4 +224,238 @@ test_expect_success 'avoid ambiguous track' '
test -z "$(git config branch.all1.merge)"
'
+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 show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase &&
+ git branch --track myr1 mybase &&
+ test "$(git config branch.myr1.remote)" = . &&
+ test "$(git config branch.myr1.merge)" = refs/heads/mybase &&
+ test "$(git config branch.myr1.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase always on a tracked local branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase always &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase2 &&
+ git branch --track myr2 mybase &&
+ test "$(git config branch.myr2.remote)" = . &&
+ test "$(git config branch.myr2.merge)" = refs/heads/mybase &&
+ test "$(git config branch.myr2.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase remote on a tracked local branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase remote &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase3 &&
+ git branch --track myr3 mybase2 &&
+ test "$(git config branch.myr3.remote)" = . &&
+ test "$(git config branch.myr3.merge)" = refs/heads/mybase2 &&
+ ! test "$(git config branch.myr3.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase never on a tracked local branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase never &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase4 &&
+ git branch --track myr4 mybase2 &&
+ test "$(git config branch.myr4.remote)" = . &&
+ test "$(git config branch.myr4.merge)" = refs/heads/mybase2 &&
+ ! test "$(git config branch.myr4.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase local on a tracked remote branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase local &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr5 local/master &&
+ test "$(git config branch.myr5.remote)" = local &&
+ test "$(git config branch.myr5.merge)" = refs/heads/master &&
+ ! test "$(git config branch.myr5.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase never on a tracked remote branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase never &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr6 local/master &&
+ test "$(git config branch.myr6.remote)" = local &&
+ test "$(git config branch.myr6.merge)" = refs/heads/master &&
+ ! test "$(git config branch.myr6.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase remote on a tracked remote branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase remote &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr7 local/master &&
+ test "$(git config branch.myr7.remote)" = local &&
+ test "$(git config branch.myr7.merge)" = refs/heads/master &&
+ test "$(git config branch.myr7.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase always on a tracked remote branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git config branch.autosetuprebase remote &&
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
+ git branch --track myr8 local/master &&
+ test "$(git config branch.myr8.remote)" = local &&
+ test "$(git config branch.myr8.merge)" = refs/heads/master &&
+ test "$(git config branch.myr8.rebase)" = true
+'
+
+test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' '
+ git config --unset branch.autosetuprebase &&
+ 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 --track myr9 local/master &&
+ test "$(git config branch.myr9.remote)" = local &&
+ test "$(git config branch.myr9.merge)" = refs/heads/master &&
+ test "z$(git config branch.myr9.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase unconfigured on a tracked local branch' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
+ git branch mybase10 &&
+ git branch --track myr10 mybase2 &&
+ test "$(git config branch.myr10.remote)" = . &&
+ test "$(git config branch.myr10.merge)" = refs/heads/mybase2 &&
+ test "z$(git config branch.myr10.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase unconfigured on untracked local branch' '
+ 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 --no-track myr11 mybase2 &&
+ test "z$(git config branch.myr11.remote)" = z &&
+ test "z$(git config branch.myr11.merge)" = z &&
+ test "z$(git config branch.myr11.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase unconfigured on untracked remote branch' '
+ 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 --no-track myr12 local/master &&
+ test "z$(git config branch.myr12.remote)" = z &&
+ test "z$(git config branch.myr12.merge)" = z &&
+ test "z$(git config branch.myr12.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase never on an untracked local branch' '
+ git config branch.autosetuprebase never &&
+ 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 --no-track myr13 mybase2 &&
+ test "z$(git config branch.myr13.remote)" = z &&
+ test "z$(git config branch.myr13.merge)" = z &&
+ test "z$(git config branch.myr13.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase local on an untracked local branch' '
+ git config branch.autosetuprebase local &&
+ 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 --no-track myr14 mybase2 &&
+ test "z$(git config branch.myr14.remote)" = z &&
+ test "z$(git config branch.myr14.merge)" = z &&
+ test "z$(git config branch.myr14.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase remote on an untracked local branch' '
+ git config branch.autosetuprebase remote &&
+ 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 --no-track myr15 mybase2 &&
+ test "z$(git config branch.myr15.remote)" = z &&
+ test "z$(git config branch.myr15.merge)" = z &&
+ test "z$(git config branch.myr15.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase always on an untracked local branch' '
+ git config branch.autosetuprebase always &&
+ 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 --no-track myr16 mybase2 &&
+ test "z$(git config branch.myr16.remote)" = z &&
+ test "z$(git config branch.myr16.merge)" = z &&
+ test "z$(git config branch.myr16.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase never on an untracked remote branch' '
+ git config branch.autosetuprebase never &&
+ 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 --no-track myr17 local/master &&
+ test "z$(git config branch.myr17.remote)" = z &&
+ test "z$(git config branch.myr17.merge)" = z &&
+ test "z$(git config branch.myr17.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase local on an untracked remote branch' '
+ git config branch.autosetuprebase local &&
+ 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 --no-track myr18 local/master &&
+ test "z$(git config branch.myr18.remote)" = z &&
+ test "z$(git config branch.myr18.merge)" = z &&
+ test "z$(git config branch.myr18.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase remote on an untracked remote branch' '
+ git config branch.autosetuprebase remote &&
+ 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 --no-track myr19 local/master &&
+ test "z$(git config branch.myr19.remote)" = z &&
+ test "z$(git config branch.myr19.merge)" = z &&
+ test "z$(git config branch.myr19.rebase)" = z
+'
+
+test_expect_success 'autosetuprebase always on an untracked remote branch' '
+ git config branch.autosetuprebase always &&
+ 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 --no-track myr20 local/master &&
+ test "z$(git config branch.myr20.remote)" = z &&
+ test "z$(git config branch.myr20.merge)" = z &&
+ test "z$(git config branch.myr20.rebase)" = z
+'
+
+test_expect_success 'detect misconfigured autosetuprebase (bad value)' '
+ git config branch.autosetuprebase garbage &&
+ test_must_fail git branch
+'
+
+test_expect_success 'detect misconfigured autosetuprebase (no value)' '
+ git config --unset branch.autosetuprebase &&
+ echo "[branch] autosetuprebase" >> .git/config &&
+ test_must_fail git branch &&
+ git config --unset branch.autosetuprebase
+'
+
test_done
--
1.5.5.1.179.g0325e.dirty
^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2008-05-10 22:37 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-29 20:49 [PATCH] Allow local branching to set up rebase by default Dustin Sallings
2008-04-29 21:56 ` Jay Soffian
[not found] ` <02471C27-C99D-43E7-BC58-50F2B86ED159@spy.net>
2008-05-07 6:01 ` Dustin Sallings
2008-05-07 15:19 ` Junio C Hamano
2008-05-07 16:22 ` Junio C Hamano
2008-05-08 17:32 ` Dustin Sallings
2008-05-08 18:23 ` Junio C Hamano
2008-05-08 18:28 ` [PATCH] Allow tracking branches " Dustin Sallings
2008-05-10 18:41 ` Junio C Hamano
2008-05-10 22:36 ` Dustin Sallings
2008-05-10 22:36 ` Dustin Sallings
2008-05-08 18:28 ` [PATCH] Doc: Mention branch.<name>.rebase applies to "git pull" Dustin Sallings
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).