1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-25 07:46:15 +02: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:
Alex Riesen 2008-08-21 19:23:20 +02:00 committed by Junio C Hamano
parent a19a424010
commit 9188ed8962
4 changed files with 46 additions and 17 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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,

View File

@ -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' '