Developer Productivity

Tools: Git worktrees



Developer Productivity

Check out a free preview of the full Developer Productivity course

The "Tools: Git worktrees" Lesson is part of the full, Developer Productivity course featured in this preview video. Here's what you'd learn in this lesson:

ThePrimeagen demonstrates using git-worktree to manage multiple working trees attached to the same repository and discusses the benefits and drawbacks. Student questions regarding when git-worktree wouldn't be useful and what happens when a change gets pushed up stream are also covered in this segment.


Transcript from the "Tools: Git worktrees" Lesson

>> So now we're gonna go into section 3. All right, I know I backed away from the computer so I didn't mute myself. I don't know if you saw that I got really excited. I don't wanna mute it all. But this is tools in the future. Yes, the future, not just 2021 but even further beyond, but first we're gonna take a quick pit stop in tools.

Cuz tools are fantastic. I just wanna highlight a couple of them. So let's do this. I call this part git the cool parts. Really, I know that most people probably use git, I just assume use git. It's kind of like the hot thing for like the last decade at least.

I really liked git. But for about eight years, I really only knew about push pull and rebase. Right? That was me. I rebased, I pushed, I pulled, William, I know you're around on the stream from time to time. So you probably already know partially where I'm going at this point with this, but there's this feature.

That's really awesome. It's called work trees and most people don't know about them. How do I know most people don't work? No bottom, well just this year Guido van Rossum the Guido himself said why did I not know about get worktree, right? Sad face classic, 1990 sad face has the nose and everything.

So people really don't know about these features. It's true. Like these are weird features that are hard to like you just you never run into them, right? You have no reason to run into them because you're always just simply checking something out. What you don't realize is you're actually in a work tree when you check something out, but it's a little bit different.

There's better ways to work with it. So what is the work tree? Well, there's a lot of ways, let's see. So how would you describe a work tree a word tree simply is a commit in time. Just like if you're on master, you're at technically art. Actually add a commit, right?

You're not all of the commits before it's do not make the branch. The current commit is really what the branch is. And that's just a named commit. It's kind of how I think about it. A work tree is just a named commit, right? You're just gonna say hey, I'm gonna go to this, this commit at this point in time, you can have several work trees at once.

Meaning that you don't have to just have this one that you're always working on. You can have several of them at once. It's quite fantastic. You can do it without having bear repos and all that. But I suggest using bear posts will kind of get into it here right away.

So there's a lot of ways, but I'm just gonna show you, you can read up on strategies. You don't have to use a bear repo, I just prefer it that way. So here we go. So let's check out my favorite project in the universe, which is the one I've been working on called refactoring.

Now, for whatever reason we're gonna just do it inside of my temp, for whatever reason, when you do a git clone bare. What will end up happening is that it actually adds the dot git as part of the name. Normally, when you clone something out you don't get that dot.

You don't get the dot on the end it just drops it, but bare for whatever reason refuses to drop it. So you always get the docket. So I always have a name afterwards. So I name it, I'm gonna clone from this repo, and I'm gonna name it this.

There we go. So we're gonna go, we're gonna clone, it's fantastic. Awesome, we have it. Let's cd into refactoring. And what do we have here? Well, this looks not what you're kinda used to, right? And if I go like this, git status, it's like I don't even know what you're talking about?

What's this status business, right? You're not in a work tree. So this is not how normally git works, right? This is just not how it works. So, this is a little bit different, but it does have a git folder. So if we go LS dash LA, you'll notice there is a git folder somewhere else, nevermind that the information is just all spread here.

Sorry, it doesn't have a git folder blah blah blah but there is always all that information in there. This is effectively your git folder, right?. It has a bunch of that in there. So how do we know what's available?. Well, we can start off with git, work tree list.

It's gonna say, hey, this is what you have, which currently is nothing fantastic, right?. So how do we know what to use, like right? Well guess what, let's use man to start of with, right? Man git-worktree, here we go, I think the first sentence is pretty good, let's see.

A git repository can support multiple work trees, allowing you to check out more than one branch at a time, with git worktree add. Also we kinda already know what's going on here a new work tree is associated with the repository. This working tree is also called a linked working tree, as opposed to the main working tree prepared by a git init or git clone.

So there you go. So whenever you check out with just git clone, you have a main working tree. Now this one's a little bit different, all right? We're actually selecting which ones we want. A repository has one main working tree, if it's not a bear repo, right? And zero or more linked working trees.

When you're done with linked working trees, you can remove it with git or tree remove, or you can delete the folder and use get work tree prune. I added that last part because it's part of Griffin, he just got to keep going, just got to keep going. All right, so also it's really great, we can use

