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
