Everything You'll Need to Know About Git

reflog Exercise & Cherry Pick



Everything You'll Need to Know About Git

Check out a free preview of the full Everything You'll Need to Know About Git course

The "reflog Exercise & Cherry Pick" Lesson is part of the full, Everything You'll Need to Know About Git course featured in this preview video. Here's what you'd learn in this lesson:

ThePrimeagen guides students through a series of tasks including creating a branch called "Baz" off of the "trunk" branch, adding a commit to the "Baz" branch in a new file, switching back to the "trunk" branch, deleting the "Baz" branch, and then recovering the deleted branch using Git commands. He also introduces the concept of using "cherrypick" to selectively merge a specific commit into a branch.


Transcript from the "reflog Exercise & Cherry Pick" Lesson

>> This will be a weird task to do, but it'll be fun. What I want you to do is I want you to create a branch called baz. I think currently we are on foo, you can create on whatever you want. It doesn't matter about the base branch or branching off of.

I want you to create a branch, or I guess I say, do it off of trunk. It really doesn't matter. But let's for now just say, create a branch off of trunk called baz, add one commit to baz, and do it in a new file, right? Don't do it in read me, do it in a new file, switch back to trunk and then delete baz.

And then I want you to bring baz back to life from just the sha. And we can discuss how you do that. So first do the first three and then we'll kind off talk more about this last one, and I'll join you. I'll go git checkout trunk, git checkout -b baz.

Echo, bazzy, the baz, git add, git commit, definitely my best work here. git check out trunk, git branch delete, baz, dang it. I just lost all that work, and darn it, I just lost all my history, too. I could have probably recovered it if I didn't Ctrl+L. But now look at this, I'm up a river without a paddle, right?

Well, hopefully, you don't think that. I think this is a fun kind of exercise to go on. So let's first use reflog and let's recover our SHA. So what I'll do is I'll go like this, git reflog. I know it's in the last couple, so why not just do a -5 so you don't see your entire history?

And look at this, definitely, my best work. Okay, so that's the SHA. We have the SHA from that commit, which means what can we do with a SHA?
>> Hook it up, rebuild the whole repo.
>> We can rebuild the entire repo just from this one little tiny SHA, right?

Remember, git cat-file -p this. Look at that, it's right there. It's still in Git. Just because we deleted the branch did not mean we deleted what you just changed, the files are in the compute, as a wise man once told me. All right, problem, with our sweet knowledge of how Git plumbing works, can you retrieve the contents of the commit using our super awesome powers to grab out baz.md?

Can you do that. You have the SHA, try to get out what was in baz.md, not from your memory, but from Git. So we can use git cat-file -p. With that, I can go into the tree, git cat-file -p that. I can see my little baz file right there, and then I can git cat-file -p, that thing, and look at that bazzy.

I recovered it walking the SHAs all the way to the exact file. So I could take this and I could cat that, and I could pipe that into baz.md and then I could git status and look at that git diff. We actually don't have anything in there, because it hasn't been added.

We can add that, then git diff staged. And look at that, there's baz, it's a new file right here. My goodness, I've just recovered it. And I feel like a hacker, right? There is actually easier ways to do this. But that was just kinda fun, right? Pure wizardr,y you do this at your job, you're getting a promotion, right?

Just right off the bat, Brent, CTO, Frontend Masters will just hire you as the new CTO for just doing this. All right, let's not use the internals. Is there another way? I mean, it's great flexing, right? You should always flex that work when you can, but maybe you don't have to.

Is there a easier way to do this? Hold on, I'll go like this, git reflog. Let me just have this thing out right here.
>> In chat, someone mentioned cherry-pick [LAUGH].
>> All right, so one thing I can do, If I really wanted that change in trunk, I could git merge just that SHA.

I already have the SHA, right? I could just bring it in. Git still has the state, boom, look at that, baz is now in trunk. Wow, that was magical, right? We didn't have to do all that hacker command stuff. We just simply needed the SHA and then we could just merge it into trunk.

Now, I have baz right there. It's just right there. Kinda interesting, right? You might not have seen that one coming. So we can do that. But there is a problem with merge. What happened if there was a lot of diverging that happened? What happened if there was a bunch of commits in betwixt my trunk head and that commit?

What would happen if we merged it? We'd git all that history, right, cuz it's gonna try to find, what does it do again? It walks back, it finds the merge base or the best common ancestor. And then it replays all of those potentially into a third branch, and then does a merge commit if the histories have diverged.

So you may not want to do all that, right? That may be kind of a pain. Maybe you just want that commit and not everything else. Well, [LAUGH] I don't know if you know about cherry-pick, probably you've never even heard the term until this exact moment. But cherry-pick allows you to take just one or more commits, specifically.

Cherry-pick is fantastic. In one of my 20% commands, I probably have used this the most. It's just because any time I have just that change, I don't want to merge, I just want this one diff cherry-pick it in. And it works with remotes, it's fantastic long as you are up to date with your remote and you have all the changes from them.

You can just cherry-pick a singular commit into your project if you need to. It does require your working tree to be clean. Remember, working tree is just the state of your project, everything that's been tracked by Git. So no changes to your working tree, and then you can cherry-pick, and no changes to your index either.

Sometimes if you have index problems, it will say no. Index, again, is the staging area. Remember, it's not necessarily your working tree, so there you go. So get cherry-pick, try it. If you haven't done it, see if you can cherry-pick the change of baz into trunk if you did not merge it in.

So all you have to do is, of course, get cherry-pick and the SHA, and it will just merge it right in. Fantastic, really? Real talk, it is by far one of my most used commands is cherry-pick. I absolutely just has saved my bacon more than once. Cuz have you ever had a change that has diverged so bad due to something, and then the merge conflict is just incomprehensible?

And this has happened to me. And luckily, you've made some small commits and you haven't made one big commit. I'm just gonna take out these two things, play them over here and then try to rebuild the rest of it. I've been in a situation where it was such a bad divergence that the only way forward was to actually just hand move things over, and that was with cherry-pick.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now