Setup Example Repo0:00
Now that you've learned the essentials of Git rebasing, well, let's switch over to interactive rebasing. How is that different? I'll show you. I've created an empty directory here, so let's go ahead and initialize Git. And let's simulate that we're working on some kind of project. So, for example, we'll say class Person, and we'll save that to Person.php. Maybe we'll do another one for the person's job, but I will accidentally spell it wrong so that we can make another commit to fix it. I want to have a lot of examples here. So job.php, list the files, looks good. Let's go ahead and add everything to the staging area, and commit with add initial person classes. All right, if we do our fancy git log here,
Let's go ahead and add everything to the staging area, and commit with add initial Person classes. All right, if we do our fancy git log here, that looks great. But now we realized we made a mistake with that Job class. So I open that up, we fix it up, close it out, do a git status, add everything here. I'm using aliases now, since we're starting to get a little more comfortable with all this stuff. And we'll commit with a message of fix typo. Next, if I open up our Person class, well, maybe we'll do something like this. If we want to designate where a person works, we could say position, and then we could say return new JobPosition,
If we want to designate where a person works, we could say position, and then we could say return new JobPosition, and we could say $job equals $that, and assign it. And, of course, remove the return. Okay, cool. So once again, we close that out, add that to the staging area, and git commit with -m "allow for setting a person's job." Remember, these commits just represent things you are working on, little stop points or milestones. All right, so if we do a git log, or my fancy git log, and if you haven't seen that one yet, you can just copy all of that.
All right, so if we do a git log, or my fancy git log, and if you haven't seen that one yet, you can just copy all of that. I'll save it to a gist or something if you're curious about that. But anyways, if we review that now, okay, so we add our Person class, and then we had a typo to fix, and then we continued working on that. But then we check out our Job class, and we forgot to add the braces here. So we have to fix that. We'll fix this up, put it on its own line, git status, git add everything. I have an alias of gaa, or, of course, that.
git status, git add everything. I have an alias of gaa, or, of course, that. And then git commit, or gc. And once again, just to make sure we're on the same page, they're just simple aliases. git commit with a message of "dang it." Finally, let's just do a tiny bit of work on the Job class, and we'll say when you initialize it, I'll use a macro here, you pass in your jobTitle, and then we assign it, and we'll say title, and return this->title.
you pass in your job title, and then we assign it, and we'll say title, and return this title. Or in fact, let's disable that for the time being, git status, and then I will say something like work in progress. You'll see this quite a bit when people are still working on things that may extend for multiple days. You'll make a commit and just write WIP. I'm still working on this, it's not done, but I'm going home for the day, so I'll make a quick work in progress commit. All right, so if we do a git log, there we go.
but I'm going home for the day, so I'll make a quick work in progress commit. All right, so if we do a git log, there we go. And then finally, the next day we come back, once again, simulating quite a bit of work. Here we'll represent that with a single getter. So we return that, and ta-da, everything works great, right? So if I do a git status, we add that to the staging area, and commit with finishUp Person and Job classes. And that's enough for our example. Okay, and that looks good.
Move Work Off Master3:44
well, you might want to rebase this just to make it a little more consumable. And that's what interactive rebasing is for. So we're going to run that command, but first, did you notice that we made all of these commits on the master branch? Well, what if you start working on master and you remember, oh crap, I forgot to create a new feature branch, right? You'll do this all the time. No problem. Here's how you can fix that. First, in its current state, check out a new branch.
Here's how you can fix that. First, in its current state, check out a new branch: feature/people. Okay, so now we have a separate branch with all of these commits. So all we have to do now is check out the master branch, or again, for the alias, if I do alias co, you'll see I have one that translates to that, which is useful. You could even do com for checkout master, since you'll do that all the time. Okay, so if we do git log here, all we have to do now is a hard reset back to the commit.
Okay, so if we do a git log here, all we have to do now is a git reset hard back to the commit before all of the ones you didn't want to write on master. So in this case, we'll reset all the way back here. And remember, you only want to do this sort of reset if you haven't yet shared your repository with the rest of the world. It's great for local stuff. So git reset hard all the way back to that state. Okay, so now if we do a git log, it's like we only ever made that first commit.
Interactive Rebase Basics5:00
Okay, so now if we do a git log, it's like we only ever made that first commit. But if we check out our feature and do a git log, sure enough, we can see all of the other commits. And that's how you fix that issue. All right, little side note there. Next, let's perform our interactive rebase. git rebase -i for interactive using the master branch. Okay, so what you'll see here might look a little overwhelming at first, but actually it's pretty easy to understand once you learn the basics.
Reword Commit Messages5:51
Imagine that WIP, well, you're really explicit and you need that to say work in progress, right? So just imagine a scenario where you want to reword a previous commit. You can fix that by saying R or type reword. And remember, that just corresponds directly to this option. Okay, so we are rewording that commit. And for all of the other ones, we say pick, meaning good to go, use that commit. All right, so I will :wq to exit out. And now notice, specifically for this commit, I can reword the message to be work in progress.
And now notice, specifically for this commit, I can reword the message to be work in progress. Okay, close that out. We're done rebasing. So if I do a git log, we've successfully changed the commit message. Useful, right? But you know what? Let's do this again because we're not done. What it looks like to me is we're working on a Person and a Job class. So we set that up, and then we made a mistake,
Squash Commits Together6:39
What it looks like to me is we're working on a Person and a Job class. So we set that up, and then we made a mistake, and then we kept working on it, and then we finished it up. So why don't we rebase all of that into a single commit that represents the work we did? Okay, well, if we take a look at these, it looks like we want to use squash. And what squash means is you take a commit and you squash it. And just imagine pushing your hand right down onto the commit so that it squashes down into the commit that came before it. All right, these changes squash in and mix up with the commit that came before it.
It's going to make the message for this commit equal to the sum of all of the messages that are being squashed. If that's what you want, then you're good to go. But if not, if you just want to rewrite it, well, remove this, remove that. And we can change this to add person and job functionality or whatever. So that's our new message. We're done rebasing. If I do a git log or my fancy git log, as easy as that, we've cleaned up our commit history.
Recover History with Reflog8:36
That's one of the huge advantages to it. So in the example of this, well, yeah, we just kind of rewrote history. So did we delete things? Is there any way to rewind the clock to how we had it before? Absolutely. You can do git reflog. This is a command, and we haven't reviewed it until now, that basically just shows a log of every event that took place. So if we look at the top, we can see we're doing a lot of rebasing here.
And now we set our message. Now before, we completely changed it. But if you just want to leave it as it is, git log, and that's how it turns out. And actually, a quick note with git to keep in mind. Sometimes it's useful when writing a commit message to explain exactly why you needed to do this, even if that requires a paragraph of writing. So what you generally do in that case is provide a quick summary of what you did on the first line.