My goodness, it's like we're already ready to use these things. So I'm just gonna go like this Here we go, it's actually using something called TLDR. So we don't even need to use we could actually just use TLDR go git. I think it's worktree I always forget how to use this.

You use the TLDR here. My goodness, dash. There it is. Alright dash. Always forget how to use word tree. Okay, so we need to do get work tree add path to directory branch name, we can create a new branch by using the dashboard. So a lot like git checkout dashboard creates a new branch.

We can do get worked through your list and get worked reproved. So there's a lot of its major operations we kind of now just know how to use them. So let's use one. Let's go, git work tree add master up, we got to do two things, right? Master, because that's the path plus this one, it already exists.

We can't just do that. So is it B? No, it already exists. So why didn't that work out? Do I already have master checked out? I do. It's right here. Silly me. It comes with it. So let's check out something else. Let's check out a new work tree, right?

So let's go -b and go foo, right? And let's create a branch called foo. There we go, we now have a branch called foo. So if we real ls in here, we'll see that we have a new folder called foo. It's right there. If we do git worktree list, you'll notice that we have these two beautiful things right here.

I must have actually added master at some point. I don't know why I didn't see that before, anyways either way, you'll see it right here. We have these two. So that means when I go into say foo and I look at it, it actually is my repository, right here.

This like genuinely is my repository. This is equivalent doing a git clone, this is my working tree. So let's make it more obvious. All right, we're gonna go in here we're gonna go to, let's go to 106. Here we go. I'm gonna put a space in here. I'm gonna go to GS.

You'll notice that I'm in head foo. Where it's at all those things so I'm gonna go over here and I'm gonna check out master for a quick second right master does not have that right? Master does not have that. So look at that I just went from one branch that has an act of change right now going to another branch that doesn't have it.

Right, I just switched between those two branches. And they both exist on my system at the exact same time, right? They're both still right here, master and foo. So if I were to go see the foo, git status, I actually have a change right here. And if I were to go back to my main branch right here, I'd go git status.

It has nothing in it. So this is one of the huge I think superpowers of git work trees. When would I not use these? When would I not I always use work trees if I have the chance to like so when I did the Gatsby course you have to check it out using Gatsby.

Gatsby does not allow me to use working trees. I can't do linked working trees the way I normally would like to. So it kind of it breaks my workflow. But on every other project, I effectively use work trees. And if you have something that has like a strict build to it, something that has like, especially if you work on a version system, work trees are 10 times better, right?

Because now you have all these separate versions that each have their own builds associated with them. You can kinda keep them all independently and all independently checked out at the exact same time. It is kinda works out with web apps when you're talking about JavaScript. The difference is that when you check it out, you have a new place in which you need to do an NPM install.

The nice part is if you have a good integrated editor with work trees, you could set up a hook. So that the moment you check out a new branch, it auto kicks off like an NPM install or a yarn install. So it could actually do all the setup for your branch without you even seeing it.

So by the time the 40 seconds go by or however long it takes for you to install and get your stuff up and running. It could already be ready for you per branch, meaning you don't have to rely on this weird state of making sure you're always up to date.

It can do all those things for you. Every time you switch branches, you can do another, NPM installed to make sure your pack is all your lock is all correct. And all that it's really. I really like it. The only downside obviously is that you literally have like a gigabyte of node modules on your system.

Just because there's so many, I hear it's heavier than a black hole, but like it's a lot of stuff inside of node modules. To me, that would be the only real downfall to this is that you just have to do these actions per checkout. As opposed to having most of your node modules already set up from one checkout to the next.

But to me, just having some good linked up to link. Gets rid of that problem anyways, I don't really care disk space is cheap. I use it all the time. I love these things. I think it's fantastic. And the best part about it is like Sam right here, I can still go and I can fetch origin and update everything.

So that means if I'm on one branch, so let's just do something really quickly. I know people aren't going to be that excited about this. But let's do it anyway. So I'm gonna go to my main branch, right?. We're gonna go up there, I'm gonna go to 106.

And I'm gonna go I think it was right here. I'm gonna save this go here. I'm gonna take that CC, live test. Sorry about the command, whatever. Go here, go here. Quit get push. I am technically using my most popular open source repo. People are gonna get this dumb commit right in the middle of their stuff.

Who knows? I put the space there, right? So now let's go and let's check out Fu again. So there's Fu. Now Fu happens to have a space right here. So here I'm gonna put that space right here and I'm gonna make the commit right now, testing, right? And now we need the rebase, right?

So I'm going to fetch from origin. Everything's updated. So technically I can git rebase foo. I can get rebase from master. Right. So rebasing, everything still works, right? So just rewind that and put it on top of it, it must been able to tell hey, you're doing the exact same commit.

