From bb0ceb6264fa1aea6e68e07cb13cd9a88473febb Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 9 Aug 2008 16:00:12 +0200 Subject: [PATCH] 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 Signed-off-by: Junio C Hamano --- Documentation/git-checkout.txt | 10 +++++++++- builtin-checkout.c | 21 ++++++++++++++++++--- t/t7201-co.sh | 11 +++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 5aa69c0e1..43d450254 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -8,7 +8,7 @@ git-checkout - Checkout a branch or paths to the working tree SYNOPSIS -------- [verse] -'git checkout' [-q] [-f] [[--track | --no-track] -b [-l]] [-m] [] +'git checkout' [-q] [-f] [--track | --no-track] [-b [-l]] [-m] [] 'git checkout' [] [--] ... DESCRIPTION @@ -21,6 +21,10 @@ specified, . Using -b will cause to be created; in this case you can use the --track or --no-track options, which will be passed to `git branch`. +As a convenience, --track will default to create a branch whose +name is constructed from the specified branch name by stripping +the first namespace level. + When are given, this command does *not* switch branches. It updates the named paths in the working tree from the index file (i.e. it runs `git checkout-index -f -u`), or @@ -59,6 +63,10 @@ OPTIONS 'git-checkout' and 'git-branch' to always behave as if '--no-track' were 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'. --no-track:: Ignore the branch.autosetupmerge configuration variable. diff --git a/builtin-checkout.c b/builtin-checkout.c index 411cc513c..e95eab9b1 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -437,13 +437,28 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); - opts.track = git_branch_track; + opts.track = -1; argc = parse_options(argc, argv, options, checkout_usage, PARSE_OPT_KEEP_DASHDASH); - if (!opts.new_branch && (opts.track != git_branch_track)) - die("git checkout: --track and --no-track require -b"); + /* --track without -b should DWIM */ + if (opts.track && opts.track != -1 && !opts.new_branch) { + char *slash; + if (!argc || !strcmp(argv[0], "--")) + 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]) + die ("Missing branch name; try -b"); + opts.new_branch = slash + 1; + } + + if (opts.track == -1) + opts.track = git_branch_track; if (opts.force && opts.merge) die("git checkout: -f and -m are incompatible"); diff --git a/t/t7201-co.sh b/t/t7201-co.sh index 9ad5d635a..943dd57aa 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -337,4 +337,15 @@ test_expect_success \ test refs/heads/delete-me = "$(git symbolic-ref HEAD)" && test_must_fail git checkout --track -b track' +test_expect_success \ + 'checkout with --track fakes a sensible -b ' ' + git update-ref refs/remotes/origin/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_expect_success \ + 'checkout with --track, but without -b, fails with too short tracked name' ' + test_must_fail git checkout --track renamer' + test_done -- 2.11.4.GIT