Git: swap the main working tree with a linked working tree?
Asked Answered
K

4

8

I'm trying to find out if there's any way to swap working trees. My company has a lot of scripts that assume a specific directory structure, so to be able to work with multiple working trees, I would need the "new" linked worktree to take the place of the main worktree.

I found git worktree move <worktree> <new-path> but that doesn't allow "main" working trees to be moved, so there's no chance of swapping.

Ideally, there would be a git worktree swap <worktree> <path> where:

  • if <path> is a worktree, it swaps them
  • if <path> is a commit-ish, it adds a new worktree with <worktree>'s name for the commit-ish, then swaps them
Kenner answered 4/9, 2019 at 19:42 Comment(2)
Then your's company scripts simple suck. In properly written one the administrator has to be able to setup the root path of the tree. I highly recommend to fix your scripts.Underdone
@Underdone I am well aware they suck and have every intention of updating the scripts. Unfortunately, when working for a huge company, you can't always be sure all scripts will work for every scenario so it's much safer if the repo could mimic the obvious expected condition. So I would say your comment is pretty unhelpful since it seeks to obscure a still-present concern. New programmers are always going to make unsafe assumptions when they aren't familiar with every feature of a tool/technology.Kenner
L
3

git worktree repair is what you need to move the main worktree. These steps worked for me on git 2.37.3:

  1. cd ~/main-worktree
  2. git worktree move ~/linked-worktree ~/tmp-linked-worktree
  3. cd
  4. mv ~/main-worktree ~/linked-worktree
  5. cd ~/linked-worktree
  6. git worktree repair
  7. git worktree move ~/tmp-linked-worktree ~/main-worktree

From git help worktree:

Repair worktree administrative files, if possible, if they have become corrupted or outdated due to external factors.

For instance, if the main worktree (or bare repository) is moved, linked worktrees will be unable to locate it. Running repair in the main worktree will reestablish the connection from linked worktrees back to the main worktree.

Limpkin answered 18/1, 2023 at 17:54 Comment(0)
P
2

Ideally, you would:

  • move the main worktree elsewhere
  • add a symlink in the "specific directory" to the main worktree or any other worktrees.

The latter can be moved too, but if you do, make sure to use Git 2.28 (Q3 2020): the same worktree directory must be registered only once, but "git worktree move" allowed this invariant to be violated, which has been corrected with Git 2.28.

See commit 810382e, commit d179af6, commit 916133e, commit 4a3ce47, commit dd9609a, commit 1b14d40 (10 Jun 2020), and commit c9b77f2 (08 Jun 2020) by Eric Sunshine (sunshineco).
(Merged by Junio C Hamano -- gitster -- in commit 9740ef8, 22 Jun 2020)

worktree: make "move" refuse to move atop missing registered worktree

Signed-off-by: Eric Sunshine

"git worktree add" takes special care to avoid creating a new worktree at a location already registered to an existing worktree even if that worktree is missing (which can happen, for instance, if the worktree resides on removable media).

"git worktree move", however, is not so careful when validating the destination location and will happily move the source worktree atop the location of a missing worktree.
This leads to the anomalous situation of multiple worktrees being associated with the same path, which is expressly forbidden by design.

For example:

$ git clone foo.git
$ cd foo
$ git worktree add ../bar
$ git worktree add ../baz
$ rm -rf ../bar
$ git worktree move ../baz ../bar
$ git worktree list
.../foo beefd00f [master]
.../bar beefd00f [bar]
.../bar beefd00f [baz]
$ git worktree remove ../bar
fatal: validation failed, cannot remove working tree:
    '.../bar' does not point back to '.git/worktrees/bar'

Fix this shortcoming by enhancing "git worktree move" to perform the same additional validation of the destination directory as done by "git worktree add".

While at it, add a test to verify that "git worktree move" won't move a worktree atop an existing (non-worktree) path -- a restriction which has always been in place but was never tested.

Public answered 27/6, 2020 at 22:17 Comment(0)
A
1

The short answer is no: the main work-tree is different from all added work-trees.

Note that you can separate the .git directory from any work-tree using the $GIT_DIR and/or $GIT_WORK_TREE environment variables, and/or --git-dir and/or --git-work-tree options (which simply set the environment variables, then carry on as if the env vars had been set originally). But in general the main work-tree of a repository is special: its HEAD file lives in .git/HEAD, rather than .git/worktrees/<name>/HEAD, for instance.

(The per-work-tree state for work-tree W is stored in $GIT_DIR/worktrees/W, in general.)

Arabist answered 4/9, 2019 at 20:43 Comment(0)
W
1

There is no automated way to move a main worktree, however, you can do it manually:

  • rename the main worktree, eg mv master main
  • edit the .git files in every link worktree to reflect that change, eg: sed -i 's!/master/!/main/!' .git

.git is a directory in the main worktree, but just a text file containing the path to the main worktree in the link worktree, which you can edit with your favourite editor.

Warila answered 4/1, 2021 at 19:5 Comment(1)
I think if you're doing this you gotta update it both ways (there's references in the main Git directory to the worktree too). The good news is that git worktree repair main should handle all of it.Poaceous

© 2022 - 2024 — McMap. All rights reserved.