@matheusbsbs / matheus-bagliano / commits / 9188ed8962
Fork 0

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>

Alex Riesen committed Aug 21, 2008 at 19:23 UTC 9188ed8962ed47c0f41c24eb1317aa07037da545
4 files changed +46 -17
Documentation/git-checkout.txt
+10 -3
@@ -64,9 +64,16 @@ OPTIONS
64 given. Set it to `always` if you want this behavior when the
65 start-point is either a local or remote branch.
66 +
67 -If no '-b' option was given, a name will be made up for you, by stripping
68 -the part up to the first slash of the tracked branch. For example, if you
69 -called 'git checkout --track origin/next', the branch name will be 'next'.
67 +If no '-b' option was given, the name of the new branch will be
68 +derived from the remote branch, by attempting to guess the name
69 +of the branch on remote system. If "remotes/" or "refs/remotes/"
70 +are prefixed, it is stripped away, and then the part up to the
71 +next slash (which would be the nickname of the remote) is removed.
72 +This would tell us to use "hack" as the local branch when branching
73 +off of "origin/hack" (or "remotes/origin/hack", or even
74 +"refs/remotes/origin/hack"). If the given name has no slash, or the above
75 +guessing results in an empty name, the guessing is aborted. You can
76 +exlicitly give a name with '-b' in such a case.
77
78 --no-track::
79 Ignore the branch.autosetupmerge configuration variable.
builtin-checkout.c
+13 -13
@@ -157,7 +157,7 @@ struct checkout_opts {
157 int force;
158 int writeout_error;
159
160 - char *new_branch;
160 + const char *new_branch;
161 int new_branch_log;
162 enum branch_track track;
163 };
@@ -437,27 +437,27 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
437
438 git_config(git_default_config, NULL);
439
440 - opts.track = -1;
440 + opts.track = BRANCH_TRACK_UNSPECIFIED;
441
442 argc = parse_options(argc, argv, options, checkout_usage,
443 PARSE_OPT_KEEP_DASHDASH);
444
445 /* --track without -b should DWIM */
446 - if (opts.track && opts.track != -1 && !opts.new_branch) {
447 - char *slash;
448 - if (!argc || !strcmp(argv[0], "--"))
446 + if (0 < opts.track && !opts.new_branch) {
447 + const char *argv0 = argv[0];
448 + if (!argc || !strcmp(argv0, "--"))
449 die ("--track needs a branch name");
450 - slash = strchr(argv[0], '/');
451 - if (slash && !prefixcmp(argv[0], "refs/"))
452 - slash = strchr(slash + 1, '/');
453 - if (slash && !prefixcmp(argv[0], "remotes/"))
454 - slash = strchr(slash + 1, '/');
455 - if (!slash || !slash[1])
450 + if (!prefixcmp(argv0, "refs/"))
451 + argv0 += 5;
452 + if (!prefixcmp(argv0, "remotes/"))
453 + argv0 += 8;
454 + argv0 = strchr(argv0, '/');
455 + if (!argv0 || !argv0[1])
456 die ("Missing branch name; try -b");
457 - opts.new_branch = slash + 1;
457 + opts.new_branch = argv0 + 1;
458 }
459
460 - if (opts.track == -1)
460 + if (opts.track == BRANCH_TRACK_UNSPECIFIED)
461 opts.track = git_branch_track;
462
463 if (opts.force && opts.merge)
cache.h
+1
@@ -451,6 +451,7 @@ enum safe_crlf {
451 extern enum safe_crlf safe_crlf;
452
453 enum branch_track {
454 + BRANCH_TRACK_UNSPECIFIED = -1,
455 BRANCH_TRACK_NEVER = 0,
456 BRANCH_TRACK_REMOTE,
457 BRANCH_TRACK_ALWAYS,
t/t7201-co.sh
+22 -1
@@ -340,9 +340,30 @@ test_expect_success \
340 test_expect_success \
341 'checkout with --track fakes a sensible -b <name>' '
342 git update-ref refs/remotes/origin/koala/bear renamer &&
343 + git update-ref refs/new/koala/bear renamer &&
344 +
345 git checkout --track origin/koala/bear &&
346 test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
345 - test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"'
347 + test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
348 +
349 + git checkout master && git branch -D koala/bear &&
350 +
351 + git checkout --track refs/remotes/origin/koala/bear &&
352 + test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
353 + test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
354 +
355 + git checkout master && git branch -D koala/bear &&
356 +
357 + git checkout --track remotes/origin/koala/bear &&
358 + test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
359 + test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
360 +
361 + git checkout master && git branch -D koala/bear &&
362 +
363 + git checkout --track refs/new/koala/bear &&
364 + test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
365 + test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"
366 +'
367
368 test_expect_success \
369 'checkout with --track, but without -b, fails with too short tracked name' '