ALTERNATE UNIVERSE DEV

CodingBlocks

Git from the Bottom Up – Commits

We are committed to continuing our deep dive into Git from the Bottom Up by John Wiegley, while Allen puts too much thought into onions, Michael still doesn’t understand proper nouns, and Joe is out hat shopping.

The full show notes for this episode are available at https://www.codingblocks.net/episode192.

News

  • Thanks for the review Alex Woodhead!
  • Ludum Dare is a bi-annual game jam that’s been running for over 20 years now. Jam #51 is coming up Sept 30th to October 3rd. (ldjam.com)

Commitment Issues

Commits

  • A commit can have one or more parents.
    • Those commits can have one more parents.
    • It’s for this reason that commits can be treated like branches, because they know their entire lineage.
    • You can examine top level referenced commits with the following command: git branch -v.
  • A branch is just a named reference to a commit!
  • A branch and a tag both name a commit, with the exception that a tag can have a description, similar to a commit.
    • Branches are just names that point to a commit.
    • Tags have descriptions and point to a commit.
  • Knowing the above two points, you actually don’t technically need branches or tags. You could do everything pointing to the commit hash id’s if you were insane enough to do so.
  • Here’s a dangerous command:
    • git reset --hard commitHash – This is dangerous. --hard says to erase all changes in the working tree, whether they were registered for a check-in or not and reset HEAD to point to the commitHash.
  • Here’s a safer command:
    • git checkout commitHash – This is a safer option, because files changed in the working tree are preserved. However, adding the -f parameter acts similar as the previous command, except that it doesn’t change the branch’s HEAD, and instead only changes the working tree.
  • Some simple concepts to grasp:
    • If a commit has multiple parents, it’s a merge commit.
    • If a commit has multiple children, it represents the ancestor of a branch.
  • Simply put, Git is a collection of commits, each of which holds a tree which reference other trees and blobs, which store data.
    • All other things in Git are named concepts but they all boil down to the above statement.

A commit by any other name

  • The key to knowing Git is to truly understand commits.
  • Learning to name your commits is the way to mastering Git.
    • branchname – The name of a branch is an alias to the most recent commit on that branch.
    • tagname – Similar to the branch name in that the name points to a specific commit but the difference is a tag can never change the commit id it points to.
    • HEAD – The currently checked out commit. Checking out a specific commit takes you out of a “branch” and you are then in a “detached HEAD” state.
    • The 40 character hash id – A commit can always be referenced by the full SHA1 hash.
      • You can refer to a commit by a shorter version of the hash id, enough characters to make it unique, usually 6 or 7 characters is enough.
    • name^ – Using the caret tells Git to go to the parent of the provided commit. If a commit has more than one parent, the first one is chosen.
    • name^^ – Carets can be stacked, so doing two carets will give the parent of the parent of the provided commit.
    • name^2 – If a commit has multiple parents, you can choose which one to retrieve by using the caret followed by the number of the parent to retrieve. This is useful for things like merge commits.
    • name~10 – Same thing as using the commit plus 10 carets. It refers to the named commit’s 10th generation ancestor.
    • name:path – Used to reference a specific file in the commit’s content tree, excellent when you need to do things like compare file diffs in a merge, like: git diff HEAD^1:somefile HEAD^2:somefile.
    • name^{tree} – Reference the tree held by a commit rather than the commit itself.
    • name1..name2 – Get a range of commits reachable from name2 all the way back to, but not including, name1. Omitting name1 or name2 will substitute HEAD in the place.
    • name1…name2 – For commands like log, gets the unique commits that are referenced by name1 or name2. For commands like diff, the range is is between name2 and the common ancestor of name1 and name2.
    • main.. – Equivalent to main..HEAD and useful when comparing changes made in the current branch to the branch named main.
    • ..main – Equivalent to HEAD..main and useful for comparing changes since the last rebase or merge with the branch main, after fetching it.
    • -since=”2 weeks ago” – All commits from a certain relative date.
    • –until=”1 week ago” – All commits before a certain relative date.
    • –grep=pattern – All commits where the message meets a certain regex pattern.
    • –committer=pattern — Find all the commits where the committer matches a regex pattern.
    • –author=pattern – All commits whose author matches the pattern.
      • So how’s that different than the committer? “The author of a commit is the one who created the changes it represents. For local development this is always the same as the committer, but when patches are being sent by e-mail, the author and the committer usually differ.”
    • –no-merges – Only return commits with a single parent, i.e. ignore all merge commits.

Resources We Like

  • Git from the Bottom Up by John Wiegley (jwiegley.github.io)
  • TotW from the past:
    • Not sure where the history of your branch started from and want an easy button? Check out Allen’s TotW from episode 182.
    • Need to search the entire history of the repo for some content (text, code, etc.) that’s not part of the current branch? Content, not a commit comment, not a commit ID, but content. Check out Michael’s TotW from episode 31.
  • Nobody Likes Onions, a podcast that has been making audiences laugh at the absurd, the obvious, and the wrong, for a very long time. (NobodyLikesOnions.com)

Tip of the Week

  • Supabase is an open-source alternative to Google’s Firebase that is based on PostgreSQL. The docs are great and it’s really easy to work through the “Getting Started” guide to set up a new project in the top framework of your choice, complete with a (for now) free, hosted PostgreSQL database on Heroku, with authentication (email/password or a myriad of providers). RBAC is controlled via database policies and everything can be administered through the portal. You can query the database with a simple DSL. Joe was able to work through a small project and get it hosted on Netlify (with SSL!) all for free in under 2 hours. (supabase.com)
  • Obsidian is a really cool way to associate markdown data with your files. (Thanks Simon Barker!) (obsidian.md)
  • Ever use a “mind map” tool? MindNode is a great, free, mind mapping tool to help you organize your thoughts (Thanks Sean Martz!) (mindnode.com)
  • Ink Drop is a cool way to organize and search your markdown files (inkdrop.app) (Thanks Lars!)
  • Tired of git log knocking the rest of your content off screen? You can configure Git to run a custom “core.pager” command with the args you prefer: (serebrov.github.io)
    • To configure just Git: git config --global --replace-all core.pager "less -iXFR"
    • Or, to modify how less prints to the screen and commands that rely on it, including Git, edit your ~/.bashrc or ~/.zshrc, etc. and add export LESS=-iXFR to the file.

Episode source