[PATCH] Extend "checkout --track" DWIM to support more cases
From: Alex Riesen <hidden>
Date: 2016-06-15 22:45:11
Subsystem:
the rest · Maintainer:
Linus Torvalds
The code handles additionally "refs/remotes/<something>/name", "remotes/<something>/name", and "refs/<namespace>/name". Test cases included. Signed-off-by: Alex Riesen <redacted> --- Johannes has likable ideas :) builtin-checkout.c | 20 +++++++++++++++----- t/t7201-co.sh | 23 ++++++++++++++++++++++- 2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index e95eab9..20466e2 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c@@ -447,11 +447,21 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) 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 (!prefixcmp(argv[0], "remotes/")) + /* skip the name of a remote */ + slash = strchr(argv[0] + 8, '/'); + else if (!prefixcmp(argv[0], "refs/")) { + /* skip namespaces, try use the names of their + * branches, but for the target namespace + * (heads) demand a new name. Also skip the + * first element in "remotes" namespace */ + const char *ns = argv[0] + 5; + slash = !prefixcmp(ns, "heads/") ? NULL: + !prefixcmp(ns, "remotes/") ? + strchr(ns + 8, '/'): strchr(ns, '/'); + } else + /* otherwise - just skip the first element */ + slash = strchr(argv[0], '/'); if (!slash || !slash[1]) die ("Missing branch name; try -b"); opts.new_branch = slash + 1;
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 943dd57..1dff84d 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh@@ -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' '
--
1.6.0.22.g09248