Podcast: Play in new window | Download
Subscribe: Apple Podcasts | Spotify | TuneIn | RSS
We wrap up Git from the Bottom Up by John Wiegley while Joe has a convenient excuse, Allen gets thrown under the bus, and Michael somehow made it worse.
The full show notes for this episode are available at https://www.codingblocks.net/episode195.
Sponsors
- Retool – Stop wrestling with UI libraries, hacking together data sources, and figuring out access controls, and instead start shipping apps that move your business forward.
News
- Thanks for the reviews on iTunes jessetsilva, Marco Fernandooo, and sysadmike702!
- Want to help out the show? Leave us a review!
In Conclusion, …
Git Reset
- Git’s
reset
is likely one of the commands that people shy away from using because it can mess with your working tree as well as what commitHEAD
references. reset
is a reference editor, an index editor and a working tree editor.
git reset |
Modifies HEAD ? |
Modifies the index? | Modifies the working tree? |
---|---|---|---|
--mixed |
YES | YES. Removes all staged changes from the index, effectively unstaging them back to the working tree. | YES. All changes from the reset commit(s) are put in the working tree. Any previous changes are merged with the reset commit(s)’s changes in the working tree. |
--soft |
YES | YES. All changes from the reset commit(s) are put in the index. Any previously staged changes are merged with the reset commit(s)’s changes in the index. | NO. Any changes in the working tree are left untouched. |
--hard |
YES | YES. Clears the index of any staged changes. | YES. Clears the working tree of any unstaged changes. |
git reset
mode flags change?Mixed reset
--mixed
is the default mode.- If you do a
reset --mixed
of more than one commit, all of those changes will be put back in the working tree together essentially setting you up for a squash of those commits.
Soft Reset
- These two commands are equivalent, both effectively ignoring the last commit:
git reset --soft HEAD^
git update-ref HEAD HEAD^
- If you did a
git status
after either of the previous commands, you’d see more changes because your working tree is now being compared to a different commit, assuming you previously had changes in your working tree.- This effectively allows you to create a new commit in place of the old one.
- Instead of doing this, you can always do
git commit --amend
.
- Instead of doing this, you can always do
- This effectively allows you to create a new commit in place of the old one.
- Similar to the use of
--mixed
for multiple commits, if you do areset --soft
of more than one commit, all of those changes will be put back in the index together essentially setting you up for a squash of those commits.
Hard Reset
- This can be one of the most consequential commands.
- Performing
git reset --hard HEAD
will get rid of any changes in your index and working tree to all tracked files, such that all of your files will match the contents ofHEAD
. - If you do a
reset --hard
to an earlier commit, such asgit reset --hard HEAD~3
, Git is removing changes from your working tree to match the state of the files from the earlier commit, and it’s changingHEAD
to reference that earlier commit. Similar to the previous point, all uncommitted changes to tracked files are undone.- Again, this is a destructive/dangerous way to do something like this and there is another way that is safer:
- Instead, perform a
git stash
followed bygit checkout -b new-branch HEAD~3
.- This will save, i.e. stash, your index and working tree changes, and then check out a new branch that references
HEAD
‘s great grandparent. git stash
saves your work in a stash that you can then apply to any branch you wish in the future; it is not branch specific.- Checking out a new branch to the older state allows you to maintain your previous branch and still make the changes you wanted on your new branch.
- This will save, i.e. stash, your index and working tree changes, and then check out a new branch that references
- Instead, perform a
- Again, this is a destructive/dangerous way to do something like this and there is another way that is safer:
- If you decide that you like what is in your new branch better than your old branch, you can run these commands:
git branch -D oldbranch
git branch -m newbranch oldbranch
- After learning all of this, the author’s recommendation is to always do the stashing/branch creation as it’s safer and there’s basically no real overhead to it.
- If you do accidentally blow away changes, the author mentions that you can do a restore from the reflog such as
git reset --hard HEAD@{1}
. - The author also recommends ALWAYS doing a
git stash
before doing agit reset --hard
- This allows you to do a
git stash apply
and recover anything you lost, i.e. nice backup plan.
- This allows you to do a
As mentioned previously, if you have other consumers of your branch/commits, you should be careful when making changes that modify history like this as it can force unexpected merges to happen to your consumers.
Stashing and the Reflog
- There are two new ways that blobs can make their way into the repository.
- The first is the
reflog
, a metadata repository that records everything you do in your repository.- So any time you make a commit in your repository, a commit is also being made to the
reflog
. - You can view the
reflog
withgit reflog
.
- So any time you make a commit in your repository, a commit is also being made to the
- The glorious thing about the
reflog
is even if you did something like agit reset
and blew away your changes, any changes previously committed would still exist in thereflog
for at least 30 days, before being garbage collected (assuming you don’t manually run garbage collection).- This allows you to recover a commit that you deleted in your repository.
- The first is the
- The other place that a blob can exist is in your working tree, albeit not directly noticeable.
- If you modified
foo.java
but you didn’t add it to the index, you can still see what the hash would be by runninggit hash-object foo.java
. - In this regard, the change exists on your filesystem instead of Git’s repository.
- If you modified
- The author recommends stashing any changes at the end of the day even if you’re not ready to add anything to your index or commit it.
- By doing so, Git will store all of your working tree changes and current index as the necessary trees and blobs in your git repository along with a couple of commits for storing the state of the working tree and index.
- The next day, you come back in, run a
git stash apply
and all of your changes are back in your working tree.- So why do that? You’re just back in the same state you were the night before, yeah? Well, except now those commits that happened due to the stash are something you can go back to in your
reflog
, in case of an emergency!
- So why do that? You’re just back in the same state you were the night before, yeah? Well, except now those commits that happened due to the stash are something you can go back to in your
- Another special thing, because stashes are stored as commits, you can interact with them just like any other branch, at any time!
git checkout -b temp stash@{32}
- In the above command, you can checkout a stash you did 32 days ago, assuming you were doing a single stash per day!
- If you want to cleanup your stash history, DO NOT USE
git stash clear
as it kills all yourstash
history.- Instead, use
git reflog expire --expire=30.days refs/stash
to let your stashes expire.
- Instead, use
- One last tip the author mentioned is you could even roll your own snapshot type command by simply doing a
git stash && git stash apply
.
Resources we Like
- Git from the Bottom Up by John Wiegley (jwiegley.github.io)
- To Reset or not to Reset (jwiegley.github.io)
- Stashing and the reflog (jwiegley.github.io)
- Git Garbage Collection Tutorial (Atlassian)
- The Pragmatic Programmer – How to Build Pragmatic Teams (Episode 114)
Tip of the Week
- A couple episodes back (episode 192), Allen mentioned Obsidian, a note taking app that operates on markdown files so you can use it offline if you want or you can keep the files in something like DropBox or pay a monthly fee for syncing. Good stuff, and if you ever want to leave the service … you have the markdown files! That’s an old tip, but Joe has been using it lately and wanted add a couple supplemental tips now that he’s gotten more experience with it.
- If Obsidian just manages markdown files, then why bother? Why not just use something like VSCode? Because, Obsidian is also a rich client that is designed to help you manage markdown with features built in for things like search, tags, cross-linking etc.
- Obsidian supports templates, so you can, for example, create a template for common activities … like if you keep a daily TODO list that has the same items on it every day, you can just
{{include}}
it to dump a copy of that checklist or whatever in. (help.obsidian.md) - Obsidian is designed to support multiple “vaults” up front. This lets you, for example, have one vault that you use for managing your personal life that you choose to sync to all of your devices, and one for work that is isolated in another location and doesn’t sync so you don’t have to worry about exfiltrating my work notes.
- Community extensions! People have written interesting extensions, like a Calendar View or a Kanban board, but ultimately they serialize down to markdown files so if the extension (for example) doesn’t work on mobile then you can still somewhat function.
- All of the files that Obsidian manages have to have a
.md
file extension. Joe wanted to store some.http
files in his vault because it’s easy to associate them with his notes, but he also wanted to be able to execute them using the REST Client extension … which assumes a.http
extension. The easiest solution Joe found was just to change the file type in the lower right hand corner in VSCode and it works great. This works for other extensions, too, of course! (GitHub)
- [Wireless] How to improve compatibility of IoT device with ASUS WiFi 6(AX) Router? (ASUS)
- Google’s new mesh Wi-Fi solution with support for Wi-Fi 6e is out, Google Nest Wifi Pro, and looks promising. (store.google.com)
- Terran Antipodes sent Allen a tip that we had to share, saying that you can place your lower lip between your teeth to hold back a sneeze. No need to bite down or anything, it just works! All without the worry of an aneurysm.