git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Extend "checkout --track" DWIM to support more cases

From
Alex Riesen <raa.lkml@gmail.com>
Date
Aug 21, 2008, 17:23 UTC
Message-ID
<20080821172320.GA5119@blimp.local>
In-Reply-To
<7vd4k3nx7m.fsf@gitster.siamese.dyndns.org>

The code handles additionally "refs/remotes/<something>/name", "remotes/<something>/name", and "refs/<namespace>/name".

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---
Junio C Hamano, Thu, Aug 21, 2008 00:22:21 +0200:
Show 13 quoted lines
> Alex Riesen <raa.lkml@gmail.com> writes:
> > Johannes Schindelin, Wed, Aug 20, 2008 22:16:19 +0200:
> >> > No. It strips refs/ OR remotes/ (because of prefixcmp with argv[0]).
> >> > And I still wanted refs/<namespace>/something...
> >> 
> >> Yes, you are correct.  However, to fix my thinko, I deem this preferable:
> >> 
> >
> > Yes, I agree (and its shorter). The git-checkout manpage can be
> > improved, too (no DWIM is obvious, except may be for the implementor).
> 
> I think that makes sense.  Care to send an appliable patch with
> documentation updates, please?

I just have another quiet evening, so I did that. Johannes, I changed your fix a bit: I see that argv[0] is used later (or if I'm blind and it actually isn't, it may be used in future: I have a feeling that builtint-checkout.c will be popular place).

 Documentation/git-checkout.txt |   18 +++++++++++++++---
 builtin-checkout.c             |   13 ++++++++-----
 t/t7201-co.sh                  |   23 ++++++++++++++++++++++-
 3 files changed, 45 insertions(+), 9 deletions(-)
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 43d4502..d93a18f 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -64,9 +64,21 @@ 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 and use it. The algorithm will remove a
+prefixed refs/ and the part after refs/ up to a slash (that part
+usually being a branch namespace, which makes it confusing to use for
+branch names). If the part after refs/ was remotes/, than a part past
+it is stripped too (it is expected to be the name of remote system).
+Otherwise, the part up to the first slash is removed.
+The algorithm aborts either if the given name has no slashes in it or
+if the part left after stripping the prefixes is empty. In this case,
+the name should be provided with '-b'.
++
+For example, if you called 'git checkout --track origin/next', the
+branch name will be 'next', as it will for 'git checkout --track
+remotes/origin/next'.
 
 --no-track::
 	Ignore the branch.autosetupmerge configuration variable.
diff --git a/builtin-checkout.c b/builtin-checkout.c
index e95eab9..214b0b2 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -445,12 +445,15 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	/* --track without -b should DWIM */
 	if (opts.track && opts.track != -1 && !opts.new_branch) {
 		char *slash;
-		if (!argc || !strcmp(argv[0], "--"))
+		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(argv0, '/');
+		if (slash && !prefixcmp(argv0, "refs/")) {
+			argv0 = slash + 1;
+			slash = strchr(argv0, '/');
+		}
+		if (slash && !prefixcmp(argv0, "remotes/"))
 			slash = strchr(slash + 1, '/');
 		if (!slash || !slash[1])
 			die ("Missing branch name; try -b");
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.59.g8ae62
Previous: Junio C HamanoNext: Junio C Hamano
Message 7 of 11 in “Extend "checkout --track" DWIM to support more cases”
  1. Extend "checkout --track" DWIM to support more casesAlex Riesen, Aug 20, 2008
  2. Johannes SchindelinAug 20, 2008
  3. Alex RiesenAug 20, 2008
  4. Johannes SchindelinAug 20, 2008
  5. Alex RiesenAug 20, 2008
  6. Junio C HamanoAug 20, 2008
  7. Extend "checkout --track" DWIM to support more casesAlex Riesen, Aug 21, 2008
  8. Junio C HamanoAug 22, 2008
  9. Alex RiesenAug 22, 2008
  10. Junio C HamanoAug 22, 2008
  11. Jay SoffianAug 22, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.