{"thread":{"id":"66112","subject":"[PATCH] worktree add: shouldn't dwim if -b or -B is given","startedAt":"2026-08-04T14:00:37Z","lastAt":"2026-08-20T17:34:58Z","messageCount":10,"participants":["Yoichi NAKAYAMA via GitGitGadget","Junio C Hamano","Yoichi Nakayama"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"549569","messageId":"pull.2192.git.1785852032626.gitgitgadget@gmail.com","threadId":"66112","inReplyTo":null,"subject":"[PATCH] worktree add: shouldn't dwim if -b or -B is given","fromName":"Yoichi NAKAYAMA via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-08-04T14:00:31Z","receivedAt":"2026-08-04T14:00:37Z","isPatch":true,"body":"From: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n\n'git worktree add <path> <branch>' DWIMs <branch> to a\nremote-tracking branch when neither -b, -B, nor --detach\nis given.\n\nHowever, 'git worktree add -b <new-branch> <path> <branch>' can\nstill DWIM <branch>, causing <new-branch> to be ignored.\n\nThis is a regression introduced in v2.42.0\n(128e5496b325640f0a09cc1d5b1e346c069b410f).\n\nSigned-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n---\n    worktree add: shouldn't dwim if -b or -B is given\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2192%2Fyoichi%2Fworktree-add-should-not-dwim-with-b-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2192/yoichi/worktree-add-should-not-dwim-with-b-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/2192\n\n builtin/worktree.c      |  2 +-\n t/t2400-worktree-add.sh | 10 ++++++++++\n 2 files changed, 11 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 654d27c3e1..3204afdb12 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -897,7 +897,7 @@ static int add(int ac, const char **av, const char *prefix,\n \n \t\t/* DWIM: Infer --orphan when repo has no refs. */\n \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n-\t} else if (ac == 2) {\n+\t} else if (ac == 2 && !new_branch) {\n \t\tstruct object_id oid;\n \t\tstruct commit *commit;\n \t\tchar *remote;\ndiff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh\nindex 87b926728a..9cbf84861d 100755\n--- a/t/t2400-worktree-add.sh\n+++ b/t/t2400-worktree-add.sh\n@@ -621,6 +621,16 @@ test_expect_success '\"add\" <path> <branch> dwims' '\n \t)\n '\n \n+test_expect_success '\"add\" <path> <branch> does not dwim with -b' '\n+\ttest_when_finished rm -rf repo_upstream repo_dwim foo &&\n+\tsetup_remote_repo repo_upstream repo_dwim &&\n+\tgit init repo_dwim &&\n+\t(\n+\t\tcd repo_dwim &&\n+\t\ttest_must_fail git worktree add -b branch ../foo foo\n+\t)\n+'\n+\n test_expect_success '\"add\" <path> <branch> dwims with checkout.defaultRemote' '\n \ttest_when_finished rm -rf repo_upstream repo_dwim foo &&\n \tsetup_remote_repo repo_upstream repo_dwim &&\n\nbase-commit: 5b2471720c93ee30e5764a19f3d3b3ae9ec9712a\n-- \ngitgitgadget\n"},{"id":"549579","messageId":"xmqq33wtx138.fsf@gitster.g","threadId":"66112","inReplyTo":"pull.2192.git.1785852032626.gitgitgadget@gmail.com","subject":"Re: [PATCH] worktree add: shouldn't dwim if -b or -B is given","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-08-04T17:11:23Z","receivedAt":"2026-08-04T17:11:28Z","isPatch":true,"body":"\"Yoichi NAKAYAMA via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n>\n> 'git worktree add <path> <branch>' DWIMs <branch> to a\n> remote-tracking branch when neither -b, -B, nor --detach\n> is given.\n>\n> However, 'git worktree add -b <new-branch> <path> <branch>' can\n> still DWIM <branch>, causing <new-branch> to be ignored.\n>\n> This is a regression introduced in v2.42.0\n> (128e5496b325640f0a09cc1d5b1e346c069b410f).\n>\n> Signed-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n> ---\n>     worktree add: shouldn't dwim if -b or -B is given\n>\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2192%2Fyoichi%2Fworktree-add-should-not-dwim-with-b-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2192/yoichi/worktree-add-should-not-dwim-with-b-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/2192\n>\n>  builtin/worktree.c      |  2 +-\n>  t/t2400-worktree-add.sh | 10 ++++++++++\n>  2 files changed, 11 insertions(+), 1 deletion(-)\n>\n> diff --git a/builtin/worktree.c b/builtin/worktree.c\n> index 654d27c3e1..3204afdb12 100644\n> --- a/builtin/worktree.c\n> +++ b/builtin/worktree.c\n> @@ -897,7 +897,7 @@ static int add(int ac, const char **av, const char *prefix,\n>  \n>  \t\t/* DWIM: Infer --orphan when repo has no refs. */\n>  \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n> -\t} else if (ac == 2) {\n> +\t} else if (ac == 2 && !new_branch) {\n>  \t\tstruct object_id oid;\n>  \t\tstruct commit *commit;\n>  \t\tchar *remote;\n\nThis part checks 'branch' (assigned from av[1] earlier) to see if it\nnames a commit.  When it does not, the code checks if it is the name\nof a unique remote-tracking branch; if it is, the code uses that as\n'branch', which is the origin to be used to fork 'new_branch' (av[1]\nin this case) from.\n\nYour observation is correct that this would overwrite 'new_branch'\nif it were supplied.\n\nStepping back a bit, though, does this change the behavior when\n'branch' *does* resolve to a commit (hence, the DWIM is already\nbypassed and 'new_branch' or 'branch' are not nuked)?  When 'ac' is\nequal to 2 and 'new_branch' is supplied, we used to call:\n\n        if (!strcmp(branch, \"HEAD\"))\n                can_use_local_refs(&opts);\n\ninside the block you are now skipping.  It looks to me that this\npatch also changes behavior when the user says:\n\n        $ git worktree add -b <new-branch> <path> HEAD\n\nby not calling can_use_local_refs(), whose only effect in this\ncontext is that it may issue a warning() to the user.  I do not know\noffhand what the ramifications of this difference are.\n\nI wonder if we want to skip only the dwim part inside of this \"else if\"\narm, e.g.\n\ndiff --git i/builtin/worktree.c w/builtin/worktree.c\nindex 654d27c3e1..2205f4e9b2 100644\n--- i/builtin/worktree.c\n+++ w/builtin/worktree.c\n@@ -898,6 +898,7 @@ static int add(int ac, const char **av, const char *prefix,\n \t\t/* DWIM: Infer --orphan when repo has no refs. */\n \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n \t} else if (ac == 2) {\n+\t    if (!newbranch) {\n \t\tstruct object_id oid;\n \t\tstruct commit *commit;\n \t\tchar *remote;\n@@ -910,6 +911,7 @@ static int add(int ac, const char **av, const char *prefix,\n \t\t\t\tbranch = new_branch_to_free = remote;\n \t\t\t}\n \t\t}\n+\t    }\n \n \t\tif (!strcmp(branch, \"HEAD\"))\n \t\t\tcan_use_local_refs(&opts);\n\nNote that above diff is with broken indentation to help reduce the\npatch noise to illustrate where the new block boundary would be.\n\n> diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh\n> index 87b926728a..9cbf84861d 100755\n> --- a/t/t2400-worktree-add.sh\n> +++ b/t/t2400-worktree-add.sh\n> @@ -621,6 +621,16 @@ test_expect_success '\"add\" <path> <branch> dwims' '\n>  \t)\n>  '\n>  \n> +test_expect_success '\"add\" <path> <branch> does not dwim with -b' '\n> +\ttest_when_finished rm -rf repo_upstream repo_dwim foo &&\n> +\tsetup_remote_repo repo_upstream repo_dwim &&\n> +\tgit init repo_dwim &&\n> +\t(\n> +\t\tcd repo_dwim &&\n> +\t\ttest_must_fail git worktree add -b branch ../foo foo\n> +\t)\n> +'\n\nTwo comments.\n\n * You call setup_remote_repo(), which takes two names, runs\n   'git init' on each of them, and prepares those repositories.  Do\n   you need to run 'git init repo_dwim' to initialize it again?\n   What for?\n\n * Expecting a failure to create a worktree may be fine, but can we\n   say how we expect the command to fail as well?  Perhaps you can\n   capture the error message while ensuring that the command fails,\n   and then check the error message to make sure it failed in the\n   expected way, or something like that.\n\nThanks.\n"},{"id":"549676","messageId":"CAF5D8-sYhrSP8D_TUPLqDUWci=GK4DNzOxJaVr_kd5c776NKyA@mail.gmail.com","threadId":"66112","inReplyTo":"xmqq33wtx138.fsf@gitster.g","subject":"Re: [PATCH] worktree add: shouldn't dwim if -b or -B is given","fromName":"Yoichi Nakayama","fromEmail":"yoichi.nakayama@gmail.com","sentAt":"2026-08-05T10:57:29Z","receivedAt":"2026-08-05T10:57:43Z","isPatch":true,"body":"On Wed, Aug 5, 2026 at 2:11 AM Junio C Hamano <gitster@pobox.com> wrote:\n> Stepping back a bit, though, does this change the behavior when\n> 'branch' *does* resolve to a commit (hence, the DWIM is already\n> bypassed and 'new_branch' or 'branch' are not nuked)?  When 'ac' is\n> equal to 2 and 'new_branch' is supplied, we used to call:\n>\n>         if (!strcmp(branch, \"HEAD\"))\n>                 can_use_local_refs(&opts);\n>\n> inside the block you are now skipping.  It looks to me that this\n> patch also changes behavior when the user says:\n>\n>         $ git worktree add -b <new-branch> <path> HEAD\n>\n> by not calling can_use_local_refs(), whose only effect in this\n> context is that it may issue a warning() to the user.  I do not know\n> offhand what the ramifications of this difference are.\n\nIt is better to emit warnings for the given arguments whenever possible,\nso I think we should not skip the step mentioned above.\nI'll modify the condition.\n\n> > diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh\n> > index 87b926728a..9cbf84861d 100755\n> > --- a/t/t2400-worktree-add.sh\n> > +++ b/t/t2400-worktree-add.sh\n> > @@ -621,6 +621,16 @@ test_expect_success '\"add\" <path> <branch> dwims' '\n> >       )\n> >  '\n> >\n> > +test_expect_success '\"add\" <path> <branch> does not dwim with -b' '\n> > +     test_when_finished rm -rf repo_upstream repo_dwim foo &&\n> > +     setup_remote_repo repo_upstream repo_dwim &&\n> > +     git init repo_dwim &&\n> > +     (\n> > +             cd repo_dwim &&\n> > +             test_must_fail git worktree add -b branch ../foo foo\n> > +     )\n> > +'\n>\n> Two comments.\n>\n>  * You call setup_remote_repo(), which takes two names, runs\n>    'git init' on each of them, and prepares those repositories.  Do\n>    you need to run 'git init repo_dwim' to initialize it again?\n>    What for?\n\n'git init' was unnecessary.  It was included because I copied\nan existing test; I'll remove it.\n\n>  * Expecting a failure to create a worktree may be fine, but can we\n>    say how we expect the command to fail as well?  Perhaps you can\n>    capture the error message while ensuring that the command fails,\n>    and then check the error message to make sure it failed in the\n>    expected way, or something like that.\n\nExpected error is 'fatal: invalid reference: foo'. I'll add test_grep.\n\nThanks,\n-- \nYoichi NAKAYAMA\n"},{"id":"549685","messageId":"pull.2192.v2.git.1785932208004.gitgitgadget@gmail.com","threadId":"66112","inReplyTo":"pull.2192.git.1785852032626.gitgitgadget@gmail.com","subject":"[PATCH v2] worktree add: shouldn't dwim if -b or -B is given","fromName":"Yoichi NAKAYAMA via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-08-05T12:16:47Z","receivedAt":"2026-08-05T12:16:50Z","isPatch":true,"body":"From: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n\ngit worktree add <path> <branch> DWIMs <branch> to a\nremote-tracking branch when neither -b, -B, nor --detach\nis given.\n\nHowever, git worktree add -b <new-branch> <path> <branch> can\nstill DWIM <branch>, causing <new-branch> to be ignored.\n\nThis is a regression introduced in v2.42.0\n(128e5496b325640f0a09cc1d5b1e346c069b410f).\n\nSigned-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n---\n    worktree add: shouldn't dwim if -b or -B is given\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2192%2Fyoichi%2Fworktree-add-should-not-dwim-with-b-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2192/yoichi/worktree-add-should-not-dwim-with-b-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/2192\n\nRange-diff vs v1:\n\n 1:  908a32fb56 ! 1:  b00f6c2fa1 worktree add: shouldn't dwim if -b or -B is given\n     @@ Metadata\n       ## Commit message ##\n          worktree add: shouldn't dwim if -b or -B is given\n      \n     -    'git worktree add <path> <branch>' DWIMs <branch> to a\n     +    git worktree add <path> <branch> DWIMs <branch> to a\n          remote-tracking branch when neither -b, -B, nor --detach\n          is given.\n      \n     -    However, 'git worktree add -b <new-branch> <path> <branch>' can\n     +    However, git worktree add -b <new-branch> <path> <branch> can\n          still DWIM <branch>, causing <new-branch> to be ignored.\n      \n          This is a regression introduced in v2.42.0\n     @@ Commit message\n      \n       ## builtin/worktree.c ##\n      @@ builtin/worktree.c: static int add(int ac, const char **av, const char *prefix,\n     - \n       \t\t/* DWIM: Infer --orphan when repo has no refs. */\n       \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n     --\t} else if (ac == 2) {\n     -+\t} else if (ac == 2 && !new_branch) {\n     - \t\tstruct object_id oid;\n     - \t\tstruct commit *commit;\n     - \t\tchar *remote;\n     + \t} else if (ac == 2) {\n     +-\t\tstruct object_id oid;\n     +-\t\tstruct commit *commit;\n     +-\t\tchar *remote;\n     +-\n     +-\t\tcommit = lookup_commit_reference_by_name(branch);\n     +-\t\tif (!commit) {\n     +-\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n     +-\t\t\tif (remote) {\n     +-\t\t\t\tnew_branch = branch;\n     +-\t\t\t\tbranch = new_branch_to_free = remote;\n     ++\t\tif (!new_branch) {\n     ++\t\t\tstruct object_id oid;\n     ++\t\t\tstruct commit *commit;\n     ++\t\t\tchar *remote;\n     ++\n     ++\t\t\tcommit = lookup_commit_reference_by_name(branch);\n     ++\t\t\tif (!commit) {\n     ++\t\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n     ++\t\t\t\tif (remote) {\n     ++\t\t\t\t\tnew_branch = branch;\n     ++\t\t\t\t\tbranch = new_branch_to_free = remote;\n     ++\t\t\t\t}\n     + \t\t\t}\n     + \t\t}\n     + \n      \n       ## t/t2400-worktree-add.sh ##\n      @@ t/t2400-worktree-add.sh: test_expect_success '\"add\" <path> <branch> dwims' '\n     @@ t/t2400-worktree-add.sh: test_expect_success '\"add\" <path> <branch> dwims' '\n       '\n       \n      +test_expect_success '\"add\" <path> <branch> does not dwim with -b' '\n     -+\ttest_when_finished rm -rf repo_upstream repo_dwim foo &&\n     ++\ttest_when_finished rm -rf repo_upstream repo_dwim wt &&\n      +\tsetup_remote_repo repo_upstream repo_dwim &&\n     -+\tgit init repo_dwim &&\n      +\t(\n      +\t\tcd repo_dwim &&\n     -+\t\ttest_must_fail git worktree add -b branch ../foo foo\n     ++\t\ttest_must_fail git worktree add -b branch ../wt foo 2>actual &&\n     ++\t\ttest_grep \"^fatal: invalid reference: foo\" actual\n      +\t)\n      +'\n      +\n\n\n builtin/worktree.c      | 22 ++++++++++++----------\n t/t2400-worktree-add.sh | 10 ++++++++++\n 2 files changed, 22 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 654d27c3e1..cc46c1b415 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -898,16 +898,18 @@ static int add(int ac, const char **av, const char *prefix,\n \t\t/* DWIM: Infer --orphan when repo has no refs. */\n \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n \t} else if (ac == 2) {\n-\t\tstruct object_id oid;\n-\t\tstruct commit *commit;\n-\t\tchar *remote;\n-\n-\t\tcommit = lookup_commit_reference_by_name(branch);\n-\t\tif (!commit) {\n-\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n-\t\t\tif (remote) {\n-\t\t\t\tnew_branch = branch;\n-\t\t\t\tbranch = new_branch_to_free = remote;\n+\t\tif (!new_branch) {\n+\t\t\tstruct object_id oid;\n+\t\t\tstruct commit *commit;\n+\t\t\tchar *remote;\n+\n+\t\t\tcommit = lookup_commit_reference_by_name(branch);\n+\t\t\tif (!commit) {\n+\t\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n+\t\t\t\tif (remote) {\n+\t\t\t\t\tnew_branch = branch;\n+\t\t\t\t\tbranch = new_branch_to_free = remote;\n+\t\t\t\t}\n \t\t\t}\n \t\t}\n \ndiff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh\nindex 87b926728a..ba3bec078f 100755\n--- a/t/t2400-worktree-add.sh\n+++ b/t/t2400-worktree-add.sh\n@@ -621,6 +621,16 @@ test_expect_success '\"add\" <path> <branch> dwims' '\n \t)\n '\n \n+test_expect_success '\"add\" <path> <branch> does not dwim with -b' '\n+\ttest_when_finished rm -rf repo_upstream repo_dwim wt &&\n+\tsetup_remote_repo repo_upstream repo_dwim &&\n+\t(\n+\t\tcd repo_dwim &&\n+\t\ttest_must_fail git worktree add -b branch ../wt foo 2>actual &&\n+\t\ttest_grep \"^fatal: invalid reference: foo\" actual\n+\t)\n+'\n+\n test_expect_success '\"add\" <path> <branch> dwims with checkout.defaultRemote' '\n \ttest_when_finished rm -rf repo_upstream repo_dwim foo &&\n \tsetup_remote_repo repo_upstream repo_dwim &&\n\nbase-commit: 5b2471720c93ee30e5764a19f3d3b3ae9ec9712a\n-- \ngitgitgadget\n"},{"id":"549687","messageId":"CAF5D8-sca=qutDYH=SZEjZsWFGkFAVLiJZz27jzUOfhvi3LWKQ@mail.gmail.com","threadId":"66112","inReplyTo":"pull.2192.v2.git.1785932208004.gitgitgadget@gmail.com","subject":"Re: [PATCH v2] worktree add: shouldn't dwim if -b or -B is given","fromName":"Yoichi Nakayama","fromEmail":"yoichi.nakayama@gmail.com","sentAt":"2026-08-05T12:30:33Z","receivedAt":"2026-08-05T12:30:46Z","isPatch":true,"body":"On Wed, Aug 5, 2026 at 9:16 PM Yoichi NAKAYAMA via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n> Range-diff vs v1:\n>\n>  1:  908a32fb56 ! 1:  b00f6c2fa1 worktree add: shouldn't dwim if -b or -B is given\n>      @@ Metadata\n>        ## Commit message ##\n>           worktree add: shouldn't dwim if -b or -B is given\n>\n>      -    'git worktree add <path> <branch>' DWIMs <branch> to a\n>      +    git worktree add <path> <branch> DWIMs <branch> to a\n>           remote-tracking branch when neither -b, -B, nor --detach\n>           is given.\n>\n>      -    However, 'git worktree add -b <new-branch> <path> <branch>' can\n>      +    However, git worktree add -b <new-branch> <path> <branch> can\n>           still DWIM <branch>, causing <new-branch> to be ignored.\n>\n>           This is a regression introduced in v2.42.0\n\nI accidentally removed the quotes in the commit message. I'll fix it.\n-- \nYoichi NAKAYAMA\n"},{"id":"549689","messageId":"pull.2192.v3.git.1785934486496.gitgitgadget@gmail.com","threadId":"66112","inReplyTo":"pull.2192.git.1785852032626.gitgitgadget@gmail.com","subject":"[PATCH v3] worktree add: shouldn't dwim if -b or -B is given","fromName":"Yoichi NAKAYAMA via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-08-05T12:54:45Z","receivedAt":"2026-08-05T12:54:49Z","isPatch":true,"body":"From: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n\n'git worktree add <path> <branch>' DWIMs <branch> to a\nremote-tracking branch when neither -b, -B, nor --detach\nis given.\n\nHowever, 'git worktree add -b <new-branch> <path> <branch>' can\nstill DWIM <branch>, causing <new-branch> to be ignored.\n\nThis is a regression introduced in v2.42.0\n(128e5496b325640f0a09cc1d5b1e346c069b410f).\n\nSigned-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n---\n    worktree add: shouldn't dwim if -b or -B is given\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2192%2Fyoichi%2Fworktree-add-should-not-dwim-with-b-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2192/yoichi/worktree-add-should-not-dwim-with-b-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/2192\n\nRange-diff vs v2:\n\n 1:  b00f6c2fa1 ! 1:  477ea27c8b worktree add: shouldn't dwim if -b or -B is given\n     @@ Metadata\n       ## Commit message ##\n          worktree add: shouldn't dwim if -b or -B is given\n      \n     -    git worktree add <path> <branch> DWIMs <branch> to a\n     +    'git worktree add <path> <branch>' DWIMs <branch> to a\n          remote-tracking branch when neither -b, -B, nor --detach\n          is given.\n      \n     -    However, git worktree add -b <new-branch> <path> <branch> can\n     +    However, 'git worktree add -b <new-branch> <path> <branch>' can\n          still DWIM <branch>, causing <new-branch> to be ignored.\n      \n          This is a regression introduced in v2.42.0\n\n\n builtin/worktree.c      | 22 ++++++++++++----------\n t/t2400-worktree-add.sh | 10 ++++++++++\n 2 files changed, 22 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 654d27c3e1..cc46c1b415 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -898,16 +898,18 @@ static int add(int ac, const char **av, const char *prefix,\n \t\t/* DWIM: Infer --orphan when repo has no refs. */\n \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n \t} else if (ac == 2) {\n-\t\tstruct object_id oid;\n-\t\tstruct commit *commit;\n-\t\tchar *remote;\n-\n-\t\tcommit = lookup_commit_reference_by_name(branch);\n-\t\tif (!commit) {\n-\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n-\t\t\tif (remote) {\n-\t\t\t\tnew_branch = branch;\n-\t\t\t\tbranch = new_branch_to_free = remote;\n+\t\tif (!new_branch) {\n+\t\t\tstruct object_id oid;\n+\t\t\tstruct commit *commit;\n+\t\t\tchar *remote;\n+\n+\t\t\tcommit = lookup_commit_reference_by_name(branch);\n+\t\t\tif (!commit) {\n+\t\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n+\t\t\t\tif (remote) {\n+\t\t\t\t\tnew_branch = branch;\n+\t\t\t\t\tbranch = new_branch_to_free = remote;\n+\t\t\t\t}\n \t\t\t}\n \t\t}\n \ndiff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh\nindex 87b926728a..ba3bec078f 100755\n--- a/t/t2400-worktree-add.sh\n+++ b/t/t2400-worktree-add.sh\n@@ -621,6 +621,16 @@ test_expect_success '\"add\" <path> <branch> dwims' '\n \t)\n '\n \n+test_expect_success '\"add\" <path> <branch> does not dwim with -b' '\n+\ttest_when_finished rm -rf repo_upstream repo_dwim wt &&\n+\tsetup_remote_repo repo_upstream repo_dwim &&\n+\t(\n+\t\tcd repo_dwim &&\n+\t\ttest_must_fail git worktree add -b branch ../wt foo 2>actual &&\n+\t\ttest_grep \"^fatal: invalid reference: foo\" actual\n+\t)\n+'\n+\n test_expect_success '\"add\" <path> <branch> dwims with checkout.defaultRemote' '\n \ttest_when_finished rm -rf repo_upstream repo_dwim foo &&\n \tsetup_remote_repo repo_upstream repo_dwim &&\n\nbase-commit: 5b2471720c93ee30e5764a19f3d3b3ae9ec9712a\n-- \ngitgitgadget\n"},{"id":"549748","messageId":"xmqqtsp8qzc4.fsf@gitster.g","threadId":"66112","inReplyTo":"pull.2192.v3.git.1785934486496.gitgitgadget@gmail.com","subject":"Re: [PATCH v3] worktree add: shouldn't dwim if -b or -B is given","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-08-05T16:58:03Z","receivedAt":"2026-08-05T16:58:05Z","isPatch":true,"body":"\"Yoichi NAKAYAMA via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n>\n> 'git worktree add <path> <branch>' DWIMs <branch> to a\n> remote-tracking branch when neither -b, -B, nor --detach\n> is given.\n>\n> However, 'git worktree add -b <new-branch> <path> <branch>' can\n> still DWIM <branch>, causing <new-branch> to be ignored.\n>\n> This is a regression introduced in v2.42.0\n> (128e5496b325640f0a09cc1d5b1e346c069b410f).\n\nI'll commit with the latter half of the above message rewritten like\nthis:\n\n    However, 'git worktree add -b <new-branch> <path> <branch>' can\n    still DWIM <branch>, causing <new-branch> to be ignored.  This is a\n    regression introduced by 128e5496b3 (worktree add: extend DWIM to\n    infer --orphan, 2023-05-17), which appeared in Git 2.42.\n\nAs we refer to an individual commit using \"log -1\n--pretty=reference\" format.\n\n> Signed-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n> ---\n>     worktree add: shouldn't dwim if -b or -B is given\n\nThe change looks good to me.\n\nThanks.\n\n>\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2192%2Fyoichi%2Fworktree-add-should-not-dwim-with-b-v3\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2192/yoichi/worktree-add-should-not-dwim-with-b-v3\n> Pull-Request: https://github.com/gitgitgadget/git/pull/2192\n>\n> Range-diff vs v2:\n>\n>  1:  b00f6c2fa1 ! 1:  477ea27c8b worktree add: shouldn't dwim if -b or -B is given\n>      @@ Metadata\n>        ## Commit message ##\n>           worktree add: shouldn't dwim if -b or -B is given\n>       \n>      -    git worktree add <path> <branch> DWIMs <branch> to a\n>      +    'git worktree add <path> <branch>' DWIMs <branch> to a\n>           remote-tracking branch when neither -b, -B, nor --detach\n>           is given.\n>       \n>      -    However, git worktree add -b <new-branch> <path> <branch> can\n>      +    However, 'git worktree add -b <new-branch> <path> <branch>' can\n>           still DWIM <branch>, causing <new-branch> to be ignored.\n>       \n>           This is a regression introduced in v2.42.0\n>\n>\n>  builtin/worktree.c      | 22 ++++++++++++----------\n>  t/t2400-worktree-add.sh | 10 ++++++++++\n>  2 files changed, 22 insertions(+), 10 deletions(-)\n>\n> diff --git a/builtin/worktree.c b/builtin/worktree.c\n> index 654d27c3e1..cc46c1b415 100644\n> --- a/builtin/worktree.c\n> +++ b/builtin/worktree.c\n> @@ -898,16 +898,18 @@ static int add(int ac, const char **av, const char *prefix,\n>  \t\t/* DWIM: Infer --orphan when repo has no refs. */\n>  \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n>  \t} else if (ac == 2) {\n> -\t\tstruct object_id oid;\n> -\t\tstruct commit *commit;\n> -\t\tchar *remote;\n> -\n> -\t\tcommit = lookup_commit_reference_by_name(branch);\n> -\t\tif (!commit) {\n> -\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n> -\t\t\tif (remote) {\n> -\t\t\t\tnew_branch = branch;\n> -\t\t\t\tbranch = new_branch_to_free = remote;\n> +\t\tif (!new_branch) {\n> +\t\t\tstruct object_id oid;\n> +\t\t\tstruct commit *commit;\n> +\t\t\tchar *remote;\n> +\n> +\t\t\tcommit = lookup_commit_reference_by_name(branch);\n> +\t\t\tif (!commit) {\n> +\t\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n> +\t\t\t\tif (remote) {\n> +\t\t\t\t\tnew_branch = branch;\n> +\t\t\t\t\tbranch = new_branch_to_free = remote;\n> +\t\t\t\t}\n>  \t\t\t}\n>  \t\t}\n>  \n> diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh\n> index 87b926728a..ba3bec078f 100755\n> --- a/t/t2400-worktree-add.sh\n> +++ b/t/t2400-worktree-add.sh\n> @@ -621,6 +621,16 @@ test_expect_success '\"add\" <path> <branch> dwims' '\n>  \t)\n>  '\n>  \n> +test_expect_success '\"add\" <path> <branch> does not dwim with -b' '\n> +\ttest_when_finished rm -rf repo_upstream repo_dwim wt &&\n> +\tsetup_remote_repo repo_upstream repo_dwim &&\n> +\t(\n> +\t\tcd repo_dwim &&\n> +\t\ttest_must_fail git worktree add -b branch ../wt foo 2>actual &&\n> +\t\ttest_grep \"^fatal: invalid reference: foo\" actual\n> +\t)\n> +'\n> +\n>  test_expect_success '\"add\" <path> <branch> dwims with checkout.defaultRemote' '\n>  \ttest_when_finished rm -rf repo_upstream repo_dwim foo &&\n>  \tsetup_remote_repo repo_upstream repo_dwim &&\n>\n> base-commit: 5b2471720c93ee30e5764a19f3d3b3ae9ec9712a\n"},{"id":"550854","messageId":"CAF5D8-tbUqLyxhj7pqDmsHJqnN_Pg4QV0C2CcGL6XEqay_BG-A@mail.gmail.com","threadId":"66112","inReplyTo":"pull.2192.v2.git.1785932208004.gitgitgadget@gmail.com","subject":"Re: [PATCH v2] worktree add: shouldn't dwim if -b or -B is given","fromName":"Yoichi Nakayama","fromEmail":"yoichi.nakayama@gmail.com","sentAt":"2026-08-19T22:01:27Z","receivedAt":"2026-08-19T22:01:40Z","isPatch":true,"body":"On Wed, Aug 5, 2026 at 9:16 PM Yoichi NAKAYAMA via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n> diff --git a/builtin/worktree.c b/builtin/worktree.c\n> index 654d27c3e1..cc46c1b415 100644\n> --- a/builtin/worktree.c\n> +++ b/builtin/worktree.c\n> @@ -898,16 +898,18 @@ static int add(int ac, const char **av, const char *prefix,\n>                 /* DWIM: Infer --orphan when repo has no refs. */\n>                 opts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n>         } else if (ac == 2) {\n> -               struct object_id oid;\n> -               struct commit *commit;\n> -               char *remote;\n> -\n> -               commit = lookup_commit_reference_by_name(branch);\n> -               if (!commit) {\n> -                       remote = unique_tracking_name(branch, &oid, NULL);\n> -                       if (remote) {\n> -                               new_branch = branch;\n> -                               branch = new_branch_to_free = remote;\n> +               if (!new_branch) {\n> +                       struct object_id oid;\n> +                       struct commit *commit;\n> +                       char *remote;\n> +\n> +                       commit = lookup_commit_reference_by_name(branch);\n> +                       if (!commit) {\n> +                               remote = unique_tracking_name(branch, &oid, NULL);\n> +                               if (remote) {\n> +                                       new_branch = branch;\n> +                                       branch = new_branch_to_free = remote;\n> +                               }\n>                         }\n>                 }\n\nTo reduce nesting and match the style of the preceding conditions, I'd\nlike to revise this part as follows:\n(I'll use the commit message modified by Junio with 'log --pretty=reference')\n\n> } else if (ac < 2 && new_branch) {\n>     ...\n> } else if (ac < 2) {\n>     ...\n> } else if (ac == 2 && new_branch) {\n>     if (!strcmp(branch, \"HEAD\"))\n>         can_use_local_refs(&opts);\n> } else if (ac = 2) {\n>     ...\n\nThanks,\n-- \nYoichi NAKAYAMA\n"},{"id":"550887","messageId":"pull.2192.v4.git.1787221888406.gitgitgadget@gmail.com","threadId":"66112","inReplyTo":"pull.2192.git.1785852032626.gitgitgadget@gmail.com","subject":"[PATCH v4] worktree add: shouldn't dwim if -b or -B is given","fromName":"Yoichi NAKAYAMA via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2026-08-20T10:31:28Z","receivedAt":"2026-08-20T10:31:31Z","isPatch":true,"body":"From: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n\n'git worktree add <path> <branch>' DWIMs <branch> to a\nremote-tracking branch when neither -b, -B, nor --detach\nis given.\n\nHowever, 'git worktree add -b <new-branch> <path> <branch>' can\nstill DWIM <branch>, causing <new-branch> to be ignored.  This is a\nregression introduced by 128e5496b3 (worktree add: extend DWIM to\ninfer --orphan, 2023-05-17), which appeared in Git 2.42.\n\nSigned-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n---\n    worktree add: shouldn't dwim if -b or -B is given\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-2192%2Fyoichi%2Fworktree-add-should-not-dwim-with-b-v4\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2192/yoichi/worktree-add-should-not-dwim-with-b-v4\nPull-Request: https://github.com/gitgitgadget/git/pull/2192\n\nRange-diff vs v3:\n\n 1:  477ea27c8b ! 1:  512b037bb7 worktree add: shouldn't dwim if -b or -B is given\n     @@ Commit message\n          is given.\n      \n          However, 'git worktree add -b <new-branch> <path> <branch>' can\n     -    still DWIM <branch>, causing <new-branch> to be ignored.\n     -\n     -    This is a regression introduced in v2.42.0\n     -    (128e5496b325640f0a09cc1d5b1e346c069b410f).\n     +    still DWIM <branch>, causing <new-branch> to be ignored.  This is a\n     +    regression introduced by 128e5496b3 (worktree add: extend DWIM to\n     +    infer --orphan, 2023-05-17), which appeared in Git 2.42.\n      \n          Signed-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>\n      \n       ## builtin/worktree.c ##\n      @@ builtin/worktree.c: static int add(int ac, const char **av, const char *prefix,\n     + \n       \t\t/* DWIM: Infer --orphan when repo has no refs. */\n       \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n     ++\t} else if (ac == 2 && new_branch) {\n     ++\t\tif (!strcmp(branch, \"HEAD\"))\n     ++\t\t\tcan_use_local_refs(&opts);\n       \t} else if (ac == 2) {\n     --\t\tstruct object_id oid;\n     --\t\tstruct commit *commit;\n     --\t\tchar *remote;\n     --\n     --\t\tcommit = lookup_commit_reference_by_name(branch);\n     --\t\tif (!commit) {\n     --\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n     --\t\t\tif (remote) {\n     --\t\t\t\tnew_branch = branch;\n     --\t\t\t\tbranch = new_branch_to_free = remote;\n     -+\t\tif (!new_branch) {\n     -+\t\t\tstruct object_id oid;\n     -+\t\t\tstruct commit *commit;\n     -+\t\t\tchar *remote;\n     -+\n     -+\t\t\tcommit = lookup_commit_reference_by_name(branch);\n     -+\t\t\tif (!commit) {\n     -+\t\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n     -+\t\t\t\tif (remote) {\n     -+\t\t\t\t\tnew_branch = branch;\n     -+\t\t\t\t\tbranch = new_branch_to_free = remote;\n     -+\t\t\t\t}\n     - \t\t\t}\n     - \t\t}\n     - \n     + \t\tstruct object_id oid;\n     + \t\tstruct commit *commit;\n      \n       ## t/t2400-worktree-add.sh ##\n      @@ t/t2400-worktree-add.sh: test_expect_success '\"add\" <path> <branch> dwims' '\n\n\n builtin/worktree.c      |  3 +++\n t/t2400-worktree-add.sh | 10 ++++++++++\n 2 files changed, 13 insertions(+)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 654d27c3e1..15a1c9624a 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -897,6 +897,9 @@ static int add(int ac, const char **av, const char *prefix,\n \n \t\t/* DWIM: Infer --orphan when repo has no refs. */\n \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n+\t} else if (ac == 2 && new_branch) {\n+\t\tif (!strcmp(branch, \"HEAD\"))\n+\t\t\tcan_use_local_refs(&opts);\n \t} else if (ac == 2) {\n \t\tstruct object_id oid;\n \t\tstruct commit *commit;\ndiff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh\nindex 87b926728a..ba3bec078f 100755\n--- a/t/t2400-worktree-add.sh\n+++ b/t/t2400-worktree-add.sh\n@@ -621,6 +621,16 @@ test_expect_success '\"add\" <path> <branch> dwims' '\n \t)\n '\n \n+test_expect_success '\"add\" <path> <branch> does not dwim with -b' '\n+\ttest_when_finished rm -rf repo_upstream repo_dwim wt &&\n+\tsetup_remote_repo repo_upstream repo_dwim &&\n+\t(\n+\t\tcd repo_dwim &&\n+\t\ttest_must_fail git worktree add -b branch ../wt foo 2>actual &&\n+\t\ttest_grep \"^fatal: invalid reference: foo\" actual\n+\t)\n+'\n+\n test_expect_success '\"add\" <path> <branch> dwims with checkout.defaultRemote' '\n \ttest_when_finished rm -rf repo_upstream repo_dwim foo &&\n \tsetup_remote_repo repo_upstream repo_dwim &&\n\nbase-commit: dea0ea3582e6980ddbc1173cc8e3e9f9db91cde0\n-- \ngitgitgadget\n"},{"id":"550922","messageId":"xmqqecfssnk0.fsf@gitster.g","threadId":"66112","inReplyTo":"pull.2192.v4.git.1787221888406.gitgitgadget@gmail.com","subject":"Re: [PATCH v4] worktree add: shouldn't dwim if -b or -B is given","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-08-20T17:34:55Z","receivedAt":"2026-08-20T17:34:58Z","isPatch":true,"body":"\"Yoichi NAKAYAMA via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n>       @@ builtin/worktree.c: static int add(int ac, const char **av, const char *prefix,\n>      + \n>        \t\t/* DWIM: Infer --orphan when repo has no refs. */\n>        \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n>      ++\t} else if (ac == 2 && new_branch) {\n>      ++\t\tif (!strcmp(branch, \"HEAD\"))\n>      ++\t\t\tcan_use_local_refs(&opts);\n>        \t} else if (ac == 2) {\n>      --\t\tstruct object_id oid;\n>      --\t\tstruct commit *commit;\n>      --\t\tchar *remote;\n>      --\n>      --\t\tcommit = lookup_commit_reference_by_name(branch);\n>      --\t\tif (!commit) {\n>      --\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n>      --\t\t\tif (remote) {\n>      --\t\t\t\tnew_branch = branch;\n>      --\t\t\t\tbranch = new_branch_to_free = remote;\n>      -+\t\tif (!new_branch) {\n>      -+\t\t\tstruct object_id oid;\n>      -+\t\t\tstruct commit *commit;\n>      -+\t\t\tchar *remote;\n>      -+\n>      -+\t\t\tcommit = lookup_commit_reference_by_name(branch);\n>      -+\t\t\tif (!commit) {\n>      -+\t\t\t\tremote = unique_tracking_name(branch, &oid, NULL);\n>      -+\t\t\t\tif (remote) {\n>      -+\t\t\t\t\tnew_branch = branch;\n>      -+\t\t\t\t\tbranch = new_branch_to_free = remote;\n>      -+\t\t\t\t}\n>      - \t\t\t}\n>      - \t\t}\n>      - \n>      + \t\tstruct object_id oid;\n>      + \t\tstruct commit *commit;\n>       \n>        ## t/t2400-worktree-add.sh ##\n>       @@ t/t2400-worktree-add.sh: test_expect_success '\"add\" <path> <branch> dwims' '\n>\n>\n>  builtin/worktree.c      |  3 +++\n>  t/t2400-worktree-add.sh | 10 ++++++++++\n>  2 files changed, 13 insertions(+)\n>\n> diff --git a/builtin/worktree.c b/builtin/worktree.c\n> index 654d27c3e1..15a1c9624a 100644\n> --- a/builtin/worktree.c\n> +++ b/builtin/worktree.c\n> @@ -897,6 +897,9 @@ static int add(int ac, const char **av, const char *prefix,\n>  \n>  \t\t/* DWIM: Infer --orphan when repo has no refs. */\n>  \t\topts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1);\n> +\t} else if (ac == 2 && new_branch) {\n> +\t\tif (!strcmp(branch, \"HEAD\"))\n> +\t\t\tcan_use_local_refs(&opts);\n>  \t} else if (ac == 2) {\n>  \t\tstruct object_id oid;\n>  \t\tstruct commit *commit;\n\nAh, that is a much smaller patch, and does not share the same issue\nas the very initial iteration.\n\nWill queue.  Thanks.\n\n> diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh\n> index 87b926728a..ba3bec078f 100755\n> --- a/t/t2400-worktree-add.sh\n> +++ b/t/t2400-worktree-add.sh\n> @@ -621,6 +621,16 @@ test_expect_success '\"add\" <path> <branch> dwims' '\n>  \t)\n>  '\n>  \n> +test_expect_success '\"add\" <path> <branch> does not dwim with -b' '\n> +\ttest_when_finished rm -rf repo_upstream repo_dwim wt &&\n> +\tsetup_remote_repo repo_upstream repo_dwim &&\n> +\t(\n> +\t\tcd repo_dwim &&\n> +\t\ttest_must_fail git worktree add -b branch ../wt foo 2>actual &&\n> +\t\ttest_grep \"^fatal: invalid reference: foo\" actual\n> +\t)\n> +'\n> +\n>  test_expect_success '\"add\" <path> <branch> dwims with checkout.defaultRemote' '\n>  \ttest_when_finished rm -rf repo_upstream repo_dwim foo &&\n>  \tsetup_remote_repo repo_upstream repo_dwim &&\n>\n> base-commit: dea0ea3582e6980ddbc1173cc8e3e9f9db91cde0\n"}]}