Git (10 blogmarks)

← Blogmarks

lucky-commit: Customize your git commit hashes!

https://github.com/not-an-aardvark/lucky-commit

A utility to quickly modify a git commit until the front of the hash achieves a desired sequence of characters.

Here’s the example they give:

$ git log
1f6383a Some commit
$ lucky_commit
$ git log
0000000 Some commit

Learned about this from this blog post.

Why some of us like "interdiff" code review systems (not GitHub)

https://gist.github.com/thoughtpolice/9c45287550a56b2047c6311fbadebed2

I learned about git’s range-diff from this article which is useful if you adopt this interdiff approach of evolving patch series. Rather than doing additive commits in response to reviews and CI feedback.

This is the essence of "interdiff code review." You

  • Don't publish new changes on top, you publish new versions
  • You don't diff between the base branch and the tip of the developer's branch, you diff between versions of commits
  • Now, reviewers get an incremental review process, while authors don't have to clutter the history with 30 "address review" noise commits.
  • Your basic diagnostic tools work better, with a better signal-to-noise ratio.

Flight rules for git

https://github.com/k88hudson/git-flight-rules

Flight Rules are the hard-earned body of knowledge recorded in manuals that list, step-by-step, what to do if X occurs, and why. Essentially, they are extremely detailed, scenario-specific standard operating procedures.

I’ve come across several comprehensive git resources and guides recently. In addition to this one:

Via: this Reddit response

Beej's Guide to Git

https://beej.us/guide/bggit/html/split/

I’m still exploring this. It’s always interesting to see the in-depth details of how someone thinks about using a tool like git.

When to use `--force-if-includes` with `git push`

https://stackoverflow.com/a/65839129/535590

Every once in a while I stumble upon a wildly-thorough 2000+ word answer on StackOverflow. Most blog posts aren't this long, let alone SO answers. This is one of those answers.

So, you can try it out by using it for all --force-with-lease pushes. All it does is use a different algorithm—one the Git folks are hoping will be more reliable, given the way humans are—to pick the hash ID for the atomic "swap out your branch name if this matches" operation that --force-with-lease uses. You can do this manually by providing the =<refname>:<hash> part of --force-with-lease, but the goal is to do it automatically, in a safer way than the current automatic way.

The tl;dr is that you probably don't need this flag, but since it is marginally safer than only the --force-with-lease flag, you might consider using both just in case.

I guess this is why oh-my-zsh makes it the default for gpf for qualifying versions of git:

| gpf   | On Git >= 2.30: git push --force-with-lease --force-if-includes
| gpf   | On Git < 2.30:  git push --force-with-lease

Git Pathspecs and How to Use Them

https://css-tricks.com/git-pathspecs-and-how-to-use-them/

Pathspecs are an integral part of many git commands, but their flexibility is not immediately accessible. By learning how to use wildcards and magic signatures you can multiply your command of the git command line.

I recently learned how to use a pathspec magic signature to exclude a directory from a git command.

$ git restore --patch -- . ':!spec/cassettes'

So, I was curious to learn more about this syntax, other magic signatures, and what all falls under the umbrella of a pathspec. I did some digging in the man pages and the main source of information I could find was a section on pathspec in the man gitglossary page. The descriptions here were fairly terse and didn't include examples.

Fortunately, Adam Giese wrote this excellent blog post on CSS Tricks covering the topic. It goes through everything from "what is a pathspec in its simplest form?" to "how to use the various magic signatures".

Here are two examples Adam gives of doing an exclude:

git grep 'foo' -- '*.js' ':(exclude)*.spec.js' # search .js files excluding .spec.js
git grep 'foo' -- '*.js' ':!*.spec.js' .       # shorthand for the same

And here is an example of combining several magic signatures:

git ls-files -- ':(top,icase,glob,attr:!vendored)src/components/*/*.jsx'

Adam also pulled this amazing line from the man gitglossary page:

Glob magic is incompatible with literal magic.

Git Pulled What???

https://frankwiles.com/posts/two-handy-git-aliases/

Usually when I'm doing a git command that involves a ref of the form @{1}, it is because I'm targeting a specific entry in the reflog that I want to restore my state to.

Frank points out another use for these right after pulling down the latest changes from a remote branch.

This will display all the commits that were pulled in from the latest pull (e.g. git pull --rebase):

$ git log @{1}..

And this will show a diff of all the changes between where you just were and what was just pulled in:

$ git diff @{1}..

One thing to keep in mind is to be sure that you are using @{1} immediately after you pull. Any other things you might do, such as changing branches, will put another entry on the reflog making @{1} no longer reference your pre-pull state.

In that case, you'd need to do git reflog and find what entry does correspond to right before you pulled.

A pitch for jujutsu

https://lobste.rs/s/ozgd5s/can_we_communally_deprecate_git_checkout#c_icfohk

jujutsu -- a version control system

I think what’s remarkable about Jujutsu is that it makes all those slightly exotic git workflows both normal and easy.

They go on to describe all these common git mechanics that jj makes more accessible.

Jujutsu simplifies the UX around those operations significantly, and makes some changes to the git model to make them more natural. Squash has its own command, splitting a commit into two is a first-class operation, rebase only does what the name suggests it should, and you can go back to any previous commit and edit it directly without any ceremony. Jujutsu also highlights the unique prefix of commit/change IDs in its UI, which is a small UI change but it makes it much easier to directly address change IDs because you only have to type a few characters instead of copying and pasting 40 characters. If you run into a conflict during any of these operations you don’t have to fix it right away like git: they sit in the history and you can deal with them however you want.

And a comment right below this points out that because of jj's interoperability with git, you can collocate to start using jj in an existing git project right away.

My only advice to someone truly curious about jj is to drop into any code base you’re familiar with, jj git init --colocate, and work for week only using jj. It won’t be painful. You’ll occasionally be unfamiliar with how to achieve some workflow with jj, but the docs are good and you’ll figure it out.

Git - Plumbing and Porcelain

https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain

I like this concept of Plumbing versus Porcelain CLI commands. I recently referenced it in Connect To Production Rails Console on AWS / Flightcontrol - Notes from VisualMode.

because Git was initially a toolkit for a version control system rather than a full user-friendly VCS, it has a number of subcommands that do low-level work and were designed to be chained together UNIX-style or called from scripts. These commands are generally referred to as Git’s “plumbing” commands, while the more user-friendly commands are called “porcelain” commands.