mirror of
https://github.com/git/git
synced 2024-08-24 18:26:02 +00:00
Extend "checkout --track" DWIM to support more cases
The code handles additionally "refs/remotes/<something>/name", "remotes/<something>/name", and "refs/<namespace>/name". Signed-off-by: Alex Riesen <raa.lkml@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
a19a424010
commit
9188ed8962
|
@ -64,9 +64,16 @@ OPTIONS
|
|||
given. Set it to `always` if you want this behavior when the
|
||||
start-point is either a local or remote branch.
|
||||
+
|
||||
If no '-b' option was given, a name will be made up for you, by stripping
|
||||
the part up to the first slash of the tracked branch. For example, if you
|
||||
called 'git checkout --track origin/next', the branch name will be 'next'.
|
||||
If no '-b' option was given, the name of the new branch will be
|
||||
derived from the remote branch, by attempting to guess the name
|
||||
of the branch on remote system. If "remotes/" or "refs/remotes/"
|
||||
are prefixed, it is stripped away, and then the part up to the
|
||||
next slash (which would be the nickname of the remote) is removed.
|
||||
This would tell us to use "hack" as the local branch when branching
|
||||
off of "origin/hack" (or "remotes/origin/hack", or even
|
||||
"refs/remotes/origin/hack"). If the given name has no slash, or the above
|
||||
guessing results in an empty name, the guessing is aborted. You can
|
||||
exlicitly give a name with '-b' in such a case.
|
||||
|
||||
--no-track::
|
||||
Ignore the branch.autosetupmerge configuration variable.
|
||||
|
|
|
@ -157,7 +157,7 @@ struct checkout_opts {
|
|||
int force;
|
||||
int writeout_error;
|
||||
|
||||
char *new_branch;
|
||||
const char *new_branch;
|
||||
int new_branch_log;
|
||||
enum branch_track track;
|
||||
};
|
||||
|
@ -437,27 +437,27 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
opts.track = -1;
|
||||
opts.track = BRANCH_TRACK_UNSPECIFIED;
|
||||
|
||||
argc = parse_options(argc, argv, options, checkout_usage,
|
||||
PARSE_OPT_KEEP_DASHDASH);
|
||||
|
||||
/* --track without -b should DWIM */
|
||||
if (opts.track && opts.track != -1 && !opts.new_branch) {
|
||||
char *slash;
|
||||
if (!argc || !strcmp(argv[0], "--"))
|
||||
if (0 < opts.track && !opts.new_branch) {
|
||||
const char *argv0 = argv[0];
|
||||
if (!argc || !strcmp(argv0, "--"))
|
||||
die ("--track needs a branch name");
|
||||
slash = strchr(argv[0], '/');
|
||||
if (slash && !prefixcmp(argv[0], "refs/"))
|
||||
slash = strchr(slash + 1, '/');
|
||||
if (slash && !prefixcmp(argv[0], "remotes/"))
|
||||
slash = strchr(slash + 1, '/');
|
||||
if (!slash || !slash[1])
|
||||
if (!prefixcmp(argv0, "refs/"))
|
||||
argv0 += 5;
|
||||
if (!prefixcmp(argv0, "remotes/"))
|
||||
argv0 += 8;
|
||||
argv0 = strchr(argv0, '/');
|
||||
if (!argv0 || !argv0[1])
|
||||
die ("Missing branch name; try -b");
|
||||
opts.new_branch = slash + 1;
|
||||
opts.new_branch = argv0 + 1;
|
||||
}
|
||||
|
||||
if (opts.track == -1)
|
||||
if (opts.track == BRANCH_TRACK_UNSPECIFIED)
|
||||
opts.track = git_branch_track;
|
||||
|
||||
if (opts.force && opts.merge)
|
||||
|
|
1
cache.h
1
cache.h
|
@ -451,6 +451,7 @@ enum safe_crlf {
|
|||
extern enum safe_crlf safe_crlf;
|
||||
|
||||
enum branch_track {
|
||||
BRANCH_TRACK_UNSPECIFIED = -1,
|
||||
BRANCH_TRACK_NEVER = 0,
|
||||
BRANCH_TRACK_REMOTE,
|
||||
BRANCH_TRACK_ALWAYS,
|
||||
|
|
|
@ -340,9 +340,30 @@ test_expect_success \
|
|||
test_expect_success \
|
||||
'checkout with --track fakes a sensible -b <name>' '
|
||||
git update-ref refs/remotes/origin/koala/bear renamer &&
|
||||
git update-ref refs/new/koala/bear renamer &&
|
||||
|
||||
git checkout --track origin/koala/bear &&
|
||||
test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
|
||||
test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"'
|
||||
test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
|
||||
|
||||
git checkout master && git branch -D koala/bear &&
|
||||
|
||||
git checkout --track refs/remotes/origin/koala/bear &&
|
||||
test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
|
||||
test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
|
||||
|
||||
git checkout master && git branch -D koala/bear &&
|
||||
|
||||
git checkout --track remotes/origin/koala/bear &&
|
||||
test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
|
||||
test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
|
||||
|
||||
git checkout master && git branch -D koala/bear &&
|
||||
|
||||
git checkout --track refs/new/koala/bear &&
|
||||
test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
|
||||
test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"
|
||||
'
|
||||
|
||||
test_expect_success \
|
||||
'checkout with --track, but without -b, fails with too short tracked name' '
|
||||
|
|
Loading…
Reference in a new issue