Episode: 3307 Title: HPR3307: Git worktree Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr3307/hpr3307.mp3 Transcribed: 2025-10-24 20:31:57 --- This is Hacker Public Radio Episode 3307 Fortuzzi, the 6th of April 2021. Jid's show is entitled, Jid Worktree and is part of the series Introduction, to Jid it is hosted by Klaatu and is about 25 minutes long and carries a clean flag. The summary is how to use Jid Worktree. This episode of HPR is brought to you by archive.org. Support Universal Access to All Knowledge by heading over to archive.org forward slash donate. Hey everybody, you're listening to Hacker Public Radio. My name is Klaatu and in this episode I'm going to talk about Jid Worktree. Jid Worktree is I think a fairly new-ish command within the Jid suite. I say I think because I didn't really track it back to see when it was introduced but the man page that certain features about Jid Worktree are in an experimental stage. Anyway, Jid Worktree is an interesting little feature of Jid that I don't feel a whole lot of people know about yet and I figured it would be worth an episode. So imagine this and this is kind of a canonical example straight out of the the man page. So it's and I think it is one example. I think it is a common example. So you're working on some software. You've been working all week on this new feature for this software branch. Maybe you've been assigned assigned this feature or maybe you have maybe you're working alone and it's just this is what you've allotted your time for. Whatever it is, exciting new feature you've been working all week. Suddenly your project manager comes in and says there's an urgent fix that needs to be made. You have to drop everything and make that fix. It's a hot fix. It's got to be done. No question has to be done right now. Drop everything. So the problem with that scenario is that it it demands that you sort of risk the integrity of your current influx Jid Worktree. And when I say Worktree, it really just means the the the get clone that you have of your original upstream repository, you know, when you did a get clone, you've got this directory, right? You've got a folder that that you know is a get repository. You've got a get directory in it. It's being tracked by get. So that is called a work tree and the the the term work tree or tree to represent a directory structure or a version control system goes back a long way and you can kind of imagine it as really a tree where the the main trunk of the tree is in get what we call the master branch. I don't know why we don't call it the trunk in get except that I think the theory is that there is no trunk in get. So I believe that's why they didn't use trunk because it is decentralized sort of. So so yeah, I guess there's no there is no trunk. But if you think of it as a trunk, then you've got your trunk and then you've got you you can create branches and when you're finished working in a branch, you can merge that branch, you can graft that branch back into that main trunk thereby adding to the that sort of through line of of finalized approved source code. And branches are are designed for sort of in part for this situation where where you do you realize one afternoon when you're when you've been working on something for a week, you realize that way back there in in the master branch, there was a really important that there's there's a problem. There's something that needs to be fixed and you have to drop everything for whatever reason. It could be a security problem. It could be something that you checked in that you didn't need to check in yet or rather push that you didn't need to push. You know, whatever it is, something back there you need to fit. And in theory that the branch structure does let you do that. It lets you walk away from from one set of from one from one one one workspace as it were and and switch over to a different workspace. But in practice, your workspace can get pretty messy where I should say your work tree can get pretty messy. And for instance, you might have files that are modified. You have files that that get doesn't even track yet. You have files maybe that are temporary and you don't want to you don't want to lose track of. You know, there's just kind of it becomes sort of a marriage of fragile marriage of of what you're holding in your head of how all these pieces fit together and and what get believes everything how everything fits together. And to walk away from that can just it can be a little bit risky. Maybe not technically risky, although sometimes it might be. I mean, if you if you accidentally if you're mucking around in your in your workspace, then then something could get moved. That wasn't supposed to get moved because you weren't thinking about it because now you've moved on to this hot fix that you have to make and you forget that this one file is really super important for and so on. So it's really it's for safety. You probably wouldn't really want to necessarily work in that same area. Now, there is another mechanism aside from get branch that is designed to help with this and that is called get stash. It probably deserves an episode on its own. Actually, I don't think I've really talked about get stash all that much. It's a pretty handy mechanism and it's kind of this idea that you've yes, you've got your workspace or your work tree and suddenly you realize you have to do something important somewhere else. So you can just take everything in your workspace and put it into a box, shove the box on a shelf and now you've got a clean workspace. Brilliant. It's perfect, right? Well, yes, in in theory, it is perfect. In practice, sometimes that doesn't quite work out as well as as it needs to because get stash doesn't get can't it's not going to take care of some of the files that you've got going on or it's going to depend on a certain state of your branch in order to make sense and so on. So it does work, but it doesn't I don't think it's a it's not quite the clean slate that you might want. So one of the solutions that has come up, I guess maybe recently, maybe not. Either way, I learned about it recently. Another solution is this command called get work tree. Now I do feel like there was an unofficial version of this command. It's really a hack where people we've probably all done it. I mean, I know I've done it. I know I've seen other people do it. So I think it's a I think it was a common hack that that probably got made official and and cleaned up a bit by work by get work tree. But the hack was that you would just kind of tip toe out of your get repository. Do a copy recursive of your food dot get folder and now you've got food dot get dash hot fix and you go into that copy. You do a get hard reset or a get what is it get dash dash hard head reset. And I'm saying that wrong. I can type it correctly. I promise. I think it's get reset dash dash hard head all capitals there. I said it allowed and it worked. So you do get reset. And then you just do your your changes. You know, maybe you make a new branch. Do your changes on this copy on this clean on this sanitized copy of your repository or you could just maybe just do another get clone, you know, whatever. The point is that you essentially you just you abandon your current work tree for tin like it doesn't exist for a moment. Do the emergency work in some other physical location on your file system commit your changes push them and then get back into your get work tree. So there is a method of sort of getting around get and the problem with that is exactly that that you're getting around get and you're getting around get. And that's that's not necessarily a problem. I mean, it's a hack and it works and I think a lot of people have done it. So I guess that's that. But I think when you start resorting to that sort of I don't know shadow IT as it were or shadow coding or whatever. I think it betrays that either you're in a state personally, if not understanding the get, well, the state of get or the mechanisms of get or that get doesn't understand what you need or or or or lacks a feature that you need or that you don't know about a feature that get has. So I you know, I mean, I've used a couple of hacks on get I'm I mean, I maintain a hack for get called get portal which sim links binary blobs to local storage so that you don't have to check them into your get repository and it works quite well for me and and that's a that's a total hack. But works for me works pretty well for what I use it for. So it's not I don't know. It's not a problem that I do that. I'm aware that I'm doing it. It's not a problem for me and doing this sort of copying of your work tree works. It's just it does tell it broadcasts to someone somewhere that the users needs are not being met by get I think and I think get work tree is a way of resolving that dissonance and it provides a couple of features. I mean, this isn't just a sort of a philosophical thing of oh well, you shouldn't be doing something because of get outside of get it. That's not what this is. This is I feel this is something that that actually serves a purpose and provides some interesting new features. So what we'll do is I'm going to create I'm going to go to my demo folder here and I'm going to make a make a directory called penguin dot get. I'm going to change directory into penguin dot get. I'm going to do and get a knit dash dash bear and so now this is a an inside out get repository that I shouldn't work in because this is going to be that this is my my pretend remote. This is my origin. So what I've just created we will pretend is on a server somewhere. So it's it's out there on the internet and now I'll back out of that and I'll make a new directory and I'm going to call this one penguin and as you can imagine I'm going to do oh actually I'm going to remove penguin dot clone that I just made remove that directory and I'm going to instead do a get clone of penguin dot get get clone penguin dot get and I'm going to clone it right right here in the same directory to a thing called penguin dot clone. Now it's warning me that I've cloned an empty repository and it's correct that I have and that's fine and if I do an LS dash a I see that there is a get directory here so that's good that means I'm in a get controlled environment. So penguin dot clone is my work tree that's my that's what this is called is it's it's the it's a we we often call it just a get repository or a get clone or something like that but but technically speaking I guess in get terms this is my work tree is my local copy of something that exists somewhere else this is my copy of the of all that source code this is my work tree this is where I'm going to do my work. So the first thing I'll do I guess is do and I'll do an echo of hello and I'll redirect the output into a file called hello dot txt and I'm going to get add hello dot txt and I'm going to get commit as first commit and now I have a get log that consists of one commit which says first commit and I've now got that in my local get work tree now I'm going to get a remote origin add unless I already have that I'll do a get remote dash v okay it already knows where my origin is that's good so I'm just going to be able to do a get push origin head and so now my I've just pushed my changes up to my server so now I've got hello dot txt committed in my log and pushed to the remote server which in this case of course is just a directory on my file system called penguin dot get and I'm in penguin dot clone okay so that's that's kind of the setup now let's pretend that for several weeks I've been working on this exciting new feature and in order to do that I guess I would have done a get checkout dash v dev so I've just created a new branch and checked out that branch and it's called dev and maybe here in dev I have changed or I've created a new file or actually maybe I've yeah I've created a new file I'll do an echo foo into a file called foo dot txt and maybe I've even maybe I've maybe I've changed well that it's gonna I keep wanting to change something but I've only got one file so I guess we won't do that I guess it it'll be enough right now because I don't want to get into get um commits or get merges and merge conflicts I think that's overstepping the scope of this so I'm going to just do an ls and I've got a hello dot txt and I got a foo dot txt of course if I do it get status then I have one untracked file foo dot txt and in real life of course you might have things like the fact that maybe hello dot txt has been changed or some other file that was committed and pushed has been changed so you might have something modified you have something untracked you might have other files that have been deleted or moved who knows all kinds of crazy things happen in a get work tree especially after a few days of coding now you realize there's something very important back on the master branch that needs to be changed and that is not convenient right now because I have stuff in all kinds of different states and if I were to walk away from this now I could risk losing something either maybe I might have to restore some file that that I've deleted for for this system to work or maybe I've I've moved it and I had to move it back for my for my hot fix but but then what's going to happen so you can introduce a lot of confusion I mean of course I mean there there's a risk of merge conflicts anyway and at some point you just kind of have to get used to that and get comfortable with that and trust and get and just know that when there's a merge conflict you can fix it you can go in you can take the the version that you you want to keep and and resolve any conflict in theory that's not a deal that's largely that that is part of what git is designed to do so that shouldn't be too scary but this is so this is less about avoiding merge conflicts as it is about just walking away prematurely from a a git state that is influx that is in progress getting out of that just temporarily to do something elsewhere in a clean way okay so right now I know that I'm in the git branch called dead but I know that I want to be back in my first commit so I'm going to create a new work tree here and that's the command for that is git work tree add so that's git space work tree all one string there space add space dash b and I'll call this hot fix and then I need to give it the location so I'm going to do tilde slash demo slash let's do was this penguin I'm going to call this penguin dot tree and the place that I want to park my head at is the master branch so I type master at the end of that so the syntax is a little bit I think a little bit weird but git work tree add dash b and then like the the user or the human friendly name of this work tree of this workspace that you're about to create and in the actual location of the data on your file system which is a new location so and it should not be within your current git work tree that should be somewhere else so I'm just going back out to my demo folder making a new directory and it'll make the directory if it doesn't exist so penguin dot tree and then where you want the head to end up and in this case I don't have that many choices I've got either my master branch or I've got my dev branch but you can set it to to any number of things okay do that it confirms for me that there is now a location called slash home slash class who slash demo slash penguin identifier penguin dot tree head is now at 54 git bd 483 so guess what if I do get log I see that my first commit ever my only commit ever was 54 bd 483 so that's exactly where that has been reset to so that's good so now I can just go out to CD slash or CD tilde slash demo penguin dot tree and there's a hello dot txt no food dot txt and if I do a git status I'll see that everything is is fine I'm on branch hot fix nothing to commit working tree is clean I'm free to do whatever I need to do so what we'll do is we'll do an echo world at the end and I'll append that to hello dot txt then I'm going to commit that as hot fix and then oh I forgot to add it first of all so add and then and and get commit there we go and then I'll get push that get push origin now it wants me to set the upstream origin to hot fix so I'm going to do a git push dash dash set dash upstream origin hot fix so in other words I'm now pushing not just my fix but the branch upon which I have made the fix to the server and now I'm basically done with that work tree there are a couple of ways to deal with the work tree once you're finished with it you can first of all do what I just did push push your change you could also not push your change but tar up your your work tree so to do that you do a git space archive space dash dash format tar for instance dash output hot fix dot tar and then whatever branch you want to tar up in this case it would be hot fit or you can fetch the changes locally from a separate work tree so you could go back to penguin dot clone you could do a git fetch on tilde slash demo slash penguin dot tree and and just clone over the hot fix branch or or fetch rather the the branch and then you could merge it at your pushing it is is one way to do it just I guess it kind of depends on on what kind of permissions you have on the server but now I'm going to go back over to my to my main work tree and when once you're there you can do or from your main work tree actually probably from either one but you can do a git work tree space list and see what work trees you have in existence and because you made the work tree from within git git is aware of your work tree which is a quite quite nice feature that the hack of just going out and be going rogue and copying your your git clone that doesn't provide this sort of awareness you just kind of have to remember that the copy exists and that's not your main working branch and that the one that you actually care about is over here but this was important for that one feature that you had to do don't do that git work tree now you can do a git work tree list and see that they that you that you've got a copy of your work tree and where it exists when you move a work tree should you need to move a work tree you can do that by telling git work tree to move to move the the the the work tree the copy so for instance if for some reason I'll make a directory called slash till the slash demo slash hpr and let's say for once for whatever reason I want to I need to move my penguin dot tree work tree into into that folder so I would do git work tree move and that is the word move m ove I don't know maybe they've aliased it to mv I'm not sure I never tried but move penguin dot tree to till the slash demo slash hpr and now it's moved and if I do get work tree list I get still to work trees but now it knows where the penguin dot tree work tree is located it knows that it's been moved out of the demo folder into a subjectory called hpr in the demo fold so that's a kind of a nice feature you can also just get rid of it if you're done with it you can do git work tree remove penguin penguin dot tree and it gets rid of it and when I say that it gets rid of it I mean it gets rid of the data and it gets rid of the the entry in its list so if I do a git work tree list I've just got my penguin clone now and if I do an ls on slash till the slash demo slash hpr it's an empty directory now it's gone the data is gone now of course I've pushed that data to the server so it's still accessible to me and here I am hanging out on my dev branch I see that I do have a hot fixed branch that's cool and if I do a git fetch origin then now I've got all the changes and then I could get merge and see what happens I could get merge get merge what is it dev space hot fix it says it's going to fast forward hello dot txt it does that if I do a cat of hello dot txt I've now got hello and world in my text file but I've still got the the the the floating status of my of my of my work tree I've still got food dot txt is an untracked file and if I'd made changes elsewhere they would still be there if I'd moved files they would still have been moved so in other words I'm able to make changes outside of my workspace and then either apply them to the server for merging later or store them in a tar file for merging later or whatever I need to do in order for them to be available and then I can keep working in my current work tree bringing it to some kind of comfortable stopping place and then deal with all the merging back into master or or whatever my workflow is so git work tree is sort of a kind of a simple this it's it's almost an overly simple and rudimentary solution to I think what what does become a rather common problem I feel like like I've said feel like people have done the hack often enough that probably work tree got developed in recognition of that that's what it feels like to me I can't confirm that like probably could confirm that if I bother doing some research but um it doesn't seem that important to me point is that this feature exists and it is quite a nice feature because you can make your copies you can work in your copies you can be aware of your copies from within git and and it is stored to it is not just sort of I mean obviously git is aware of it so I mean that that means that it exists somewhere and the place that it exists is in your dot slash git I mean not dot slash your dot git folder uh in a sub directory called work trees and then if there were something like back when I did have a hot fix work tree it it would be in dot git work trees uh penguin dot tree or whatever in fact what we could do it right now get work tree add dash b uh example and then we'll make it out here example penguin dot example and we'll reset it or we'll send it back to the master branch again now if I do an ls on my did dot git directory in work trees I see a folder called penguin example by looking penguin example there's a whole little sort of a sub tree within that uh like a sub git directory within that within that work tree that will track uh the git directory the head the logs all kinds of stuff so it's it's pretty pretty interesting um to to witness and in that way if you need access to that for some reason within a git hook or something like that you've got it so it it's a very formalized way of doing something that that that feels like it shouldn't even be part of git it feels very much like cheating because you're abandoning sort of a branch and you're you're you're essentially just creating a new trunk a new master branch that that lives parallel to your actual master branch but it's fine it works just as I say if you're if you're changing a bunch of stuff get ready for merge conflicts but that's kind of part of life when you're editing source code from lots of different places I mean that's going to happen and obviously it depends on your use case too if if you're if your features and your fixes are truly truly separate maybe they'll never collide work tree is still useful because at least it gets you into a clear mental space a clear workspace where you have no danger of accidentally moving some file that wasn't supposed to be moved or removing a file that wasn't supposed to be removed and so on so that is git work tree I hope that's been useful to you I've I've enjoyed using it the couple of times that I've used it so far hopefully you will too thank you for listening I'll talk to you next time you've been listening to hecka public radio at hecka public radio dot org we are a community podcast network that release the shows every weekday Monday through Friday today's show like all our shows was contributed by an hbr listener like yourself if you ever thought of recording a podcast and click on our contribute link to find out how easy it really is hecka public radio was found by the digital dog pound and the infonomican computer club and it's part of the binary revolution at binrev.com if you have comments on today's show please email the host directly leave a comment on the website or record a follow up episode yourself unless otherwise status today's show is released on the creative comments attribution share a like three dot org license