Elijah Newren <newren@xxxxxxxxx> writes: > On Tue, Jan 25, 2022 at 3:36 PM Glen Choo <chooglen@xxxxxxxxxx> 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. > 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@xxxxxxxxxx> >> --- >> 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