I recommend to look into git log --help and git rev-list --help .
I just created 2 scripts to list commits from Git repositories. It’s more in the score of an alias actually, so nothing comprehensive here. If you have some one-liners, alias or scripts for commits listing, please share here. The link of this post goes to the git log documentation. I’ll share mine in the comments too rather than in the post.
git log -S'some_string' -pis the one that pays for itself. it finds the commits where that string was added or removed, so you can track down when a function disappeared without reading through history.-Gis the same idea with a regex, matching any changed line.and
git log --follow -p path/to/filekeeps going across renames, which plaingit log filewon’t do.I like this one :
git adogMagit: press
lin the Magit window.The grain truck collision that is the Git command line is still visible in everything Magit does, and I can learn a lot by dipping into that. But I don’t need to look up the commands or combine weirdly disjoint options; Magit has a coherent, superior porcelain.
i keep hearing “porcelain” but I don’t understand what it is. Would you care to explain?
The man page sheds a bit of light, but basically it the stuff on top of the core git functionality.
LOW-LEVEL COMMANDS (PLUMBING) Although Git includes its own porcelain layer, its low-level commands are sufficient to support development of alternative porcelains. Developers of such porcelains might start by reading about git-update-index(1) and git-read-tree(1). The interface (input, output, set of options and the semantics) to these low-level commands are meant to be a lot more stable than Porcelain level commands, because these commands are primarily for scripted use. The interface to Porcelain commands on the other hand are subject to change in order to improve the end user experience.Related, but not to be confused with the
--porcelainoption available for some git commands. Eg, from the man page forgit status:--porcelain[=<version>] Give the output in an easy-to-parse format for scripts. This is similar to the short output, but will remain stable across Git versions and regardless of user configuration. See below for details.Like it says, if you’re doing any kind of scripting this will remove weird escape codes to make parsing the output easier.
ah I got it thanks. Porcelain is a pretty confusing term
Interesting. So this is an Emacs extension it seems. Are the Git commands it produces usable outside Emacs?
So this is an Emacs extension it seems.
That’s right. I have taught many people to use Magit, who have then loved it so much they go on to learn Emacs :-)
Are the Git commands it produces usable outside Emacs?
Yes, Magit is a porcelain to Git, meaning that Magit uses Git commands as its internal plumbing. Any option you select is shown (de-emphasised) as the corresponding Git command-line option; and any operation Magit does, you can optionally pull up the window where it’s running the Git commands.
This is a very good way to learn Git! The Magit interface is highly coherent and comprehensive, so it’s relatively easy to discover what you can do; and then you (optionally) look behind the scenes while it does it.
None of this saves you from the burden of learning the mental model of how a Git repository operates. But at least you can learn that after getting your work done, by asking “okay and how did happen?”.
who have then loved it so much they go on to learn Emacs :-)
Unfortunately I’m an evil Vim user. As for me, I’m not afraid of reading documentation and help texts. And in fact I love writing scripts and chain commands. But I’m at least always open to see what others do and use.
cat .local/bin/git-lastblame#!/usr/bin/env bash #Show when <paths> were last committed, with date, author and commit title paths=("$@") if ((${#paths[@]} == 0)); then paths=(".") fi while IFS=$'\t' read -r hash file; do git log -n1 --pretty=format:"%h:%Cblue%as%Creset %Cgreen%an%Creset %Cblue$file:%Creset%s" --no-patch $hash done < <(git last-modified ${paths[@]})By default it will show all the files in your current directory. I like it to get an idea of of the lifecycle of one area of a project. Files will be listed ordered by most recent commit. Note that it’s not very fast so it’ll probably choke on big repos. Alias as
g lb- press few key.This is an interesting one. But there is probably a better way instead running a Git command for every single file.
You’re absolutely right. Here’s a slopcoded rewrite that does run a ton faster and doesn’t use
git last-modified(which is labelled experimental but was kind of the original inspiration). I even got it to do relative filenames instead of the full path to the root of the repo which I had been wanting.cat .local/bin/git-slopblame#!/usr/bin/env bash # Show when <paths> were last committed, with date, author and commit title paths=("$@") if ((${#paths[@]} == 0)); then paths=(".") fi git log --format='@@@%h%x09%as%x09%an%x09%s' --relative --name-only -- "${paths[@]}" | awk '/^@@@/ { commit = substr($0, 4) next } length($0) && !seen[$0]++ { print commit "\t" $0 }' | while IFS=$'\t' read -r hash date author subject file; do printf '%s:\033[34m%s\033[0m \033[32m%s\033[0m \033[34m%s:\033[0m%s\n' \ "$hash" "$date" "$author" "$file" "$subject" done
I normally dislike aliases but this one I can’t live without:
alias.lg=log --graph --date=iso-local --pretty=format:'%Cred%h%Creset - %cn:%C(auto)%d%Creset %s %Cgreen(%cd)%Creset' --abbrev-commithttps://gist.github.com/thingsiplay/9ad7df1d743a5dafa4bef489801503f6
gitlog:#!/usr/bin/env bash # List Git log messages by tag or commit range. Defaults to HEAD. # gitlog [from] [to] # # from and to can be a tag or commit id: # gitlog v1.22.2 # gitlog 281b532 # gitlog 281b532 b0353a6 from="HEAD" to="HEAD" if [[ $# -ge 1 ]]; then from="${1-HEAD}" shift fi if [[ $# -ge 2 ]]; then to="${1-HEAD}" shift fi format="(%cr) %s" git --no-pager \ log \ --oneline \ --decorate=no \ --date=short \ --abbrev-commit \ --pretty=tformat:"${format}" \ "${from}^..${to}^" \ origin/master "${@}"gitlogdate:#!/usr/bin/env bash # List Git log messages since date. Defaults to today. # gitlog [date] # # date can be a specific date %yyyy-%mm-%dd or description: # gitlogdate 2026-11-03 # gitlogdate yesterday # gitlogdate 3 weeks ago date="today" if [[ $# -gt 0 ]]; then date="${*-today}" fi format="%h %ad %s" git --no-pager \ log \ --oneline \ --decorate=no \ --date=short \ --abbrev-commit \ --pretty=tformat:"${format}" \ --since-as-filter="${date}" \ origin/master






