checkout --track: make up a sensible branch name if '-b' was omitted
What does the user most likely want with this command? $ git checkout --track origin/next Exactly. A branch called 'next', that tracks origin's branch 'next'. Make it so. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Aug 9, 2008 at 16:00 UTC
bb0ceb6264fa1aea6e68e07cb13cd9a88473febb
3 files changed
+38
-4
Documentation/git-checkout.txt
+9
-1
@@ -8,7 +8,7 @@ git-checkout - Checkout a branch or paths to the working tree
8
SYNOPSIS
9
--------
10
[verse]
11
-'git checkout' [-q] [-f] [[--track | --no-track] -b <new_branch> [-l]] [-m] [<branch>]
11
+'git checkout' [-q] [-f] [--track | --no-track] [-b <new_branch> [-l]] [-m] [<branch>]
12
'git checkout' [<tree-ish>] [--] <paths>...
13
14
DESCRIPTION
@@ -21,6 +21,10 @@ specified, <new_branch>. Using -b will cause <new_branch> to
21
be created; in this case you can use the --track or --no-track
22
options, which will be passed to `git branch`.
23
24
+As a convenience, --track will default to create a branch whose
25
+name is constructed from the specified branch name by stripping
26
+the first namespace level.
27
+
28
When <paths> are given, this command does *not* switch
29
branches. It updates the named paths in the working tree from
30
the index file (i.e. it runs `git checkout-index -f -u`), or
@@ -59,6 +63,10 @@ OPTIONS
63
'git-checkout' and 'git-branch' to always behave as if '--no-track' were
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'.
70
71
--no-track::
72
Ignore the branch.autosetupmerge configuration variable.
builtin-checkout.c
+18
-3
@@ -437,13 +437,28 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
437
438
git_config(git_default_config, NULL);
439
440
- opts.track = git_branch_track;
440
+ opts.track = -1;
441
442
argc = parse_options(argc, argv, options, checkout_usage,
443
PARSE_OPT_KEEP_DASHDASH);
444
445
- if (!opts.new_branch && (opts.track != git_branch_track))
446
- die("git checkout: --track and --no-track require -b");
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], "--"))
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])
456
+ die ("Missing branch name; try -b");
457
+ opts.new_branch = slash + 1;
458
+ }
459
+
460
+ if (opts.track == -1)
461
+ opts.track = git_branch_track;
462
463
if (opts.force && opts.merge)
464
die("git checkout: -f and -m are incompatible");
t/t7201-co.sh
+11
@@ -337,4 +337,15 @@ test_expect_success \
337
test refs/heads/delete-me = "$(git symbolic-ref HEAD)" &&
338
test_must_fail git checkout --track -b track'
339
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 checkout --track origin/koala/bear &&
344
+ test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
345
+ test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"'
346
+
347
+test_expect_success \
348
+ 'checkout with --track, but without -b, fails with too short tracked name' '
349
+ test_must_fail git checkout --track renamer'
350
+
351
test_done