I'm sure if I would have done something a little bit smarter right there, I could have caused a merge conflict a little bit easier. But it works no different than if you're just working on a single kind of the main working tree style. Where you can still rebase and you can still rebase from another branch.

It just simply, you now have multiple branches, which means you can have multiple things running at once. I don't know if he ever did this, where you're working on something. You're making some progress someone says hey, I need some help. Can you help me with this? You know this other thing.

So what do you have to do? Either at the stash it or you have to commit it with some sort of don't forget to squash me later message. You do that you go, you check out something else. You hydrate everything back up. And now you're running on this new one.

And then when you're done with that, you have to take it all down, go back to the other one and either make sure that everything's working correctly on that one or unstash it. And make sure the build and everything is correct on this other one. With work trees, you just don't even have that as part of your workflow, right?

I just simply need to create a new work tree. I have a nice script to do it for me at this point, but here, I'll just quit and do right here. I'm okay, I need a new work tree. Git checkout, my goodness work tree add. They help-someone one, right?

This is my path. I want a new branch and help-someone, right? We'll name them the same thing. There we go. We have a new one right there. And so now it's right there, it's right here. So we could actually have that thing checked out from the latest commit from master right there.

Fantastic. It just works and I just love that. To me this is one of the greatest features that people just don't know about. You can really take advantage of a lot cooler things and I feel like it's just as way less cumbersome than the old way I just hated the old way.

It just made me nuts. Right. You can still use stashing to write I did forget to talk about this. So let's go. Let's go to foo, we got a foo. Awesome. Let's check out 106 there we go. Do that go here, right here. There we go. We have this I can stash it.

There we go. I just stash that. And now I can go back to master. Right and there we go. It's right here and then I can go and I can get stash pop right? I popped it there we go. There's the space, right so you can still get.

You can stash from one tree and bring it over to another tree, right? It all the same. It's just now every check out or every commit can have its own directory. So to me awesome. I love it. It's fantastic. All right, question.
>> What happens when you push a changeup scream after entry is created.

>> It's the exact same thing effectively. So I created foo right? So now what I can do is let's go back and let's check out foo. So if I were to go in here, let's close this thing down like this. Git branch. All right, there's a bunch of branches but look, I have little plus sign.

So normally you just have a single item, right inside of this list. But in this one, it's all the work trees that I have versus all the other branches. So I can have like this. I can go git push origin foo, right? I'm gonna push to my origin foo.

And when I go to GitHub refactoring, you'll notice right away it's no different than if I just checked out a commit. Right, is I'm gonna have something called foo. I don't know why it's not showing up. It's because it's identical to master right? But I will have in here foo.

So it's not different. Just treat them like they are checkout right. That's what a work tree is. Remember when you do git clone some project you're in a work tree. You're just in the main work tree. When you do a git check or clone bare, you can only use linked work trees, which means you specify each one.

So that's why when I did git branch, I actually had multiple of them. So let's go like this. Let's do anything. Let's go grep. What does that star or plus, there we go. So I have these three work trees all checked out at the exact same time, and I can go between them at any point.

So they're no different than just a standard checkout. It's just that they're simply separated by path to me just makes it way more convenient. There you go. That's the pros and cons. Really the only con I can see is that it's a little bit more work all right?

So I don't know what, VS code has for integration, but because, by the way I use vim I don't know if I type on Dvorak to I don't know if you know that by the way. But I don't know the exact tools that it has. So therefore, I can't tell you how convenient it is.

But because I wrote the actual tool to work with work trees in git, and I use fugitive, I have it like perfectly and seamlessly working the exact way I want. In fact, it works so well inside of my vim experience that I actually have something called git work tree.

Where I can go in here. Let's see what is it, print hello and then go, op, path, upstream, there we go, close all those things, reopen up vim. And whenever I change a tree, it will go through here and it will tell me Hey, I've just switched the table.

I've done all these things, or I've just switched it gives me a table, it tells me what happened. So therefore, I can actually take all this information and I could create hooks into tmux. Right? So, right when I switched that branch, you know what I could have done?

I could have created a command to go out to the system, create a new tmux window using detach so it doesn't take over my current window. Remember detach is a thing, right? So I could have, just to show you. T mux new window d look at that it created a new window without me even seeing it.

I could have created a new window with the command NPM install. So could have done that in the background every single time I switch branches so I know it's always up to date, whatever I'm working on at any point I can do that through them. So very good kind of creamy experience that that creamy beige we all want, right?

That's a weird way to say it. I've watched too much old Greg. Alright. That is that there we go. That's pros and cons. Really. I I think there's way too many pros versus the cons. Like I said, maybe a lot of NPM modules you'll probably have like a tonne like a gigabyte.

But honestly, I have 595 gigabytes left right now I could have a lot of node modules.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now