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

Re: [PATCH] worktree: teach "add" to check out existing branches

From
Duy Nguyen <pclouds@gmail.com>
Date
Jan 22, 2018, 11:18 UTC
Message-ID
<CACsJy8D9LS7e=cVE3Fq2qOnxK5++nFg2vjuhkNtRO-Bx0X1j6w@mail.gmail.com>
In-Reply-To
<20180121120208.12760-1-t.gummerer@gmail.com>
On Sun, Jan 21, 2018 at 7:02 PM, Thomas Gummerer <t.gummerer@gmail.com> wrote:
Show 47 quoted lines
> Currently 'git worktree add <path>' creates a new branch named after the
> basename of the path by default.  If a branch with that name already
> exists, the command refuses to do anything, unless the '--force' option
> is given.
>
> However we can do a little better than that, and check the branch out if
> it is not checked out anywhere else.  This will help users who just want
> to check an existing branch out into a new worktree, and save a few
> keystrokes.
>
> As the current behaviour is to simply 'die()' when a brach with the name
> of the basename of the path already exists, there are no backwards
> compatibility worries here.
>
> We will still 'die()' if the branch is checked out in another worktree,
> unless the --force flag is passed.
>
> Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
> ---
>
> This is a follow-up to
> https://public-inbox.org/git/20171118181345.GC32324@hank/, where this
> was first suggested, but I didn't want to do it as part of that
> series.  Now I finally got around to implementing it.
>
>  Documentation/git-worktree.txt |  9 +++++++--
>  builtin/worktree.c             | 22 +++++++++++++++-------
>  t/t2025-worktree-add.sh        | 15 ++++++++++++---
>  3 files changed, 34 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
> index 41585f535d..98731b71a7 100644
> --- a/Documentation/git-worktree.txt
> +++ b/Documentation/git-worktree.txt
> @@ -61,8 +61,13 @@ $ git worktree add --track -b <branch> <path> <remote>/<branch>
>  ------------
>  +
>  If `<commit-ish>` is omitted and neither `-b` nor `-B` nor `--detach` used,
> -then, as a convenience, a new branch based at HEAD is created automatically,
> -as if `-b $(basename <path>)` was specified.
> +then, as a convenience, a worktree with a branch named after
> +`$(basename <path>)` (call it `<branch>`) is created.  If `<branch>`
> +doesn't exist, a new branch based on HEAD is automatically created as
> +if `-b <branch>` was given.  If `<branch>` exists in the repository,
> +it will be checked out in the new worktree, if it's not checked out
> +anywhere else, otherwise the command will refuse to create the
> +worktree.

It starts getting a bit too magical to me. We probably should print something "switching to branch..." or "creating new branch ..." to let people know what decision was taken, unless --quiet is given. Yeah I know --quiet does not exist. You don't need to add it now either since nobody has asked for it.

More or less related to this, there was a question [1] whether we could do better than $(basename <path>) for determining branch name. Since you're doing start to check if a branch exists, people may start asking to check for branch "foo/bar" from the path abc/foo/bar instead of just branch "bar".

[1] https://github.com/git-for-windows/git/issues/1390
Show 20 quoted lines
>
>  list::
>
> diff --git a/builtin/worktree.c b/builtin/worktree.c
> index 7cef5b120b..148a864bb9 100644
> --- a/builtin/worktree.c
> +++ b/builtin/worktree.c
> @@ -411,13 +411,21 @@ static int add(int ac, const char **av, const char *prefix)
>         if (ac < 2 && !opts.new_branch && !opts.detach) {
>                 int n;
>                 const char *s = worktree_basename(path, &n);
> -               opts.new_branch = xstrndup(s, n);
> -               if (guess_remote) {
> -                       struct object_id oid;
> -                       const char *remote =
> -                               unique_tracking_name(opts.new_branch, &oid);
> -                       if (remote)
> -                               branch = remote;
> +               const char *branchname = xstrndup(s, n);
> +               struct strbuf ref = STRBUF_INIT;
Perhaps a blank line after this to separate var declarations and the rest.
> +               if (!strbuf_check_branch_ref(&ref, branchname) &&
> +                   ref_exists(ref.buf)) {
> +                       branch = branchname;
Hmm.. do we need UNLEAK(branch);? Maybe you should try valgrind, I'm not sure.
Show 46 quoted lines
> +                       opts.checkout = 1;
> +               } else {
> +                       opts.new_branch = branchname;
> +                       if (guess_remote) {
> +                               struct object_id oid;
> +                               const char *remote =
> +                                       unique_tracking_name(opts.new_branch, &oid);
> +                               if (remote)
> +                                       branch = remote;
> +                       }
>                 }
>         }
>
> diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh
> index 2b95944973..721b0e4c26 100755
> --- a/t/t2025-worktree-add.sh
> +++ b/t/t2025-worktree-add.sh
> @@ -198,13 +198,22 @@ test_expect_success '"add" with <branch> omitted' '
>         test_cmp_rev HEAD bat
>  '
>
> -test_expect_success '"add" auto-vivify does not clobber existing branch' '
> +test_expect_success '"add" auto-vivify checks out existing branch' '
>         test_commit c1 &&
>         test_commit c2 &&
>         git branch precious HEAD~1 &&
> -       test_must_fail git worktree add precious &&
> +       git worktree add precious &&
>         test_cmp_rev HEAD~1 precious &&
> -       test_path_is_missing precious
> +       (
> +               cd precious &&
> +               test_cmp_rev precious HEAD
> +       )
> +'
> +
> +test_expect_success '"add" auto-vivify fails with checked out branch' '
> +       git checkout -b test-branch &&
> +       test_must_fail git worktree add test-branch &&
> +       test_path_is_missing test-branch
>  '
>
>  test_expect_success '"add" no auto-vivify with --detach and <branch> omitted' '
> --
> 2.16.0.312.g896df04e46
>
-- 
Duy
Previous: Robert P. J. DayNext: Thomas Gummerer
Message 3 of 112 in “worktree: teach "add" to check out existing branches”
  1. worktree: teach "add" to check out existing branchesThomas Gummerer, Jan 21, 2018
  2. Robert P. J. DayJan 21, 2018
  3. Duy NguyenJan 22, 2018
  4. Thomas GummererJan 22, 2018
  5. 0/3 worktree: teach "add" to check out existing branchesThomas Gummerer, Feb 4, 2018
  6. 1/3 worktree: improve message when creating a new worktreeThomas Gummerer, Feb 4, 2018
  7. Duy NguyenFeb 5, 2018
  8. Thomas GummererFeb 5, 2018
  9. Junio C HamanoFeb 5, 2018
  10. Eric SunshineFeb 7, 2018
  11. Thomas GummererFeb 9, 2018
  12. Duy NguyenFeb 9, 2018
  13. Duy NguyenFeb 10, 2018
  14. 2/3 worktree: be clearer when "add" dwim-ery kicks inThomas Gummerer, Feb 4, 2018
  15. 3/3 worktree: teach "add" to check out existing branchesThomas Gummerer, Feb 4, 2018
  16. Duy NguyenFeb 5, 2018
  17. Junio C HamanoFeb 5, 2018
  18. Thomas GummererFeb 5, 2018
  19. Duy NguyenFeb 6, 2018
  20. Thomas GummererFeb 9, 2018
  21. 0/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Mar 17, 2018
  22. 1/4 worktree: improve message when creating a new worktreeThomas Gummerer, Mar 17, 2018
  23. 2/4 worktree: be clearer when "add" dwim-ery kicks inThomas Gummerer, Mar 17, 2018
  24. 3/4 worktree: factor out dwim_branch functionThomas Gummerer, Mar 17, 2018
  25. 4/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Mar 17, 2018
  26. 0/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Mar 17, 2018
  27. 1/4 worktree: improve message when creating a new worktreeThomas Gummerer, Mar 17, 2018
  28. Duy NguyenMar 19, 2018
  29. Junio C HamanoMar 19, 2018
  30. Eric SunshineMar 20, 2018
  31. Thomas GummererMar 24, 2018
  32. 3/4 worktree: factor out dwim_branch functionThomas Gummerer, Mar 17, 2018
  33. 2/4 worktree: be clearer when "add" dwim-ery kicks inThomas Gummerer, Mar 17, 2018
  34. Eric SunshineMar 20, 2018
  35. Eric SunshineMar 20, 2018
  36. Eric SunshineMar 20, 2018
  37. Thomas GummererMar 24, 2018
  38. 4/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Mar 17, 2018
  39. Eric SunshineMar 20, 2018
  40. Thomas GummererMar 24, 2018
  41. 0/6 worktree: teach "add" to check out existing branchesThomas Gummerer, Mar 25, 2018
  42. 1/6 worktree: improve message when creating a new worktreeThomas Gummerer, Mar 25, 2018
  43. 2/6 worktree: be clearer when "add" dwim-ery kicks inThomas Gummerer, Mar 25, 2018
  44. Eric SunshineMar 27, 2018
  45. Thomas GummererMar 30, 2018
  46. 3/6 worktree: remove force_new_branch from struct add_optsThomas Gummerer, Mar 25, 2018
  47. Eric SunshineMar 27, 2018
  48. Thomas GummererMar 30, 2018
  49. 4/6 worktree: factor out dwim_branch functionThomas Gummerer, Mar 25, 2018
  50. Eric SunshineMar 27, 2018
  51. 5/6 worktree: teach "add" to check out existing branchesThomas Gummerer, Mar 25, 2018
  52. Eric SunshineMar 27, 2018
  53. Thomas GummererMar 30, 2018
  54. 6/6 t2025: rename now outdated branch nameThomas Gummerer, Mar 25, 2018
  55. Eric SunshineMar 27, 2018
  56. Thomas GummererMar 30, 2018
  57. 0/6 worktree: teach "add" to check out existing branchesThomas Gummerer, Mar 31, 2018
  58. 1/6 worktree: remove extra members from struct add_optsThomas Gummerer, Mar 31, 2018
  59. 3/6 worktree: improve message when creating a new worktreeThomas Gummerer, Mar 31, 2018
  60. Eric SunshineApr 8, 2018
  61. 2/6 reset: introduce show-new-head-line optionThomas Gummerer, Mar 31, 2018
  62. Junio C HamanoApr 2, 2018
  63. Thomas GummererApr 2, 2018
  64. Thomas GummererApr 2, 2018
  65. Junio C HamanoApr 2, 2018
  66. Thomas GummererApr 2, 2018
  67. 6/6 worktree: teach "add" to check out existing branchesThomas Gummerer, Mar 31, 2018
  68. 5/6 fixup! worktree: teach "add" to check out existing branchesThomas Gummerer, Apr 1, 2018
  69. Eric SunshineApr 9, 2018
  70. Thomas GummererApr 9, 2018
  71. Eric SunshineApr 9, 2018
  72. Eric SunshineApr 8, 2018
  73. Thomas GummererApr 8, 2018
  74. 4/6 worktree: be clearer when "add" dwim-ery kicks inThomas Gummerer, Mar 31, 2018
  75. 5/6 worktree: factor out dwim_branch functionThomas Gummerer, Mar 31, 2018
  76. Eric SunshineApr 8, 2018
  77. Thomas GummererApr 8, 2018
  78. Eric SunshineApr 9, 2018
  79. Thomas GummererApr 9, 2018
  80. Thomas GummererApr 9, 2018
  81. Eric SunshineApr 9, 2018
  82. Thomas GummererApr 11, 2018
  83. Eric SunshineApr 11, 2018
  84. Thomas GummererApr 11, 2018
  85. Eric SunshineApr 11, 2018
  86. 0/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Apr 15, 2018
  87. 1/4 worktree: remove extra members from struct add_optsThomas Gummerer, Apr 15, 2018
  88. 3/4 worktree: factor out dwim_branch functionThomas Gummerer, Apr 15, 2018
  89. 2/4 worktree: improve message when creating a new worktreeThomas Gummerer, Apr 15, 2018
  90. Junio C HamanoApr 16, 2018
  91. Thomas GummererApr 23, 2018
  92. Eric SunshineApr 23, 2018
  93. Thomas GummererApr 23, 2018
  94. 4/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Apr 15, 2018
  95. Eric SunshineApr 23, 2018
  96. 0/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Apr 23, 2018
  97. 1/4 worktree: remove extra members from struct add_optsThomas Gummerer, Apr 23, 2018
  98. Eric SunshineApr 24, 2018
  99. 2/4 worktree: improve message when creating a new worktreeThomas Gummerer, Apr 23, 2018
  100. Eric SunshineApr 24, 2018
  101. 3/4 worktree: factor out dwim_branch functionThomas Gummerer, Apr 23, 2018
  102. 4/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Apr 23, 2018
  103. Eric SunshineApr 24, 2018
  104. 0/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Apr 24, 2018
  105. 1/4 worktree: remove extra members from struct add_optsThomas Gummerer, Apr 24, 2018
  106. 2/4 worktree: improve message when creating a new worktreeThomas Gummerer, Apr 24, 2018
  107. 3/4 worktree: factor out dwim_branch functionThomas Gummerer, Apr 24, 2018
  108. 4/4 worktree: teach "add" to check out existing branchesThomas Gummerer, Apr 24, 2018
  109. Eric SunshineApr 27, 2018
  110. Thomas GummererApr 28, 2018
  111. Junio C HamanoApr 30, 2018
  112. Junio C HamanoMar 18, 2018

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.