Jun 30, 2022 · 5 minute read
Version control is magical.
I strongly believe everyone should learn how to use it - not just developers. How many times did you complete homework back at school and create arrays of filenames to denote just how final that piece of work was?
Today, in modern web development, Git is an absolute pre-requisite. But it's still shocking to see just how many experienced developers are just scratching the surface of what Git can do for you.
In this blog post I hope to unearth at least one useful Git command you perhaps haven't come across or would even think to use.
Git rebasing is boils down to moving or combining a sequence of commits into a new base commit. It essentially appears like you've created your branch from a different commit base - extremely useful if you've been working on a branch for a while, you've diverged off of the main branch for a while and you run into conflicts when you try and merge back in.
It works something like this:
git checkout main # change to main branch git pull origin main git checkout - # go back to last branch (feature branch) git rebase main # fix conflicts git add . git rebase --continue # until all changes are in
You can also use
--interactive mode for rebasing which will let you manually select which commits you want to ignore throughout - helpful if you've made a commit purely to add some debugging and forgotten before committing.
Now, some of you might be thinking you can just
git pull origin main in your branch and resolve the merge conflicts in an even easier fashion. While they are both similar there's one massive difference that you want to keep in mind here:
git pullwill create a new commit that combines the two branches together
git rebasewill move the commits of one branch on top of the other
You can also use
git pull --rebase to pull using rebase which can be great and save you a lot of time. However
git rebase will essentially keep your git history clean.
Why is this important?
It means you can safely and effectively use our next arcane power:
git bisect uses binary search to find a commit that introduced some new unwanted functionality (read: bug).
It kind of works like this:
Imagine you're digging for the commit that broke a feature that we knew was working in commit
0cd429f02 (or a tagged commit), and somewhere along the way we broke something and a test is failing.
We can use git bisect to narrow down the commits and help us identify the culprit like so:
git bisect start git bisect bad git bisect good 0cd429f02
Note: You can use
git bisect reset to jump out of this.
Once you've specified a good and a bad commit, bisect will find a commit in the middle of that range, check it out and give you some information regarding how many possible steps are left to split through.
Now that you're in your checked out commit you should run your tests and assuming it works, you can inform bisect of that by typing
git bisect good, or tell bisect that that particular version is failing with
git bisect bad.
Repeat the above steps and eventually you'll run out of revisions to test - bisect will then spit out the description of the first bad commit with a nice little summary - and there's your buggy commit. ✨
Stashing is used to take your uncommitted changes (including staged) and temporarily "stash" them away for later.
Extremely useful when you're not quite ready to commit a change, but need to move to another branch for some reason - maybe there's a bug you need to investigate.
You can stash your content like this:
git status Changes not staged for commit: modified: README.md modified: mix.exs modified: test/inspyre_web/live/story_live_test.exs no changes added to commit (use "git add" and/or "git commit -a") git stash git status On branch main Your branch is up to date with 'origin/main'.
Like magic your changes are seemingly gone.. or are they?
If you run
git stash list you'll see a log of previously stashed events alongside the branch you were operating on and the last commit in that log.
git stash apply will take the last stashed set of changes and apply them to your current branch but will not remove them from your stash list. If you know you won't need them this one time stash you'll want to use
git stash pop to apply the changes and pop them out of your stash list.
Have you ever accidentally thought you changed branch but really you were still in the last feature you were working on?
Have you committed multiple times?
Whoops. It's cool - we can fix that.
git reset --soft HEAD^N where N is the number of commits you want to un-commit to bring them back to you. From here you can stash or move to another branch and commit them there.
Be careful not to type
--hard though. That'll trash unsaved changes for good.
Gits secret weapon / time capsule.
git reflog will give you a list of every single thing you've done in git across every single branch.
If you've accidentally ended up in a state you weren't expecting to be in, deleted things, merged things accidentally or can't figure out what's happened, reach for
git reflog (at least before you trash everything and re-clone your repo).
This one is simple but effective - and one I know several devs resort to deleting and recreating a branch to solve! 🤯
Renaming a branch!
git branch -M <new_branch_name> to set your new branch name for the branch your currently in.
That's all folks.
Hopefully that was useful for some - subscribe to my Substack below for similar content and follow me on Twitter for more git (and general programming) tips.