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

Re: [PATCH 2/2] checkout: introduce "--to-branch" option

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Dec 10, 2021, 08:59 UTC
Message-ID
<211210.86y24sdd7k.gmgdl@evledraar.gmail.com>
In-Reply-To
<254b352e31029d8151eb6a974fdf8c127340cf79.1639117329.git.gitgitgadget@gmail.com>
On Fri, Dec 10 2021, ZheNing Hu via GitGitGadget wrote:
Show 47 quoted lines
> From: ZheNing Hu <adlternative@gmail.com>
>
> When we want checkout to a branch (e.g. dev1) which reference
> to a commit, but sometimes we only remember the tag (e.g. v1.1)
> on it, we will use `git checkout v1.1` to find the commit first,
> git will be in the state of deatching HEAD, so we have to search the
> branches on the commit and checkout the branch we perfer. This will
> be a bit cumbersome.
>
> Introduce "--to-branch" option, `git checkout --to-branch <tag>`
> and `git checkout --to-branch <commit>` will search all branches
> and find a unique branch reference to the commit (or the commit which
> the tag reference to) and checkout to it. If the commit have more
> than one branches, it will report error "here are more than one
> branch on commit".
>
> Signed-off-by: ZheNing Hu <adlternative@gmail.com>
> ---
>  Documentation/git-checkout.txt |  8 +++-
>  builtin/checkout.c             | 33 +++++++++++++
>  t/t2018-checkout-branch.sh     | 85 ++++++++++++++++++++++++++++++++++
>  t/t9902-completion.sh          |  1 +
>  4 files changed, 126 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
> index d473c9bf387..2a240699fd9 100644
> --- a/Documentation/git-checkout.txt
> +++ b/Documentation/git-checkout.txt
> @@ -10,7 +10,7 @@ SYNOPSIS
>  [verse]
>  'git checkout' [-q] [-f] [-m] [<branch>]
>  'git checkout' [-q] [-f] [-m] --detach [<branch>]
> -'git checkout' [-q] [-f] [-m] [--detach] <commit>
> +'git checkout' [-q] [-f] [-m] [--detach] [-w|--to-branch] <commit>
>  'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
>  'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...
>  'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]
> @@ -210,6 +210,12 @@ variable.
>  	`<commit>` is not a branch name.  See the "DETACHED HEAD" section
>  	below for details.
>  
> +-w::
> +--to-branch::
> +	Rather than checking out a commit to work on it, checkout out
> +	to the unique branch on it. If there are multiple branches on
> +	the commit, the checkout will fail.
> +
So basically what this option implements is something that could be done
as a shellscript of:
	
	git_checkout_branch_from_oid () {
		rev=$1
		git for-each-ref --format='%(refname:strip=2)' --points-at $rev >/tmp/found
		if test $(wc -l </tmp/found) -ne 1
	        then
			echo "Goldilocks error in finding $rev: $(cat /tmp/found)"
	                return 1
		fi
	        git checkout $found
	}

Which is not to say that it isn't useful, but that I think adding this to "git checkout" specifically is adding this to the wrong level. Isn't this useful to most things that parse revisions? I.e. wouldn't a better interface be via the peel syntax?

    oid=$(git rev-parse HEAD)
    git checkout $oid^{tobranch}

Doing it that way would allow any arbitrary command that takes revisions now access to that, and we could have e.g. "^{tobranches}" too, so you could do:

    git for-each-ref --format='%(refname:strip=2)' $oid^{tobranches}
Or:
    git log $oid^{tobranches}

I think implementing that is a bit harder. It's peel_onion() in object-name.c. I think parse_branchname_arg() via get_oid_mb() is now only capable of filling in an OID for a given name, and then checking out that name comes as a separate step, and you can't just return e.g. "master".

But I don't think anything stops us from adjusting those functions a bit so that get_oid_with_context(() and friends could pass down say an optional "struct string_list *", and the "peel" could then be expanded to that.

Similar to how we have "git chekout -", and the "-" is understood by some commands, but not all (via some opt-in whose location I forget...).

Previous: ZheNing HuNext: ZheNing Hu
Message 7 of 16 in “checkout: introduce "--to-branch" option”
  1. 0/2 checkout: introduce "--to-branch" optionZheNing Hu via GitGitGadget, Dec 10, 2021
  2. 1/2 checkout: handling branch_info memory leakZheNing Hu via GitGitGadget, Dec 10, 2021
  3. Ævar Arnfjörð BjarmasonDec 10, 2021
  4. 2/2 checkout: introduce "--to-branch" optionZheNing Hu via GitGitGadget, Dec 10, 2021
  5. Christian CouderDec 10, 2021
  6. ZheNing HuDec 11, 2021
  7. Ævar Arnfjörð BjarmasonDec 10, 2021
  8. ZheNing HuDec 11, 2021
  9. Bagas SanjayaDec 10, 2021
  10. ZheNing HuDec 11, 2021
  11. Junio C HamanoDec 10, 2021
  12. ZheNing HuDec 11, 2021
  13. Junio C HamanoDec 12, 2021
  14. Ævar Arnfjörð BjarmasonDec 13, 2021
  15. Junio C HamanoDec 13, 2021
  16. Junio C HamanoDec 13, 2021

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.