Skip to content

Commit fb68242

Browse files
committed
Merge branch 'tk/simple-autosetupmerge' into jch
"git -c branch.autosetupmerge=simple branch $A $B" will set the $B as $A's upstream only when $A and $B shares the same name, and "git -c push.default=simple" on branch $A would push to update the branch $A at the remote $B came from. * tk/simple-autosetupmerge: t3200: tests for new branch.autosetupmerge option "simple" merge: new autosetupmerge option 'simple' for matching branches
2 parents e199128 + 7095267 commit fb68242

File tree

6 files changed

+75
-8
lines changed

6 files changed

+75
-8
lines changed

Documentation/config/branch.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ branch.autoSetupMerge::
99
automatic setup is done when the starting point is either a
1010
local branch or remote-tracking branch; `inherit` -- if the starting point
1111
has a tracking configuration, it is copied to the new
12-
branch. This option defaults to true.
12+
branch; `simple` -- automatic setup is done only when the starting point
13+
is a remote-tracking branch and the new branch has the same name as the
14+
remote branch. This option defaults to true.
1315

1416
branch.autoSetupRebase::
1517
When a new branch is created with 'git branch', 'git switch' or 'git checkout'

Documentation/git-branch.txt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,17 @@ The exact upstream branch is chosen depending on the optional argument:
221221
itself as the upstream; `--track=inherit` means to copy the upstream
222222
configuration of the start-point branch.
223223
+
224-
`--track=direct` is the default when the start point is a remote-tracking branch.
225-
Set the branch.autoSetupMerge configuration variable to `false` if you
226-
want `git switch`, `git checkout` and `git branch` to always behave as if `--no-track`
227-
were given. Set it to `always` if you want this behavior when the
228-
start-point is either a local or remote-tracking branch. Set it to
229-
`inherit` if you want to copy the tracking configuration from the
230-
branch point.
224+
The branch.autoSetupMerge configuration variable specifies how `git switch`,
225+
`git checkout` and `git branch` should behave when neither `--track` nor
226+
`--no-track` are specified:
227+
+
228+
The default option, `true`, behaves as though `--track=direct`
229+
were given whenever the start-point is a remote-tracking branch.
230+
`false` behaves as if `--no-track` were given. `always` behaves as though
231+
`--track=direct` were given. `inherit` behaves as though `--track=inherit`
232+
were given. `simple` behaves as though `--track=direct` were given only when
233+
the start-point is a remote-tracking branch and the new branch has the same
234+
name as the remote branch.
231235
+
232236
See linkgit:git-pull[1] and linkgit:git-config[1] for additional discussion on
233237
how the `branch.<name>.remote` and `branch.<name>.merge` options are used.

branch.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,11 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
273273
goto cleanup;
274274
}
275275

276+
/*
277+
* This check does not apply to the BRANCH_TRACK_INHERIT
278+
* option; you can inherit one or more tracking entries
279+
* and the tracking.matches counter is not incremented.
280+
*/
276281
if (tracking.matches > 1) {
277282
int status = die_message(_("not tracking: ambiguous information for ref '%s'"),
278283
orig_ref);
@@ -307,6 +312,20 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
307312
exit(status);
308313
}
309314

315+
if (track == BRANCH_TRACK_SIMPLE) {
316+
/*
317+
* Only track if remote branch name matches.
318+
* Reaching into items[0].string is safe because
319+
* we know there is at least one and not more than
320+
* one entry (because not BRANCH_TRACK_INHERIT).
321+
*/
322+
const char *tracked_branch;
323+
if (!skip_prefix(tracking.srcs->items[0].string,
324+
"refs/heads/", &tracked_branch) ||
325+
strcmp(tracked_branch, new_ref))
326+
return;
327+
}
328+
310329
if (tracking.srcs->nr < 1)
311330
string_list_append(tracking.srcs, orig_ref);
312331
if (install_branch_config_multiple_remotes(config_flags, new_ref,
@@ -599,6 +618,9 @@ static int submodule_create_branch(struct repository *r,
599618
case BRANCH_TRACK_INHERIT:
600619
strvec_push(&child.args, "--track=inherit");
601620
break;
621+
case BRANCH_TRACK_SIMPLE:
622+
strvec_push(&child.args, "--track=simple");
623+
break;
602624
case BRANCH_TRACK_UNSPECIFIED:
603625
/* Default for "git checkout". Do not pass --track. */
604626
case BRANCH_TRACK_REMOTE:

branch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ enum branch_track {
1212
BRANCH_TRACK_EXPLICIT,
1313
BRANCH_TRACK_OVERRIDE,
1414
BRANCH_TRACK_INHERIT,
15+
BRANCH_TRACK_SIMPLE,
1516
};
1617

1718
extern enum branch_track git_branch_track;

config.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,9 @@ static int git_default_branch_config(const char *var, const char *value)
17831783
} else if (value && !strcmp(value, "inherit")) {
17841784
git_branch_track = BRANCH_TRACK_INHERIT;
17851785
return 0;
1786+
} else if (value && !strcmp(value, "simple")) {
1787+
git_branch_track = BRANCH_TRACK_SIMPLE;
1788+
return 0;
17861789
}
17871790
git_branch_track = git_config_bool(var, value);
17881791
return 0;

t/t3200-branch.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,41 @@ test_expect_success 'branch from tag w/--track causes failure' '
886886
test_must_fail git branch --track my11 foobar
887887
'
888888

889+
test_expect_success 'simple tracking works when remote branch name matches' '
890+
test_create_repo otherserver &&
891+
test_commit -C otherserver my_commit 1 &&
892+
git -C otherserver branch feature &&
893+
git config branch.autosetupmerge simple &&
894+
git config remote.otherserver.url otherserver &&
895+
git config remote.otherserver.fetch refs/heads/*:refs/remotes/otherserver/* &&
896+
git fetch otherserver &&
897+
git branch feature otherserver/feature &&
898+
rm -fr otherserver &&
899+
test $(git config branch.feature.remote) = otherserver &&
900+
test $(git config branch.feature.merge) = refs/heads/feature
901+
'
902+
903+
test_expect_success 'simple tracking skips when remote branch name does not match' '
904+
git config branch.autosetupmerge simple &&
905+
git config remote.local.url . &&
906+
git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
907+
(git show-ref -q refs/remotes/local/main || git fetch local) &&
908+
git branch my-other local/main &&
909+
test -z "$(git config branch.my-other.remote)" &&
910+
test -z "$(git config branch.my-other.merge)"
911+
'
912+
913+
test_expect_success 'simple tracking skips when remote ref is not a branch' '
914+
git config branch.autosetupmerge simple &&
915+
git tag mytag12 main &&
916+
git config remote.localtags.url . &&
917+
git config remote.localtags.fetch refs/tags/*:refs/remotes/localtags/* &&
918+
(git show-ref -q refs/remotes/localtags/mytag12 || git fetch localtags) &&
919+
git branch mytag12 localtags/mytag12 &&
920+
test -z "$(git config branch.mytag12.remote)" &&
921+
test -z "$(git config branch.mytag12.merge)"
922+
'
923+
889924
test_expect_success '--set-upstream-to fails on multiple branches' '
890925
echo "fatal: too many arguments to set new upstream" >expect &&
891926
test_must_fail git branch --set-upstream-to main a b c 2>err &&

0 commit comments

Comments
 (0)