 Thanks for everyone for joining me in this discussion. Today I want to talk about Git, commit messages, and some unexpected value that they can provide as a form of documentation. Starting out, I want to talk about complexity. I started at Stitch Fix a little bit over a year ago, and we have pretty good onboard documentation. I read the Wiki, I read your first day, got my computer set up, and I felt like I had a pretty good sense of the teams and the apps. Then the rubber met the road, and I got my first story. My team works on an application that's been around for about six years now, and so it's accrued a lot of complexity. Add to this, the first story I took was a bug fix. As I got into it, this is just what it felt like. It felt like I was doing with a lot of different pieces, and they're connected to each other, but it wasn't exactly clear why or how they're connected, or when I'm changing something here, what's going to happen elsewhere. It got me thinking about documentation and where I could look for the answers to this question. Two different metrics stand out for me as a way of thinking about my documentation. Accuracy and accessibility. Accessibility to me means that I don't have to work too hard to get it. If I have to look at documentation often throughout the day, if it takes me a minute to find an answer, and I'm doing that a couple dozen times, that's 30 minutes. It really adds up, and so if I can get an answer quickly in a few seconds, that's perfect. If I don't have to read my text editor, that's even better. Accuracy is kind of like what it sounds like. Is the information I'm reading, is it correct, or has something changed? Has the code evolved in a way that is separate from the documentation, and now what I'm reading about it is incorrect. So one of the ways we can get answers is with, my phone will connect, all right, we're going to do it this way. It's with Wikis, so this is how I started, we're going to get all the transitions now. Wikis are great for the onboarding stuff, the new hire, the high level, you're not going to change it very often, but you see I put it down here on this bottom left because they're not super accessible. Yes, you can search some, but for me, in my experience, the search just never seems to work as like I want, I always have a hard time, and they're not always accurate. So for new hire stuff, they're good, but if you were to try to document that circuit diagram, that entire system in a wiki, it would just very quickly go out of date. Next is JIRA, so issue tracker, maybe use Pivotal Tracker. We use JIRA at Stitch Fix, and I can look at recent issues and try to get a sense of what's been changing and follow that, but it's, I would say, even less accessible than a wiki, it's very challenging to search, but maybe a little bit more accurate because it's a little bit more timely. GitHub, GitHub's up there because it searches a little bit better than Wikis, and it has the same accuracy as, you know, a little bit more accurate than JIRA because it's still timely, I can look at the issues, I can look at pull requests. We really want to nail accessibility, comments. Comments have a bad rap, understandably, and that's why I've put it pretty low on the accuracy. It's super accessible, which is probably the reason we often turn to comments, it's a way of documenting things, because it's right there in the code, and it checks that box of I don't even have to leave the text editor. However, as we've probably, a lot of us that may have experienced, they're not always accurate. It's easy to change the method, change what's happening, and forget to update the documentation. And so, we're here to talk about Git. Git is what I think the best of both of these. I'm gonna show in a few minutes some different ways that it's hyper accessible through text editor integrations, and it's very accurate. As you are modifying the code, you're gonna write a new message that describes the change, and because that change, that message is attached to the code that it's changing, if you overwrite a method, you're now gonna have the new message. You are automatically updating the documentation associated with that. Here's an example, it's a code I was looking at in this application. And something about this caught my eye, it's that comment. So, if we have 99999, and we wanna generate the next one. This is for generating purchase order numbers. We wrap back to one. And my first instinct is, are we gonna start overwriting PO numbers, what's gonna happen? Why, what is going on here? Why, why is this the behavior that you want? I can look at the code itself and see the how, but I couldn't see the why. And so I followed my instincts, I looked at the get blame, and this was the message I saw. Work in progress, generate PO numbers based off of starting point. Now, to be fair, this commit was written four years ago. So it was a different time for the company, we were moving fast, but it's not unsurprising to see these kinds of commits in our repositories. More recently, I did this. This is some work that I'm doing, I'm actually still working on this. There's one of our pages where we wanted to change the CSS to a new framework. And it's not really prioritized in our sprints. It's something that I tend to just hack on every, whenever I have 30 minutes. Whenever I can just take a few minutes to update a new little part. And so it's resulted in a lot of work in progress commits. The changes aren't often atomic, and so I don't have time or much. There's not anything to unite the commit that I would give it a good message. And so it just has developed into this work in progress mess. And I want my commits to be valuable to my coworkers. I want them to provide context. And what I just showed you clearly isn't going to do that. If somebody get blames, they're not going to understand any of the issues that I ran into updating the CSS or why I may have changed the button color. I have sacrificed that documentation with this bad history. So let's talk real quick about how we can use the history. The simplest is to get log. If you just run it in your terminal, you're going to get a very verbose output, and so it's maybe not the most useful on its own. But if you pair this with some of the command line options, you can search through your git history. And if you're using a GUI, which is perfectly legit, then you can also search through GUIs. So there's a lot of richness just in the git log command. My favorite way and the way I more often use it is with git blame. So here's an example of a git blame integration with BS code. You can probably barely see it, but off to the right of each line that I've highlighted. There's a little annotation that shows the commits author. And I think it's also the, how long ago, how long ago that was changed. And if you hover over it, you get this nice little pop up, gives you a little bit more information, includes a link to take you right to GitHub if you want to view it there, if you want to share it with someone. Pretty great integration with BS code. And then here's another example. This is Adams. Adams I like because it has this heat, this little heat map bar. And so the more orange that line is, the more recent it is, and blue is older. That's nice if you're just getting into a file and you want to see what's been happening in this code recently. Or if you're debugging and you want to see maybe somebody made a change that had some unexpected consequences, this is a really cool integration. But all of this depends on writing good commit messages. So if we are, we can see how it's not helpful enough to just know that it commits recent or old, but we also need to include all this information. So let's take a few minutes to think about what makes these commit messages valuable. The first thing is starting off with a good title. So I like this convention, this is, I think, pretty liberally borrowed from Tim Pope's, one of Tim Pope's blog posts. I like this convention of starting with a capitalized verb. We'll go through some examples, but for example, one example is add a blog, or add posts, or update CSS. And follow that with a description. This is where I think a lot of times we move a little too fast. This is a wonderful place to take a second and just think about yourself in a week or a month or a year. What questions are you going to ask? If you were to look at this code again, what is going to make you raise an eyebrow? What do you think somebody else is going to wonder? What do you want to make sure people aren't tapping you on the shoulder or writing you in slack? You want to try to answer these questions for them if you can. And it's not just, I personally, I don't know if this is selfish or lazy or what, but I really like to think about myself about this. For some reason it just really helps motivate putting the right content in here. And so, yeah, it's good to focus on your descriptions. And then last is an issue tracker. For the most part, you will be using an issue tracker. Maybe it's GitHub issues. Maybe it's JIRA, Pivotal Tracker. If you include a reference to your issue tracker in the commit message, this gives people a way to find their original issue. And again, just kind of connect it to the business context. Connect it to the bigger picture. So here's an example of a commit I was working on. So I'm just gonna, for this, all these examples, we're gonna say I'm working on a blog. So this is my commit message. Let's try to apply those guidelines we just talked about. So if I start off without ad posts, the first thing we can see is that we need to work on that title. So let's capitalize the first letter. And you know, this seems like a really minor, like, pedantic thing. But it adds a lot of, like, visual cohesion or, like, professionalism. It adds, like, that nice touch to your Git history. And it's almost evocative of, like, a broken Windows principle that, like, if you just show that you, like, take that level of care, that it somehow motivates others and, like, says, like, we care about those. So here's just a slightly more descriptive title. I'm not doing too much in this commit. I'm just generating a post-model and a table. But there are some details I can add. So I can write a small sentence about it. Maybe I'm not adding too much detail, but I am, I'm highlighting that the posts have a title and body. I am also calling out that maybe somebody looking at this in the future would wonder why I didn't associate posts with a user. Surely that's something you'd have to have. Well, I can highlight that that's coming in a future, future story, and so don't worry. And then, of course, we have to add our issue tracker. So we still have this mess, though. I've written all these bad commits. What am I going to do about this? We'll talk about some tools that we can use to help work with our Git history. First is rebasing. This one has developed quite a reputation, and I feel like I've run into a lot of junior engineers who were told at one point to just never rebase. Don't worry about it, it's going to ruin the history, and you're gonna destroy my work, so just don't ever do it. And that's what I was told when I started out. But then I started talking to other engineers, reading some blog posts, and there's a tutorial I'll share in a minute that was also really helpful. And once I got my head around what's happening, it really empowered my Git workflow. And so I'm gonna go through a really, this is the simplest rebasing example I could think of, but I hope it helps give you some visual model of what's happening. So in this example, we are on the master branch. I'm only showing two commits. And head is a reference, it's just saying which branch am I currently on. So if I were to run Git status right now, you can see confirmation I'm on master. So as we're going along, you'll see that head reference move around. All right, so let's start our new feature. This is gonna be a feature where I'm adding a post model. So I'm gonna check out with the dash B flag to create a new branch. And you can see it's out of the new branch and that head reference has now moved up because I'm now on add posts. I've done some work. We're gonna give it a not so great commit message, but we're gonna just for this example, make a quick commit, and I'm gonna switch back to master. This is, let's say I'm working on this with my buddy and I know that they just made some, they just merged the pull request into master and I wanna make sure that I'm working on the most recent version of master. So I need to switch back to master and then I run Git pull, which is gonna get that new work and it's gonna move master along. So you see there's now this divergence in the history and this is where rebasing becomes valuable. I can switch back to add posts and I can run Git rebase master. When I do this, Git is gonna take the commit, this commit, in this case we only have one commit, it's gonna take this commit and it's gonna change the base of it from that original commit, three, two, zero, and it's gonna change the base to master. So it's gonna replay that work onto master and when it does that, it's gonna generate a new shawl. This is something just to keep in mind, we're gonna come back to the consequences of this. So this is where it can kinda create headaches for people. So that's the simplest example of rebasing I could think of. So let's make it a little bit more complicated. In this example, I've done three commits worth of work and I would say we still have some work in progress in there and I don't really want that to live forever. So let's this time do an interactive rebase. This is by and far the most powerful way to do a rebase. Although it's gonna pop up this giant wall of text. But don't be worrying, most of this is just documentation. So everything on the bottom that starts with a hash is just documenting what you can do with an interactive rebase and everything at the top are your commits. So these are those three commits that are within this rebase and it's gonna apply them from top to bottom and what it's gonna do is, so on the far left where it says pick, that's the instruction. So it's telling get, you should just pick this commit and if we were to close the editor right now, it would work as if we hadn't done an interactive rebase anyways. But there are a lot of other options we can use and these are the ones that I end up using the most. I know this text is small so I hope people in the back can still read it. So pick is the one that we're already on, it's the default. That's just gonna use the commit, use the message and everything just moves on. Reword is gonna use the commit and give you a chance to change the message. This one I end up using a lot because I will often get carried away working and forget to add the issue tracker to my store, to my commit messages. And so I'll do an interactive rebase and I'll reword the commits which gives me a chance to add that issue tracker back in. Squash is going to take the commit and combine it with the previous one and fix up it's just like that but it's going to discard the message. So the squash, you're gonna have a chance to edit the message, fix up, it's just gonna get rid of the message. So in this example, let's say we wanna pick that first, we wanna pick that first commit and then the next two commits, we wanna combine into the first commit. So we're gonna change the next two lines to squash. When we close the editor, gets going to again pick up those commits and it's going to open up another editor. So this is because we did squash, it's going to give you a chance to update the commit message. So this is the original commit message but we just did some work on creating a new commit message. So let's get rid of that and then let's add in our new commit message that's descriptive, has a good title and has a link to our issue tracker. Now when we close the editor, gets gonna do its thing, it's gonna combine these commits and it's gonna replay it on the master and once again, give it a new show. So these are two very, these are probably some of the simpler cases of rebasing. If, I wish I could spend more time going through examples, I love rebasing. This is a great resource, we're gonna get branching if you aren't familiar with it. I highly recommend you check it out. It goes, it starts from a very simple, I think it starts with just creating a commit and then takes you all the way up to really intense rebasing and combining different crazy branches that I hope you never end up in that situation but it's super good practice. And by the way, I have at the end of this a link to everything that I'm referencing and I'll publish my slides online so these will be available. Okay, so we've covered rebasing so let's talk about amending commits. This happens to me way too often. I think I'm done and then I realize, yeah, I gotta run the test suite and I run it and I get a failure. So one option is I can fix it, can add those changes and create a new commit that's just fixing the test. And I, you know, you see this all the time, I do. This is fine, if we look at the log, the problem is we have this, we have two commits that are now, neither of them are atomic commits and this is a word you may have heard about commits. It's this idea that a commit is an isolated change and it can exist like on its own. Right now there's a dependence that we couldn't release this without 89f. And so that means that B9e commit is not atomic. The test suite was not green. So that's one of the downsides of this. Another is it's not, it doesn't help my coworkers get context on what change is happening. So if my coworker goes and looks at these tests that I had to fix and they try to understand what was happening and they wanna understand why the test was written this way or what feature we were working on, they're gonna see fixed tests as their commit message. And that's not what the feature was. That was a consequence of the fact that I broke the test. The feature was I added posts. And so it's not providing enough, it's not providing as much context as it could. But we have an option and this is the amend flag with committing. So with dash dash amend, Git will open up the editor again and give us a chance to change the message. And so this is more powerful than just adding in new work. It's also useful if you realize that you need to make a change to the commit message. But in this example, I'm just focusing on we've made some fixes and we need to combine them with the previous work. So here I can commend, I can amend it. Looks, you know, the message isn't gonna change. So that's fine. And when I exit, it's gonna just make another commit. It's gonna make this, it's gonna update that commit. And of course we can run our tests. See, we're all green, it's great. Now we can look at Git log. We have a nice, clean history. It's descriptive and it builds context for our co-workers, explains what we were doing. So let's push it up. Ah, dang it. Rejected. So, if you've done any of this before, you've probably ran into this. And this is where that detail about the shawl changing comes in. There's a, and this is also, I think why a lot of times junior engineers are told just to avoid rebasing. Cause there's a bit of a decision tree that emerges. So this is roughly what happens in my head. It's, there's a lot of nuance to this. And so don't, you know, but yeah, for me, we are using a pull request workflow at Stitch Fix. So each feature starts out as a new branch and I own that branch. I'm the only one working on that branch. The powerful thing about that is because I'm the only one working on that branch, I'm not at risk of, and I'm not at risk of messing up someone else's work if I were to rebase and push, or force push, which we'll show in a minute. However, if you are not using that type of workflow, or if you are working on a feature branch with someone else, then you should not rebase. You should not amend. There's a lot of danger in, and how you could potentially lose other people's work. It's not, yeah, so let's now try that push again. This time we're gonna use a different, we're gonna use a flag. There's actually two ways to accomplish this. This one is a slightly safer way. So the simplest way is with just dash dash force. When you do that, Git is going to just tell GitHub, take this, I don't care what you have. I don't care if anyone's done anything on it. My version's the right one, take it. Force with least is a slightly gentler version of that. You're still telling Git, take this, I know that I'm changing the history from what you have, but it's instead saying, if someone else has changed the history since I last pushed, then reject me. And so this is a slightly safer way if just in case one of your coworkers decides to unexpectedly contribute to your feature branch, this is a way to avoid that. Okay, so let's go back to this. There is yet another way that I like to deal with messy Git history, and it's probably the way that I'll end up dealing with this. The reason is because of the nature of this work, I ended up with a lot of merge conflicts and instead of trying to rebase my branch onto master, I ended up back merging master into my branch, which I didn't talk about, but is another way of keeping my branch up to date. And so the Git history for this is quite a mess, but it doesn't mean that I have to let this make it onto the master branch. I can still, I still have one more chance to clean it up before it makes it to master. And it's this option, if you click this little arrow when you go to merge and commit, there's a squash and merge option. What it does is it's doing that same rebase squash that we just went through, and it's giving you the chance here to edit the commit message. So here, you can see I've just taken, I already have the description written well and so I just copy and pasted that. Updated the commit message and merged it. And so now, even though I started off with a mess of work in progress commits, what's made it, what it eventually makes it into master, I will be able to add more context and color to it so that it's helpful for my coworkers. So bringing it back, I just want to talk about accuracy and accessibility. And I've also added to sickness here because I find that it kind of speaks to how quickly you can find answers and get if you and your coworkers invest the time and effort into writing quality messages. So thank you again for coming out and hearing my talk. I work at Stitch Fix. This is my Twitter handle. You can try to reach out to me. I'm not a huge Twitter person, but I will try to pay attention. So email is another option. And again, I'll put my slides up on the speaker deck I think is the website. And so all of these links will be accessible. So there's the Tim Pope article about commit messages. Forced With Weas is an Atlassian article. That's pretty good. And then that learn, get branching is a great tutorial. You can also just Google it and it's pretty easy to find. Thank you.