This week weāre joined by Annie Sexton, UX Engineer at Render, to talk about her blog post titled Git Organized: A Better Git Flow that made the internet explode when she suggested using reset instead of rebase for a better git flow. On this show we talk about the git flow she suggests and why, how this flow works for her when sheās hacking on the Render codebase (and when she uses it), the good and the bad of Git, and we also talked about the cognitive load of Git commits as you work.
Featuring
Sponsors
Sentry ā Working code means happy customers. Thatās exactly why teams choose Sentry. From error tracking to performance monitoring, Sentry helps teams see what actually matters, resolve problems quicker, and learn continuously about their applications - from the frontend to the backend. Use the code CHANGELOG and get the team plan free for three months.
InfluxData ā InfluxDB empowers developers to build IoT, analytics, and monitoring software. Itās purpose-built to handle massive volumes and countless sources of time-stamped data produced by sensors, applications, and infrastructure. Learn about the wide range of use cases of InfluxDB at influxdata.com/changelog
FireHydrant ā The reliability platform for every developer. Incidents impact everyone, not just SREs. FireHydrant gives teams the tools to maintain service catalogs, respond to incidents, communicate through status pages, and learn with retrospectives. Try FireHydrant free for 14 days at firehydrant.io
MongoDB ā An integrated suite of cloud database and services ā They have a FREE forever tier, so you can prove to yourself and to your team that they have everything you need. Check it out today at mongodb.com/changelog
Notes & Links
Transcript
Play the audio to listen along while you enjoy the transcript. š§
So we are joined by Annie Sexton, a UX engineer at Render and the author of a very interesting blog post recently, āGit Organized: A Better Git Flow.ā Annie, thanks for coming on the show.
Yeah, thanks for having me.
So a better Git flow⦠I think we all have an idea about how to flow with our Git processes⦠And some could be better or worse, or it works for me, but it may not work for you⦠Itās an interesting topic of conversation. But really, it comes down to communicating and collaborating. Thereās lots of things, like āWho am I serving here? Who is this for? How do I do it? How do we do it together? How do we get on the same page?ā Iām curious how you came ā weāre gonna talk about the nitty-gritty details of this particular process and how it compares to other ways that you can Git⦠But Iām curious how you came to this process, what your process was to land here and think āIāve gotta write about this.ā
Yeah, well it really started with a co-worker of mine making some comments about some PRs that I was making⦠And he offered some advice about doing Git differently. And up until that point, I really hadnāt had a lot of coaching around Git, aside from just the basics⦠And it made me realize that there was a lot of things that I didnāt understand about Git, and it was a lot less scary than I expected it to be⦠And it opened up this great conversation where he introduced me to his method of cleaning up his commits; although our techniques differ a little bit, he tends to rely more on using rebase interactive, rather than just like a full-on reset⦠But through teaching me all these elements of Git, it introduced me to this new way of approaching Git flow that is way less stressful, and also results in a much cleaner Git history.
[04:26] So we do wanna talk about the process⦠I wanna go up a level for a second, because I think thereās an interesting meta-game involved, with regards to tools and processes and software in general, which is opinionated versus unopinionated. Itās interesting that Git is kind of unopinionated about how you use it, considering the original authorship⦠And sometimes there are other ecosystems or tools that are like, āHey, there is one way to do itā or āThere is one best way to do it.ā Go comes to mind, Python, around their PEPs, and like āThis is how you write idiomatic Python.ā And then thereās the Perl and the Ruby TMTOWTDI idea of like there is more than one way to do it, and we like that. Iām curious of your thoughts on not just Git, because you can use Git in many different ways; in fact, I think the Linux kernel team - they still email patches around to each other, and stuffā¦
Yeah.
ā¦to a certain degree. But do you like the flexibility it provides? If there was only one way to use Git, we wouldnāt have to even have this conversation, or your blog posts, where like āThis is just how you do it, is this way.ā But instead, thereās flexibility, which some people like, but also now we have to decide how to use it. Iām just curious what you think about that trade-off.
Yeah, Iāve thought a lot about this, because ā Iām gonna use a comparison. So Iām a full-stack developer, really, but the two frameworks that I am most used to are React and then Rails. And those are kind of two ends of the spectrum as far as opinionated stuff goes, like how much structure do you get right out of the box. So with Rails, you do things the Rails way. Ruby - yes, thereās lots of flexibility, but with Rails thereās a way you do things; you have the MVC flow, and thatās what you do. Whereas with React, I would say you have pretty simple concepts, and as a result, many React apps - thereās so many different ways of structuring them. And it can be quite intimidating when youāre joining a new team, and being introduced to a new React app that youāre not familiar with, because everyone can do it differently. So you get more control with that.
Once youāre actually more familiar with the codebase and youāre the one in the driverās seat making these decisions, then I think that flexibility can be really empowering⦠But sometimes it can be quite overwhelming, because if thereās not a precedent already set, then that can be a challenging task.
Luckily, I do think that Git is old enough that many, many people, many veterans of Git have tested it a lot of different ways, tried it different ways, and have some really valuable workflows that people can rely on⦠But itās still flexible enough that people can do it other ways if they want to. So I think ā I tend to like to know how things work under the hood. I donāt love when things just sort of magically work, and I think thatās actually what made Git so intimidating for the longest time, is because there was just a lot under the hood that I didnāt understand⦠And thatās not to say that I am now a Git expert by any stretch, but I know a lot more than I did then.
I think when youāre able to ā when youāre just getting starting, having some basic, obviously knowledge about Git, but also practices that other people have tried and tested, can really help minimize the need to get super into the weeds⦠But then when you start to run into problems and you gain more experience with it, having that extra knowledge about how things work behind the scenes is really valuable.
[08:11] I will say that Git can be very, very intimidating. I was once on a team ā this is back in the day, I was still remote, too⦠It was Change Healthcare, the company I was working with; I was a contractor, and I was definitely not an engineer. I was definitely designer UX. Not to say that those folks donāt get deep into Git, but ā I committed code, but I was mostly a frontender. This is probably 2007-2008⦠Or 2010 maybe, I donāt know. I donāt know the exact year, but it was early Git days. So even my knowledge around Git was still young then. I had to rebase often, Iām like āOh my gosh, am I diverging somehow from the master branch? Oh my gosh, where am I at?ā and Iād have to call in error support⦠And this was before Zoom. I think we actually did remote meetings with like GoToMeeting, or something like that, and I had to screenshare⦠Thatās how back in the day this was.
And I would just get into situations where Iām like āI just wanna commit my code. I just wanna get my code into the repo and move along with my dayā, because all my cognitive load and all my brain was on this Git flow, versus my actual job, which was marking up the form, making sure it worked, making sure the markup was right and the styles are right, and nothing would break on mobile, and different stuff like that. I was totally outside of my jobās perspective, just trying to commit code. And itās such an intimidating thing when youāre in that position, when youāre like āYou know what - I just wanna get my code committed.ā
I think unless youāre Linus, or maybe you predate Git and you were using CVS, or using SVN, and then you decided to switch to Git - unless youāre one of those elder statespeople of our community, pretty much all of us have to use Git before weāre gonna understand Git. Nobody has a four-year degree in Git and then they start coding, right? Youāre coding, and then youāre like āI need to share this. I just wanna get it out there.ā So almost all of us start just by memorizing a handful of things that you can do, and having no idea how it works.
Yeah.
And just like āHereās this incantationā, and then when this messes up⦠And the design, the API of the command line tool - somewhat obtuse. Itās gotten better over the years. It used to be very unintuitive how you would for instance delete a remote branch I still donāt know why⦠Thereās a reason for that, Iām sure. But yeah, as you use it, first you start off just memorizing the commands, then you start emulating people who have been around longer, and then you start to kind of understand how it works, and it does become less intimidating, but you still arenāt sure if youāre using it right.
Right.
Iāve been using it since it came out⦠Actually, SVN was more intimidating to me than Git was⦠Because I kind of learned Git as I started programming. I just had the right timing in my career, and I had to do some SVN stuff, because I was making WordPress plugins, and Iām like, āThis thing is intimidatingā¦ā But Iāve had enough experience with Git, probably ā however many years itās been publicly available⦠And I still question whether Iām using it right.
Totally. Iām always in the docs, man⦠How do I revert that, again? Whatās the syntax to do it? It always seems to jump around and I have to consult the docs for Git constantly.
Absolutely.
So the standard, typical ā now that GitHub is established and most of us are doing PRs, or if youāre on GitLab youāre doing MRs (merge requests), kind of a standard flow for a feature or even bug production⦠Bug production - thatās what most of us do on accident. [laughter] Itās a feature branch, but Iāve got bugs alongside. I remember I made an image one time of ā it was a meme I was trying to get going⦠It was like a ship that was shipping a ship⦠Not a cargo ship, but an airplane. Have you ever seen those ā theyāre carrying a little one on top maybe it was a rocket on top, or somethingā¦
Oh, yeah.
[12:05] And it was like ā the big one that was flying was like the feature that youāre shipping, and then the little one along for the ride was the bug that youāre shipping alongside, just because, like, itās there. So yeah, we have bug production⦠But the typical flow is Iām on my main branch, Iām ready to start my feature, I create a feature branch, I check it out, so now Iām there⦠And I go about, I do some things, I make a commit, I describe what I did, I do some more things, I make a commit, I describe what I did. Maybe I have two of those, and then I get back on the main⦠Or maybe I have 27, because itās been a long-standing deal, and maybe Iāve rebased it along the way⦠Who knows what Iāve done. But Iāve had these commits, commits, commits, and then itās time for a pull request, and I merge back onto the main branch. And thatās pretty standard. There are other ways of doing it, and people that donāt do it that way, but thatās what youāre typically gonna see out there.
So when you talk about this better Git flow that you describe in your post, Annie, itās better than that, is what youāre saying. So letās start with saying, that flow right there - what are some of its drawbacks? Why is it not always ideal?
Well, one of the issues is that itās much riskier to roll back commits, especially if your commits arenāt as tidy as they could be⦠You know, when you have that sneaky little bug thatās piggybacking on top of another commit that you didnāt realize was there⦠When you roll things back, then all of a sudden you might be also breaking other things, that if your Git commits arenāt as self-contained as they ought to be, that can be really problematic, because you can roll things back, and maybe you fix the bug, but then you introduce a new issue, because something else was depending on the code that you just committed. So that can be problematic.
I actually think that more importantly what makes this flow better is for PRs, the actual review process. For most of my career, Iāve hated doing reviews on PRs, because itās code that somebody else wrote and I donāt understand exactly how everything is connected⦠Especially if thereās a ton of files, and they donāt give you a very good description of whatās actually happening, their commits arenāt actually broken up into logical steps, because they just committed to save the work. So some things are sort of half finished between commits, and that can be kind of overwhelming to review. Itās possible, obviously, but itās not the nicest process. So what I like about this Git flow is that it introduces a way to keep your Git commits really clean, so that they are easy to revert and easy to review.
So in like a pull request then with this kind of flow, would you - and Jerod, in our case⦠Iām looking at PR #400, āMove assets to S3ā, the most recent one⦠So in this case ā and you may not have this as a reference, but itās just a pull request and you can kind of see the atomic commits over time from Jerod and Gerhard essentially committing code to our repository that moves our assets from a local disk to S3 as part of the process. So in this case, would you then just ā with all those atomic commits over time, by going the reset route, would those be gone?
Well, hold on, she hasnāt described the new way yet.
Oh, okay. Sorry. Iām jumping ahead. My bad.
[laughs]
So those are the two things⦠Reverting is problematic because you might actually revert something that you didnāt think you were going to, because the commits are messy, and over time ā especially the longer you do a thing, you end up doing things that arenāt core to that feature; theyāre just tangential. And then the code review is the same problem that manifests in a different way, which is like thereās just more things in there. And thatās probably the way that that pull request youāre looking at, Adam, goes.
Yeah.
[16:07] But now describe this other way, so at least weāll have both methods on the table. Then we can discuss the differences. So how do you propose, or how are you doing it these days, that you learned from Dan?
Sure. So what I do these days is when I am developing a feature, fixing a bug, Git is really not something Iām thinking about too often. The first stage is just fix the thing, make the feature; along the way I still wanna save my work, obviously, and push up to a feature branch, but I tend to just always commit things with a WIP (work in progress) message, and thatās it. I donāt try and describe what I was doing, because all of that I intend to just completely rewrite.
So build the feature, do the thing, and then when youāre ready ā and I actually didnāt list this in the article, but⦠So the next step would be to do a reset to origin main, or origin master. I tend to do a git fetch and then I rebase on top of master⦠Just a plain rebase, not interactive, just so I know that I have the most up to date version of code that Iām building off of, and then from there, I will reset origin master.
Now, with reset, without any parameters aside from the branch that youāre resetting from, it doesnāt change your working tree, so all of your files stay intact. Reset was always really intimidating to me⦠I think I was coached back in the day that things are irreversible if you use reset, and itās super-dangerous⦠And itās not. Itās really not. Thereās actually very few things in Git that you canāt undo.
Yeah, itās almost always in there.
Yeah, itās in there. Because itās an append-only database, soā¦
Right.
So thatās a huge relief. So I do want my work in progress commits, then I do a reset, which basically makes it look like youāve just made all of your changes all in one go, without ever making a single commit. And then, you can go through and pick out which files seem to go together the best, and just group your changes into logical commits. And especially if you have an editor that makes this a lot easier, I think that ā I use VS Code and itās quite easy to just click through the files that Iāve changed, see the changes and verify that they should be grouped together, and then I make individual commits saying exactly what I did.
So itās as if I was a perfect person and I knew exactly what I was gonna build, every single line, and I committed them one after the other, as if I was like a robot, or something⦠[laughter] So itās quite nice, actually⦠The end result is a very, very tidy and well-organized Git history. But what I love about this is that theyāre completely separate tasks. When Iām in development mode, Iām in development mode, and Iām just problem-solving, and I donāt have to switch mentally to thinking about Git as well, because all of that gets taken care of later. So thatās personally why I really prefer this reset method.
Yeah. So this is where Richard Hipp, whoās the author of Fossil, would say youāre basically lying to everybody. Youāre going through and youāre tidying up history that wasnāt there, and youāre rewriting history⦠Because in Fossil, every commit that you commit is immediately shared over the network with everybody else. Thereās no hiding anything. Now, you can go back and change things and append new things that fix other things. But he/they believe in āLet it all out thereā, which - Iām more on your side; I like to prepare myself. Iām like, āIām gonna get cleaned up before I go to the restaurant.ā
So thatās very interesting. That now comes into the conversation that Adam was getting into with collaboration, because you have this feature branch along the way⦠And this is pushed remote, I assume. Youāre not keeping that on your laptop, right? No, you arenāt, or yes, you arenāt? I asked it in a weird way.
Oh, I am pushing it to a remote branch.
Youāre sharing. Okay. I asked in a double-negative fashionā¦
Sorry⦠[laughs]
[20:19] No, Iām sorry. So it is shared⦠And then when it comes time to open a PR then, are you force-pushing ā like, is that branch only there so that it exists in more than one place, or is there collaboration along the way during these WIP commits, or are they just for you?
The WIP commits are just for me. When I push up to the feature branch, sometimes I do have ā but I am pretty comfortable doing a forced push, because thatās usually when I have gone through and made my cleaner commits afterwards. So thereās no harm in doing that way.
āforce is so scaryā¦
Iāve gotten a lot less intimidated by it since doing it this way, because I know exactly what Iām changingā¦
Sure.
It comes down to knowing how Git works, and knowing that and being comfortable. Because if you have a scalpel and you donāt know itās sharp, you can cut somebody, right? Youāre still holding the same object. It could be a dull scalpal it could be a sharp one but if you donāt know how sharp it is, then you can still do some damage.
Right.
Then if youāre using a forced push in this case ā so essentially this forces a rewrite to the remote repository, and that forces everybody else who tracks that repository to adhere to whatever you⦠Like, you kind of revert some things. Does it only happen in the branch then?
Yeah, it only happens in the branch. Itās just the branch. Thatās why itās pretty harmless.
So if youāre only doing that to a branch, itās different then⦠Because if youāre doing a āforce on master or mainā¦
No, I would not do that⦠[laughs]
Right, right, right.
Somebodyās upset.
Yeah, a lot of people are upset. So āforce is there for a reason⦠So as long as we know why youāre wielding that scalpel, and youāre doing it to precisely do what you want to do, itās totally fine. And in the case of a remote branch thatās there merely for you to not have a single point of failure - itās there so that you can work on it elsewhere or whatever, but itās still just Annieās code, sheās working on this feature, and if you go and look at it, youāre gonna see a bunch of WIP commits that are just like āOkayā¦ā Youāre not going to collaborate on that.
But once you get to the point where youāve done all of that, youāve done all your reset - which by the way, I learned about this use of reset from this post, so thank you. Like I said, Iāve been using Git for many years⦠But Iāve only ever used Git reset to unstage some stuff. I canāt remember what I used it for. But this is like all the commits that you did between when you forked ā not forked; when you branched, and whatās there now, assuming youāve rebased, so you have the latest⦠All those commits ādisappearā and everything goes on stage, but all your changes are right there.
Right.
So itās like, your code is still changed, but your history is now āgoneā, itās hidden, and you can recommit it logically, and itās a beautiful thing. You basically cleaned up your room, and got dressed, and now youāre ready for the world to see your stuff.
Right. And I would say that ā because Iāve heard some people complain that āWell, that sort of defeats the purpose of having those point in time commits to track exactly actually what happened.ā And I would say āWell, whatās the point of having those early timestamps?ā Because they donāt actually serve your teammates. What actually helps your teammates understand and navigate the changes that were made is when they are actually properly organized. So the fact that you sort of like āerasedā (Iām using quotation marks) those old commitsā¦
For Richardās sake, yes. Erasing the history.
I was also doing air quotes, and I forgot to say it out loud, because youāre watching me, butā¦
Right. [laughs] You know, the fact that you āerasedā those old commits doesnāt actually change how other people will interact with the code. In fact, it makes it a lot easier. Because the fact that you did at a certain point in time I would argue doesnāt really matter as much as the changes that you actually made, and then the order that they were committed. The order is really what matters. And so when you know that, and as long as youāre committing them in an appropriate order, where youāre not leaving the code in a broken state, then youāre still keeping the repository in a clean state thatās easy to review, and easy to manage for other teammates as well.
So Annie, Iāve mentioned somewhat prematurely this pull request that we have out there, pull request #400 on our main repository. So if you go to GitHub user thechangelog/changelog.com (thatās the repo), and then pull request #400 on it, you can track along with that. Weāll also have a link in the show notes. But this is a pull request recently ā and hey, by the way, we talked about this on Ship It #40, our Kaizen episode. If you havenāt listened to Ship It yet, thatās a great episode to begin at. We talk about the behind-the-scenes here at Changelog and how we actually improve our infrastructure and platform, and this is part of that.
So we talked about moving our assets to S3, thatās pull request #400⦠And what this pull request has is an opening commit and comment from Jerod saying kind of what weāre doing with this pull request, stating the case. And then along the way you see ā and because I know Gerhard and Jerod did not use your Git flow, I know that these are atomic commits in the, I guess, normal fashion Jerod had mentioned in part one. So what you see here is you see a collaboration between Gerhard adding commits that add Crossplane features to our Linode provider, and then all down the line; you see different comments and commits, you see Jerodās atomic commits on dropping Waffle to replace Ark, and a bunch of other stuff that essentially make us move our local assets from a disk at Linode to S3.
And what Iām curious of, since I know that it nulls your flow, and we talk about collaboration with the pull requests, because in a lot of cases you do have a lot of collaboration. Sometimes theyāre single individuals committing and itās just a review; so it might be you committing a feature and your teammates coming on, and you wanna organize things so itās easier for them to do the review, because thatās never fun to do, organize a reviewā¦
So how does collaboration happen? So if this is an example of non-Annie workflow, if we can call it that, letās just say⦠If we know itās not that, how do we then collaborate in your style? How does it change?
So I think that the reset method that I outlined could technically work for this. It might be a little trickier, because as Iāve said before, when youāre cleaning things up, youāre doing that forced push to clean up your feature branch. And I think that can get tricky when youāre collaborating with other people. Now, the way that I have collaborated with others is we just each keep our own branches and they exist on GitHub as completely separate branches, and we might reference our branches and pull requests in another pull request, and so we have a conversation there⦠But I think that actually maybe a rebase interactive might make it a little easier. Itās still the same sort of principle, where you clean up your commits afterwards, but doing a rebase interactive might make it a little bit easier when youāre ā because it sounds like you guys are working on the same branch, is that right? Or two people were working on the same branch?
Yes, so let me describe how this went down. So youāll notice, for people who are paying close attention and actually click through to the URL, that if you look at the commit list, which thereās 31 commits on this, the first commit is on January 16th, 2022, and if you look at when I opened the pull request, I opened it on November 29th, 2021. So thereās definitely some rewriting going on at some point anywaysā¦
Yeahā¦
I think you can see how itās like Jerod authored and Gerhard committed⦠So somehow Gerhard did something that changed the timestamps around anyways⦠But the way that I generally work - and this is a feature that I put in 90% of the work, opened up the pull request, and the rest of the work was like āNow we need to kind of reconfigure and change some environment variables and some part of our infrastructure deployment stuff before we merge this, so that itāll go out smoothly.ā
[31:51] So I did the feature, and then Gerhard came in later and kind of did the end things⦠And if you scroll to the bottom of the commit list youāll see itās pretty much Gerhard by himself doing some stuff. And Iām not actually sure how you do those Jerod Santo authored and Gerhard committed⦠Itās like a sign-off or something you can do inside Git, and somehow GitHub is doing a good job of describing that⦠But the way I work is actually somewhat similar to the way that youāre describing, until I get the pull request open. And then I just kind of go chronological from there. Thatās where I was confused with this process. Once youāve shared, and I assume thereās gonna be follow-up commits based on code review, maybe you have a teammate whoās like āHey, Iāll hop in and do somethingā¦ā And I guess once you do your reset and your rewrite and you get it all logically awesome, and submit it for code review - from that point on, do you just do commits naturally and push them to the branch? Or are you still going to do a reset at the very end when itās time to merge?
Um, it depends on what changes Iām making. If itās a āHm, we really need to rethink how weāre designing this componentā or if itās a simple āOops, thereās a typo.ā If thereās a typo, letās do a Git commit amend, honestlyā¦
So youāre force-pushing all the time.
I mean, if Iām the only one making the changes and no one else is making commits to this branch, I donāt think it matters that much. But if other people are making commits, thatās a little bit different.
Right. If you know thereās collaboration, you canāt do forced, because that really would ruin their branch. They would be divergent to the branch at that point because it wouldnāt match up.
Exactly. I mean, you could still do it; you would just have to ā
It would work. It just causes more pain for them.
It does. So itās a matter of how much do you need to rewrite, how much are you collaborating, how much is the work shared between two people? Because if somebody else ā if thereās quite a bit of work that is shared, then youāll probably wanna do fewer forces; and if you do forced pushes, you have to stay in communication with each other. So itās a matter of ā you know, do you work in different timezones, or itās the same time of day, youāre on Slack at the same time, so you can just be like āHey, by the way, I did a forced push. Youāre gonna have to do this.ā
So I think it all sort of depends on how closely are you communicating with your collaborators; is it super-asynchronous communication? If so, then you might wanna be a little more considerate about the commits that you make⦠Because youāre right, force-pushing can be quite extreme when somebody else is also touching that same branch. So it really depends on how youāre working together and what theyāre willing to do.
Sometimes a force is just absolutely necessary and you can just let them know⦠But I think a rebase would be a good way of more delicately handling these. It does require a little more tweaking and knowing exactly what to do when youāre doing an interactive rebase, to say like āFix up this, squash this, rearrange these things.ā But even then, I think that can still ā I donāt think that would result in a forced push, but⦠But that can help, I would say.
So a lot of people have brought up āYou can use rebasing as an alternativeā, and I think this is actually a really good use case for when you might actually wanna use rebasing instead of like a full reset.
Letās play a little game then⦠Letās imagine weāre a collaborator with Annie on a pull request, and for some reason she has to do a forced push. What then ā and Jerod, Iāll say what I think, and weāll see whoās Git flow is better. Yours may be better. Letās assume weāre the collaborator. Weāre on the same branch and are collaborating, and she has to do a forced push. And she messages me in Slack and she says āHey Adam, sorry, I did a forced push.ā I think what I would do then is if I had some ā
Throw a temper tantrumā¦
[laughs]
[35:49] Well, I might be upset, but if you know your Git, then maybe there is no tantrum. Itās just more like a blip of cognitive shift to get my Git right, and then get back to my ā Iām gonna just keep saying Git⦠Iām gonna get my Git stuff back in order.
But I think what I would do then is if Iāve got some ā letās just say Iāve got my own WIPs locally⦠If I know sheās got a forced out there and Iāve gotta essentially consume what sheās got because Iām out of sync, I would probably maybe keep my work in progress commits⦠I essentially wanna rebase her branch. I wanna have my changes in place; probably commit all my changes, even WIPs or actual messages, get all my stuff staged actually in my commit log, and then I wanna rebase that branch back locally, all my changes back onto hers. Thatās essentially how you deal with a forced, right?
Yeah.
Because otherwise, if I didnāt do that, Git would yell when Iād try to push to that branch and say ā I donāt even know what it would say. Itād probably say Iām out of sync, or Iām ahead, or Iām behind, or something like that, from the head of the branch. Is that how you would do it, Jerod? Did I win?
Likely. How do you win if weāre both gonna do the same thing?
Well, is that the right way? Since you could probably do it different ways, how would you do it?
Well, another way you could do it is basically unstage your WIPs and stash them, and pull, and then unstash. I do that a lot⦠Iāll just stash, pull, or rebase if you have to, and then unstash⦠Because if those are WIPs anyways, you donāt care about the history of those commits.
Right, right. You could do the reset back to the SHA using Annieās method, back to a known SHA prior to Annieās current head on the branch. Then you could make one gigantic commit of that. Maybe a massive WIP versus many WIPs, right?
Sure.
Do another rebase off of her branch; youāve got that. Or you could do the stash. See, thatās the thing with Git - if you know the different tools and how they work, you can get more comfortable. Thatās why I wanted to play this little game, because thereās like probably 3-4 different ways, and none of them are right. They all work, they all get you back to work. Itās a matter of which tool youāre most comfortable with, which can you do quickly, so that Annieās interruption cognitively doesnāt shift you away from your work.
Right, exactly. And this is actually ā I think this brings up a question of āWhatās the best way to collaborate at all?ā Is it always that youāre on the same branch? Because in situations like this, it depends on if youāre touching the same files, then it can be a little bit tricky⦠But if youāre not, I think that thereās always a benefit in just having completely separate branches.
Iāve never done that before, so this is a new thought process to me. I donāt see why it wouldnāt be good, I just had never done it that way.
When youāre touching the same files it can be tricky, and I would probably reevaluate whoās doing whatā¦
Your lifeā¦
[laughs] Try to reevaluate if this is better left to one person, or if it really needs to be collaborated on by two people⦠But if youāre touching relatively different files, then just creating different branches and merging them in separately - that also saves you a lot of the headache of āWhat happens if I force-push?ā I know a lot of people have opinions about not force-pushing, and theyāre welcome to those opinions.
My opinion is once you have more than one person pushing to the same branch, you should be done with your force-pushing.
Right, exactly.
Just because itās causing them more work if youāre doing that. I have no problem with it if youāre on your own branch.
Yeah, same with me. I mean, Iāll forced push all day long to my own repos, because there aināt anybody there to get upset. [laughs]
Thatās right. Pushing nobody around.
Thatās right.
So most of the collaboration that I do on small teams - our teams are like one, two, sometimes three people. And I know thereās people that work on larger teams and collaboration is harder amongst more people, so Iām not sure how those processes scale⦠But most of what we do is tag team. So itās kind of like I do some commits, the pull request is open or something, and we talk about it, and then itās kind of like ātag your itā, and so now here comes Cody is another collaborator of ours. He did a lot of the UI of things that I would build the backend for, to create a full-stack developer between the two of us⦠And itās like, āHey, your turn. Let me know when youāre done doing some stuff.ā And then he works on that same branch for a while, and then he says āPassing it back to youā, and then I pull, and workā¦
[40:22] Thatās how a lot of my collaboration has been, is kind of just like pass the baton, more so than like weāre both working simultaneously on the same feature. So I think in that way, one branch makes a lot of sense. But if youāre simultaneously collaborating on a feature, maybe different files, but youāre not passing the feature back and forth - I could see where two branches, or N branches for that many collaborators is a better flow.
So tell us about the teams that you work on and how many collaborators you usually have, and whatās your setup usually like.
Sure. So at Render we have a lot of people working on many of the different repos, and we tend to have one person per branch. I donāt know that thereās many people who have multiple people working on the same branch. In fact, most of the time we tend to preface our branches with our names, slash whatever feature weāre working on.
Gotcha.
And in that regard, itās quite easy to keep our work separate, and thereās no real mix-up. And the collaboration that we do happens more in the form of pair programming and the conversations that actually happen in the PRs. So thatās what collaboration looks like. And if itās a bigger feature that canāt be completed in a single branch, then ā and Iām not actually sure if we do this, but I just thought this might be an option⦠You can have sort of like a long-running feature branch that you then diverge from individually with. So youāve got the main feature branch, and then ā
Like a pseudo-main almost.
Right, exactly. Essentially staging, but feature-specific. So that would be another way of having people have their own branches they can manage, that they then have people review. And then you merge those into your main feature branch, if that makes sense. And that eventually that can get merged into main as well.
So that has been what collaboration has looked like in the past for me. I actually donāt have much experience working directly on the same branch. Itās usually been you have your own feature branch, that only touch, and if somebody else is messing with it, itās because theyāre helping me solve a bug that I canāt crack. And then when we figure it out, then maybe they make a commit, or they just tell me what they did and then I write it.
Iām curious which is more common. So if youāre listening and youāre like āOur teams work Render style, Annie style, which is each person has their own named feature branch named after themselves, and collaborate that way, or more like the way Iāve described, where itās tag-teaming the same branch, and passing it back and forth or collaborating that way.ā Let us know in the comments or hit us up on Twitter and just send us a note, what style do you do. Because like I said, thereās more than one way to do it, and this is a way that I actually havenāt heard anybody elucidate in the way that you have. Apparently, totally common at Render; maybe itās totally common at a lot of shops, and itās just that we donāt talk about these things all that often. So yeah, thatās pretty cool.
Back to the flexibility of Git though - I think thatās what makes it so cool, that it is so flexible⦠Back to your example, Annie, between React and Rails. You know, thereās just so much you could do with it, and so I think thatās why itās such a good fit and why itās actually lasted so long. Like, why it won and why itās lasted, despite reset seeming scary because of what it actually names, or the way you would delete a branch to a remote repository by pushing, and despite the odd API sometimes with Git, and some of the scary innards, itās so flexible. It lets you and your team work the way you want, other teams work the way they want. Itās really about leveraging its tooling inside of Git to work the way you need to for a team to collaborate in the way that it actually works out on GitHub itself.
Totally. And I would say that one of the benefits of having a lot of different ways to achieve the same objective in Git is that it also means that if you screw up, thereās a lot of different ways of fixing it. And thatās really nice. So thereās a huge relief when you start to learn more about Git, and find that itās really not as scary⦠It definitely can seem scary, but the complexity is really beneficial when you realize that a lot of these things are salvageable as long as you know how or you have somebody who can help you.
So Annie, in the pre-call we talked about your Twitter bio, and I will reveal some things about you to our audience that may not know you yet, and will know you after this show, and may go to your Twitter bio and follow you⦠One of the things you say is React.js; thatās the first thing, and then you say āADHD brain, lover of neuroscience.ā And you obviously put the brain emoji there, so thatās beautiful⦠And then UX engineer at Render, previously at Heroku. āShe/herā, your pronouns, some Japanese I canāt read, but you can⦠And then opinions are your own, blah-blah-blah; and thatās actually what it says, āblah-blah-blah.ā
So I wanna bring the neuroscience in there, because I think one outlier here that we havenāt really talked about, that may not even have made it into your post, that I just looked to see if cognitive was mentioned, is the load that thinking about your commits as you make them does to a creatorās brain, whether youāre a frontend designer, or a full-stacker, or a backender, or API - it doesnāt matter. If youāre using Git, which you probably are - weāve demonstrated that by this conversation - youāre thinking in commits. Youāre thinking in code, but youāre thinking in commits if youāre committing back to a repository, whether itās yourself or other collaborators. How does the cognitive load tie into this ā and maybe why even call it a better workflow, a better Git flow?
Sure. And I would have a disclaimer - I would just say that itās better than the one that Iāve outlined earlier. Not that itās better than everyoneās Git flow; just the simple one that I outlined in the post.
Right.
But yeah, there is a good amount of mental shifting that is required, that I think many people sort of take for granted, that happens when youāre both developing a feature and also thinking about āWait, should this be its own commit right now?ā And that ability to pause and shift your focus and think about something else requires a lot of working memory, your short-term memory, and a lot of executive functioning, which if you have something like ADHD or you have another disorder that deals with executive dysfunction, then that might be a little bit difficult. And I do not speak for every neurodivergent person, but I have just found for me that that is a moment when itās advantageous to let myself just hyper-focus on writing my code first, and then worrying about how to organize that in Git later. Because that mental shifting is not something that Iām great at; itās something that I quite struggle with due to my personal brain chemistry, and as a result, I think itās great that Iām able to use this other flow that really works a lot better for my brain. And I think other people might not want to do it this way, because their brain is a little bit different. And in fact, many people responded to this post bringing up rebasing as an alternative.
Rebasing is a really great option, weāve talked about it before⦠And I think that rebasing can actually be faster than the reset method that Iāve mentioned, as long as some of your commits are able to be left relatively intact. So if you have to ā the thing is, when Iām writing code, itās really difficult for me to also keep in my whether or not I should be committing at the same time. I tend to just commit just to save my work along the way, and then organize things later. But if youāre able to do that little mental shift easily, and itās something you are quite practiced at and it comes naturally for you, then itās a great tool. Because the more commits you can just leave intact, the easier itās gonna be to clean up later, obviously. So thatās where rebasing interactively could be a great option. But I find that for the effort that itās worth for me, in the moment, during development, itās quite disruptive. So taking this approach is a lot more manageable for a brain like mine.
[52:14] Can I define executive function for us, so that way we have our audience caught up on some of the neuroscience things around it?
Yes, sure.
So executive function - thanks to understood.org for making this definition right there when you google āexecutive functionā, so thank you to this⦠This is not me bringing this out of my own memory, Iām leveraging the internet. So here we go. Executive function is a set of mental skills that include working memory, flexible thinking, and self-control.
Another post goes into deeper details, which is the seven executive functions. They include proficiency in adaptable thinking, planning, self-monitoring, self-control, working memory, time management, and organization. And as any creative, as youāre thinking, these different executive functions are constantly being taxed. You may be thinking āIām hungryā, so thatās self-control on like āDo you want to eat?ā Self-monitoring. āAm I actually hungry?ā Time management, āIs it time to eat?ā All these different things that are monitors as youāre just doing life. So these things get taxed by anybody.
So from your perspective then, what youāre saying is when you work itās just easier for you to sort of like blaze through things without taking that time to have to stop. It keeps you in flow for you, and you can just ā maybe you have an alias where itās like āWIPā and you move along. I donāt know. But whatever it is, your pauses are less ā maybe theyāre just as frequent, but theyāre not that long. So your time between creative, Git, commit, and then back to creative again is minimized.
Exactly. And you know, executive functioning ā the main thing that I find difficult in switching between thinking about development versus my commits is that transitioning skill. That is something that if you have ADHD, itās something that we tend to struggle with. Not with everything⦠So the ways in which your executive function impairments show up for everyone with ADHD is quite different. And ADHD is not the only disorder where people struggle with this. Itās just the one that Iām the most familiar with. But that ability to transition is a skill thatās managed in the prefrontal cortex, itās all part of your executive function skills, it relies on dopamine and norepinephrine to be able to shift that way. And if you are deficient in those abilities, then it can be quite difficult. So itās really, really great to find different ways of working with your brain, rather than expecting it to do ā work in ways that it just wasnāt really built naturally for that.
So do your WIP commits literally just say āWork in Progressā? Or do you also ā I do this locally as well, but Iāll kind of leave myself breadcrumbs, to a certain degree. I actually do it less efficiently than you. I have one WIP commit that I just amend to. And I usually leave in there what I was doing, or what Iām thinking; notes to future me. And Iām curious if you take time to do that, like āHereās what Iām trying to accomplishā, or āHereās what I did during this hourā? Or itās literally just like āWIP, WIP, WIP, WIPā, and you leave them blank for later?
I just use āWIP, WIP, WIP, WIP.ā
Okay.
So if I wanna keep track of what Iām working on for myself, I just use a notes app, or something.
Gotcha.
Just because itās serving a different purpose. Itās not there to keep my history in check. I really just need to keep track of what was the bug that I was on, what was the thing that I was struggling with. But I will say, I know a number of people that do write little notes in their WIP commits, and then later when they choose to do a rebase, itās a lot easier to rearrange things as needed.
[56:09] Did I guess it right that you have an alias, or do you not have an alias for making your WIPs easier? Do you actually type āgit commit - mā?
I should. I should have an alias. I really donāt though. Thatās a good idea. Iāll do that.
Letās get you an alias. Maybe GWIP, I donāt know.
Just WIP.
Just WIP.
Maybe itās just WIP, yeah.
Itās so fun to say, and probably really fun to type as well.
Yeah. [laughs]
So whatās the time span at which you are doing this, and at what frequency? Because at a certain degree, if youāre literally just WIPping in order to have a backup for something, youāre basically just hitting the Save button again in Git, which means you really donāt trust your SSD⦠Which is fair, I think. But is this over the course of hours, days, weeks, months?
Usually hours. Definitely at the end of the day, at the very least, so I can push up to my future branch because I donāt wanna lose any changes⦠But itās really whenever I remember. But because itās all gonna get rewritten, it doesnāt really matter how frequently I do it, as long as itās at least at the end of the day. But itās really just for saving your work at that point, if youāre doing it in the method that Iāve described.
Right. You can actually write a watcher to do that for you.
Yeah, if you want to.
It can run every 30 minutes. And if you have unsaved changes, every 30 minutes just do a WIP commit. Because thereās no abnormalness to any of your WIP commits. Theyāre just like ā
Yeah.
So who needs an alias? Just get a script, and just ā boom!
[laughs] Right.
Weāre automating Annieās world.
But I would say, that does kind of marry you to the reset option.
Totally.
You know what I mean? You wouldnāt wanna ā
Right.
Those WIP commits are gonna be kind of useless if youāre doing a rebase interactive.
Letās keep the human in control here, Jerod. Cāmon.
[laughs]
Iām trying to help her out. Iām trying to get her as efficient as possible. Because then your cognitive load never switches.
Exactly.
Thatās true.
Because even switching to the command line and typing up āgit commit - m wipā
You know, but then I would just forget how to use Git⦠[laughter]
Fair enough. Itās all trade-offs.
All trade-offs.
So how has the community responded? Because this has been out there a couple of weeks⦠Weāve covered it in Changelog News, people have been reading it, thereās Twitter responses, I think thereās a Hacker News thread probably⦠What has been the consensus, the response? Because people do care about their Git, and people do think they have the best flow. And you have a better flow.
Yeahā¦
You donāt specify āBetter than the one Iām giving the example to.ā
[laughs] Exactly.
What have people been saying?
Well, thatās just to give it a catchy title; thatās all it was.
Totally.
Itās been a really mixed response. I would say most people have responded fairly positively, saying āI like this. I do it slightly differently.ā Thatās been the general response. And a lot of people have responded that they tend to rely more on rebasing interactive and Git squashes. Git squashes can be really helpful. I am not the biggest fan, because I like to have a little more granularity in what my commits are defining.
Describe a Git squash. I donāt know how thatās different than a rebase, or a reset.
Usually, a Git squash is what you might do when you have your PR, itās been approved, and to squash it, rather than having all of those individual commits, they all get squished into one commit that contains all of those changes. So it simplifies things.
Right.
But then you lose that granular view of what has actually happened. So I prefer not to use Git squash as much, but for some things it can be kind of nice⦠But I totally understand.
[59:47] Is Git squash a first-class citizen in VS Code, in terms of like its ā since youāve mentioned you use VS Code, itās pretty easy to hit the plus sign on a file to stage a change on like⦠If you knew you worked on two files, and youāre reviewing your reset for example, itās like āOkay, those two files go together, these three files go together.ā You just hit the plus sign and easily do that. I just wonder even if a squash is like a first-class citizen in the workflow of VS Code. I donāt think it is, to my knowledgeā¦
I donāt know. Iām mostly familiar with relying more on VS Code for knowing what to stage and what not to stage, because itās a lot easier to be specific about which files ā especially, if youāre doing this process where youāre only staging some of them, and not all of them. So Iām not sure.
I wasnāt sure what your flow was particularly because thatās how I tend to use VS Code; Iām usually a command line junkie with Git, unless Iām already in that visual mode and Iāve got my commit sitting here unstaged might as well hit the plus button on these two files and just commit them right there, because I happen to be there. Now, I also use Sublime Text, I occasionally use Vim, too⦠But most of the time Iām doing commits into a repository itās been VS Code primarily.
Early Google search says you need the Git Graph extension for this in VS Code⦠But thatās also 18 months old, so who knows; they could have brought it into the main editor.
Squash is good if you know ā I mean, thatās the thing⦠Again, thereās no one way to roam. Thereās just so many roads thereā¦
Right.
If squash gets you there, itās basically the same as doing a reset and choosing files. I mean, itās almost the same. The end result is almost the same. Youāve done away with that actual commit. If you have three individual commits and you squash them to one, itās still the same files touched; one single commit, one new message. The end result is basically the same. How you get there is just a different route, really.
Yeah. Once youāve decided youāre gonna rewrite the history to make it a clean history, then itās like āWell, how do I achieve that?ā
Yeah. And thereās no one way to do it. Thereās so many different ways.
Thereās at least three that weāve discussed. Thereās probably more.
I like the way youāve described it though, Annie, because for you in particular, if your executive function is challenged whenever you have to divert away from your creative brain, and you pause, or whatever ā they call they call that the state of flow. And you mentioned dopamine and norepinephrine - those are two neurochemicals that keep your brain in that world. Dopamine is primarily a reward kind of chemical, whereas norepinephrine is kind of keeping you back in adaptability, keeping your awareness of time, and self-control⦠Those are things that happen. So if thatās a challenge for you, then this is one of the perfect flows for you, because it just helps you to stay in flow.
Right, exactly. People with ADHD tend to ā itās not that we have deficiency in attention, itās that we have a hard time regulating our attention.
Right.
And this is exactly a situation where I personally find that ā itās not impossible by any stretch, and Iām sure if I just practice a little bit more, it might be easier for me to keep my commits as Iām building them in a little more tidy of a manner⦠But at the end of the day, if I do the reset method, my commits are gonna be as clean as possible. The end result is just fantastic. So why spend the energy upfront to do that when I can just clean it up and do it perfectly in the very end? Thatās my take.
Yeah. And you get one more dopamine hit.
Yeah, it feels great.
When you do that, itās like ā
Check that off.
Bonus dopamine. āThank you. End my day. See ya!ā
Absolutely.
Right.
Iād say to each their own, right?
Yeah.
Whatever works for you, I think thatās ā but I think one point of this conversation is 1) Jerod learned about reset, and you taught me about reset as a result of your article⦠But then 2) deeply examining what workflow works for you, and why.
Yes.
And then someoneās gonna hear this show and think āYou know what, Annie - thatās a great workflow for you. I like that for the reasons youāve stated.ā Mostly Iām a reset kind of person, I love interactive reset. I know Mark Erikson, one of the core contributors to Redux, commented on your tweet for your article, and just shared essentially the exact opposite; not that your way was bad, but they prefer reset, based upon their tweet.
[01:04:17.17] Rebase?
Sorry. Yeah, rebase. My bad. I should reset what I said, and say rebase. [laughter]
Thatās a WIP.
Thatās the thing though - itās deeply examining the way we leverage common tools.
Right.
And what works for you may not work for me, but now I know. And one ā I guess several points, but a main point is now I have a very deep point of empathy with you. If I was your co-worker and you did this and I didnāt understand your back-story, it may drive me crazy if I was like āWhy in the world is she resetting? That doesnāt make any sense.ā But now I know. Now I have ā
Her PRs are so clean and instructive⦠I hate it. I hate how logical her commits are.
[laughs]
Right. Such amazing commits⦠But for whatever reason, I can ā not so much down-talk your methodology, but not understand it. If I didnāt understand your back-story⦠Thereās something that changes in humanity when I or someone knows somebody elseās back-story. Think of a villain in a story. Whenever theyāre sharing that story, for a little while theyāre a villain⦠Until they share their back-story and they describe why theyāre the villain. Even the most recent version of Joker, for example ā Iām not sure if youāre a fan of this, butā¦
Yeah.
Joaquin Phoenix played that role amazingly. And traditionally, Joker is a villain, right? He is a villain. But now you have this significant point of empathy with that character, because wow, thatās what they went through in life and why they ended that way. It doesnāt make it okay, but at least now you can understand them better. I think thatās what weāre trying to do here, is like ā youāre the villain. Iām kidding, youāre not the villainā¦
Thatās exactly what I was about to say⦠[laughs]
I knowā
I was drawing some lines here and Iām wondering where youāre trying to go with this
I am the Joker, I am the Joker. [laughter]
Iām trying to massage my analogy hereā¦
This whole show was one big reveal⦠[laughter]
Surprise!
Itās a point of empathy, it really is⦠Because thereās no one way to roam, and obviously, Git can be a divisive kind of conversation, because people have feelings and emotions around their ways and their things⦠I think it just provides that point of empathy, for real.
Yeah. And I think that it doesnāt need to be a point of tension, because ā especially with the things that Iāve outlined⦠If you have your own feature branch and itās just you, and itās how you manage your local commits, it aināt nobodyās business how you do that, and how you deal with it. It really isnāt. Itās whatever works for you. And I see a lot of value in how other people have described how they managed to get through rebasing and I think thatās fantastic. And I donāt think it needs ā to me, there doesnāt need to be a fight about it. At the end of the day, itās just whatever works for you⦠And I think itās awesome that Git can accommodate so many different ways of approaching this.
Let me ask you this - do you think Render has less customers because of the way you commit your code, or more customers? They donāt even know, is the answer. They donāt even know. They still love the platformā¦
Itās none of their business! [laughs]
Yeah, itās none of their business. If the end result is still a working product that customers love, thatās the point, right?
Right.
Well, Annie, we appreciate you coming on the show today. This has been a fun conversation. And we appreciate you writing this blog post. Hopefully, you have future posts in mind, and we encourage you to keep writing⦠Because as you share this way ā I learned something, Adam got some more empathy, we revealed that youāre the Joker⦠See? Good things happen ā
Thatās right.
ā¦when you publish on the internet. So we really appreciate it. And just broadening the conversation around a tool that we all know, and most of us love is just helping everybody involved. So we appreciate that, and we just encourage you to keep writing.
Thank you so much.
Any advice for those out there following along? Any final words of wisdom?
I would say donāt let the imposter syndrome get to you too much. I think thatās really what drives a lot of peopleās strong opinions; if you were maybe taught a certain way, and when you were learning early on that youāre supposed to do it this way, and that was something that you struggled with, then that history may have contributed to some amount of imposter syndrome. But the reality is thereās a lot of different ways of accomplishing the same thing. This goes for beyond Git, just in development in general. The more we are curious about how other people approach the same problems, the more we can learn, and I think itās a lot better for the community if we approach these conversations through a lens of curiosity, rather than trying to find the right answer.
I agree. For the curious! Thank you, Annie. Itās been awesome.
Thank you.
Our transcripts are open source on GitHub. Improvements are welcome. š