I have no idea what use case is satisfied by git worktree, based on that blog post. In the case that you desperately needed to have two branches checked out, why not just clone twice?
With multiple clones, you would need to remember to update each clone regulary not only from remote, but also push/pull locally in case you want to compare your state with other branches.
A 'git checkout' on a large repository such as the Linux kernel may take a while (bound by I/O performance). Regulary switching between branches with many changed files becomes annoyingly slow.
If you keep multiple clones, you actually keep multiple copies of the full history, which seems like a waste of disk space (yes, deduplicating filesystems exist, but are rarely used).
git worktrees are also very useful if you have unfinished on a release branch. You do not have to make temporary commits or stashes you forget about, you can just leave the modified files as they are and switch to a different worktree to continue your work on another branch.
`git clone --local` does hardlinks, space usage is quite low, so I'm not really sure that part holds up. Maybe in Windows? Switching branches can definitely be slow tho, yeah. Do worktrees change that somehow tho?
From all I've read so far (quite limited!) they just sound like replacements for `git stash` or making a temporary commit / branch, but with a new set of commands and rules to learn. I don't find `git commit -am tmp` (literally, I just do that) to be particularly worth optimizing further, and worktrees so far sound like substantially more work.
---
edit: ah, yeah, updating multiple clones is definitely annoying / easy to forget, totally agreed there. that alone might make it worthwhile. I only need it like once a year so I probably won't, but I do know some coworkers who do it a lot.
git worktrees can also be useful if your build system needs different arguments per branch. For example if you keep multiple release branches installed side-by-side on your machine, it is easier to just run `./configure --prefix=/opt/release-X.Y` only once on a worktree instead of repeating this procedure every time you switch branches. That way you can even keep all your object files around and save the time to compile them again.
The same also applies to languages such as Python or Node.js, where you might have a different set of dependencies depending on the branch and don't want to regenerate your virtualenv or node_modules on every branch switch.
aaahh, so it can track un-tracked files too? that I can definitely see being useful - the lack of a "local" / "remote" git ignore split makes this kind of thing hard :|
(yea, there's .git/info/exclude, but you can't add it to a branch and have it only exist locally. and it has weird interactions when something becomes tracked later.)
I use it to build multiple versions of Go from source locally. When a new release branch appears, I just `git worktree add release-branch-1.12 ../go1.12`, then `cd ../go1.12/src` and `GOROOT_BOOTSTRAP=../go1.11 ./make.bash`. It makes it very easy to try out betas while staying in sync with patch releases. It’s also great for keeping an old version of Go around if you have some project that requires it.
I usually use it to keep an unrelated branch easily accessible. For example:
- website generator (JS stuff) on "master" branch checked out at $PROJECT_ROOT, and website content (Markdown files) on "content" branch checked out using git-worktree at $PROJECT_ROOT/content.
- Project source code on "master" branch checked out at $PROJECT_ROOT, and images needed for GitHub README file in "media" branch checked out using git-worktree at $PROJECT_ROOT/media.
I never use it for quickly switching topics (that's the git-stash use case, it you can just make a temporary commit).
Have a "develop" branch that does not contain any generated files, and a "master" branch that does. Have a post-commit hook that uses a worktree pull every commit from "develop" to "master" and generate any files.
That type of workflow is possible by cloning the local repo, but is kludgey and brittle enough prior to worktrees, I had never considered that workflow viable.
I usually leave release engineering tasks such as denormalizing data (generating derived files) to release time and Fossil has a particular place to keep these bits, as unversioned artifacts (which are optionally synced, on a per repository basis).
I usually agree with that. The projects I was referring to are either Go (where the norm is to check in code-gen'ed files, so that things are `go get`able), or static websites (where every commit will get rolled out as soon as you push it).
The main reason I'm using worktree instead of two clones is that you can commit in one and cherry-pick in the other immediately, without pushing/fetching. You can rebase the branch in development in worktree 2 on top of something else in worktree 1.
Sometimes this is fine, but if the history is large enough (like in the case of the Linux kernel), it can start to get out of hand space-wise. If you have a deduplicating filesystem, that can help, but only so much.
Of course, there is a way to use clone which hardlinks the objects.