Hacker News new | past | comments | ask | show | jobs | submit login

Being able to explore code from another revision in your regular editor side by side with your other branch (two editor instances) is a big plus of worktrees. Maybe it wouldn't work if you use some heavyweight editor like Visual Studio or Eclipse or if your project is massive and IDE intelligence features take up a lot of RAM, but for lightweight editors, small-medium projects it works great.

I personally use it all the time on longer lived projects. Stashing/unstashing is fine, but I like really like the flexibility of just being able to switch over to another branch to fix something, review a PR, or anything else with zero mental overhead of keeping track of stashed work.




The thing that annoys me about worktrees is that you can't have two checked out to the same commit at the same time [0], which can be inconvenient when I forget about one that I had open a few days ago. This also breaks the feeling of isolation, since the issue doesn't exist if I do a fresh `git clone` to another directory, so it begs the question of what fragility is present in worktrees that isn't in a fresh clone.

In other words, I wouldn't feel safe doing weird Git operations in a worktree, so why use one in the first place? If I want a true throwaway repo, I'll just re-clone in another directory (and make sure to remove the remote, to be extra safe in case I accidentally push).

Also, git worktree requires me to make a new directory anyway! So why would I not just put a fresh clone in there? To save a few megabytes of the .git index?

[0] https://stackoverflow.com/a/39668520


You can do this. You just need to use --detach.

When you check out a branch, your working directory is expected to be in sync with it. Internally the HEAD points to the branch which then points at the commit. When you make changes on one worktree, in general it doesn't update the other worktrees.

So if you change the reference that the branch is pointing at, when you look inside the other worktree that points to that branch, it has no way of knowing it was initially looking at a different commit and it just thinks that the diff between the current head of that branch and your current working directory is a bunch of uncommitted changes.

If you use --detach or refer directly to the commit instead you get the behavior that is expected which is that it points to the commit itself and not the branch (which then points to the commit).

> Also, git worktree requires me to make a new directory anyway! So why would I not just put a fresh clone in there? To save a few megabytes of the .git index?

The problem is that not all repos are small and often it's easier to just do things in one repo than to need to push everything up and pull it down to move between multiple repos.

Also not all repos are small. The linux repo (which if you are working in the higher spec side of embedded software you probably will be using with multiple different downstreams) is at least a gigabyte in size nowadays. I like having the whole repo when I can because it makes looking for stuff locally easier but I don't want to lug around multiple copies of that repo if I can avoid it.


They can absolutely be checked out to the same commit. They cannot be checked out to the same local branch. But checking out to the same SHA, or even the same remote branch (which, really, is just another name for a given SHA) is just fine.

I have two workflows heavily benefitting from worktrees. The first is simple enough...code archeology. I want to do it without disturbing my working tree. Yes, this could have also been done with a separate clone, but I'd have to fetch in that clone, and that's just extra keystrokes.

The second is that I like to have a "synthesis" worktree...one that includes PRs I'm reviewing and ones I'm creating. Both benefit from my regularly building and using them (e.g., I might incidentally find bugs through usage I otherwise missed through testing or code-reading, or I might spot pending integration problems). I don't want multiple build locations...I want to run everything in one build.

But when I've finished developing a PR, need to create a clean version of it from the master branch. In my secondary worktree, I can just cherry-pick commits from my synthesis worktree to produce a clean branch to push. I could do this in the synthesis worktree, too, but at the cost of almost certainly forcing a complete rebuild. In a second clone, I'd have to create patch files because the clone wouldn't have access to the commit objects for cherry-picking.


You can make a temporary branch if you want an identical copy of a revision. For example, `git checkout feature-x` (on worktree 1), then `git checkout -b feature-x-temp feature-x` (on worktree 2).

I've never had any issues with worktrees after heavy and extensive worktree usage since 2017. I use it regularly on big projects. The only time I had an issue with git was actually on a small non-worktree repo after 10 years of using git. The .git/ metadata got corrupted somehow, never understood why or how.

When you have a worktree based workflow, you're getting the benefit of a single .git/ database managing them. Whereas if you have multiple standalone clones, you have to manually keep them up to date. With worktrees doing a `git fetch` will ensure all worktrees are able to do git operations on the most update to date git data. Whereas separate clones means you need to do N git fetches.

Saving a few megabytes literally doesn't matter. Your project dependencies will likely use up tens if not hundreds of megabytes when you install them (pip packages, node modules, etc). Disk space is never really an issue anymore is it? Disks are hundreds of GBs now even on low end machines. I probably have multiple GBs of redundant disk usage because of my worktrees, but the convenience is well worth it IMO.


I find this very annoying. I don't know if this is the right thing or not, but my workflow for starting new work is "git checkout master; git pull; git checkout -b new_work". This is all fun and games until you have a worktree that's sitting at master. Now you have to figure out where that is, chdir there, and update that branch from the remote. It's actually extremely annoying.

Maybe there is "git update master from remote and throw away my local changes because if i committed something there that was a mistake". But probably not, sadly, because technically the "git pull" operation to pull origin/master into the local tracking branch master updates the working copy where master is checked out, and that's what worktree is trying to avoid (changing a directory you're not in). I guess "git pull; git checkout -b new_branch remotes/origin/master" is what I should write, but that's more bytes to type.


I get around this by having "wt-" (wt-1, wt-2, etc) branches that act as my main/master branch per work tree.

As long as you set the upstream to master, it works fine, you can pull in upstream main/master changes without issue. It does mean you have these "wt-" branches, but it works well enough for me, never got in my way or caused me to stop using worktrees.

My workflow is like this: For each worktree I add, checkout a new branch, wt-N, with it's upstream set to main/master. If I need to checkout some other branch in a worktree, do it, finish up, check out wt-N again, git pull to bring it up to date with upstream. Leaving idle worktrees on a "wt-" branch so I don't have the issue of "branch X is already checked out out worktree Y"


  git fetch origin
  git checkout -b new_work origin/master
Git pull is essentially git fetch + merge. You don't have to update your local master branch to check out a new branch based on it.


just a minor nit but you don't even need to do `remotes/origin/master`, just `origin/master`.

Alternatively you could do `git switch -c new_work && git pull -f origin master` which will create a new branch (you could use `git checkout -b` as well but like you said, more bytes to type) and then force pull from master on origin into the current branch (which is now your new branch) replacing the history with origin/master.


> The thing that annoys me about worktrees is that you can't have two checked out to the same commit at the same time

Checking out the same commit is fine. You just can’t checkout the same branch.

This is not a problem for me because I either use detached head (if say I’m going to build from some commit) or restrict branches to certain worktrees naturally (if I am backporting to `old-version` on a worktree then... it’s not like that backport branch is ever going to be relevant in my main worktree where I do most of my work).


I used to use it myself. Not too much of problem. I just didn't use it enough to warrant use. Was quite straightforward to just switch up. But I shall try it again and see.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: