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

Re: [PATCH] sequencer.c: set GIT_WORK_TREE in run_git_checkout

From
Glen Choo <chooglen@google.com>
Date
Jan 26, 2022, 00:22 UTC
Message-ID
<kl6lczkf1h32.fsf@chooglen-macbookpro.roam.corp.google.com>
In-Reply-To
<CABPp-BGkpjD=WFSFSY9g85MAZ2JUh+UCfi6NThevZ4RxZUxtVw@mail.gmail.com>
Elijah Newren <newren@gmail.com> writes:
Show 23 quoted lines
> On Tue, Jan 25, 2022 at 3:36 PM Glen Choo <chooglen@google.com> wrote:
>>
>> When rebasing in a subdirectory of a worktree, Git fails due to a dirty
>> worktree:
>>
>>   error: The following untracked working tree files would be overwritten
>> by merge:
>>           a/b/c
>>   Please move or remove them before you merge.
>>
>> This occurs because "git rebase" invokes a "git checkout" without
>> propagating the GIT_WORK_TREE environment variable, causing the worktree
>> to be assumed to be ".". This was not an issue until bc3ae46b42 (rebase:
>> do not attempt to remove startup_info->original_cwd, 2021-12-09), when
>> the .dir of the "git checkout" child process was changed such that it no
>> longer runs at the root of the worktree.
>>
>> Propagate GIT_WORK_TREE to the "git checkout" child process and test
>> that rebase in a subdirectory of a worktree succeeds.
>
> This is correct, but leaves the reader wondering why the failure to
> set GIT_WORK_TREE fails when in a non-primary worktree, but does not
> fail in the primary working tree.
Ah, that is true. Thanks for digging into it deeper.
Show 43 quoted lines
> Here's how I described it in the patch I was about to send to the list:
>
> """
> In commit bc3ae46 ("rebase: do not attempt to remove
> startup_info->original_cwd", 2021-12-09), we wanted to allow the
> checkout subprocess to know which directory the parent process was
> running from, so that the subprocess could protect it.  However...
>
> When run from a non-main worktree, setup_git_directory() will note
> that the discovered git directory
> (/PATH/TO/.git/worktree/non-main-worktree) does not match
> DEFAULT_GIT_DIR_ENVIRONMENT (see setup_discovered_git_dir()), and
> decide to set GIT_DIR in the environment.  This matters because...
>
> Whenever git is run with the GIT_DIR environment variable set, and
> GIT_WORK_TREE not set, it presumes that '.' is the working tree.  So...
>
> This combination results in rebase failing when run from a subdirectory
> of a non-main worktree.  Fix it by also setting the GIT_WORK_TREE
> environment variable along with setting cmd.dir.
>
> A possibly more involved fix we could consider for later would be to
> make setup.c set GIT_WORK_TREE whenever (a) it discovers both the git
> directory and the working tree and (b) it decides to set GIT_DIR in the
> environment.  I did not attempt that here as such would be too big of a
> change for a 2.35.1 release.
> """
>
> (Another fix would also be making sequencer stop forking a "git
> checkout" subprocess; it should be able to call a library function,
> and then quit dropping and re-reading the index.  But that's also a
> much bigger change...)
>
>> Signed-off-by: Glen Choo <chooglen@google.com>
>> ---
>> Here is a fix for the bug I found in [1]. I didn't look through the rest
>> of the "preserve cwd" thread for other possible bugs pertaining to
>> worktrees, but I didn't find any during a cursory glance at sequencer.c.
>
> We'll need the same fix for stash due to 0fce211ccc ("stash: do not
> attempt to remove startup_info->original_cwd", 2021-12-09) -- in that
> case, though, it's calling git-clean rather than git-checkout.  But
> the same idea.
Let's use your patch [1] instead of mine :)
[1] https://github.com/git/git/pull/1205
Previous: Elijah Newren
Message 5 of 5 in “sequencer.c: set GIT_WORK_TREE in run_git_checkout”
  1. sequencer.c: set GIT_WORK_TREE in run_git_checkoutGlen Choo, Jan 25, 2022
  2. Glen ChooJan 25, 2022
  3. Elijah NewrenJan 26, 2022
  4. Elijah NewrenJan 26, 2022
  5. Glen ChooJan 26, 2022

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.