Skip to content(if available)orjump to list(if available)

How Core Git Developers Configure Git

How Core Git Developers Configure Git

128 comments

·February 25, 2025

jelder

My favorite alias is `git out`, which just lists all unpushed commits. I use it all the time.

  [alias]
    out = "log @{u}.."
In my head I always hear it in the voice of The Terminator: https://youtu.be/8cdC1Y5oRFg?t=54

schacon

I should do another article on the best aliases, because this is a great one. I want it just because I want to do the Arnold voice every time.

Now I want to do: `git to-da-choppa`

theshrike79

That could be just

  git add . && git commit -a -m "git to da choppa" && git push --force
For when you need to Get to da choppa and don't have time to clean up =)

sandreas

I use `qp`for `quick-push` with a function to provide a comment:

  # git alias
  qp = "!f() { git add . && git commit -m \"$1\" && git push; }; f"


  # usage
  git qp "whatever your comment is"

sedatk

That comes out of the box with Mercurial. (`hg out` or `hg outgoing`).

_kb

While everyone is here considering their life choices (at least as far as they relate to ~/.gitconfig), highly recommend delta [1] as a companion to the git cli.

[1]: https://dandavison.github.io/delta/

leonheld

After using delta for a while, I'm going back to the regular diff view... it's not that it isn't good, but I'm constantly copying diffs (yes, I know I can generate patches) and the pretty output breaks that workflow.

Also, when your terminal is a bit small it's a bit hard to see things. But it's really good software, I recommend anyone who's reading to give it a try.

JadedBlueEyes

IIRC if you pipe the output to, e.g, xclip, or redirect to a file it will give the original diff format. Not as convenient, but still workable.

leonheld

I... did not know that! Yep yep that should do the trick for me. Thanks a lot, actually!

pca006132

Wow I never knew this, I always just type `--no-ext-diff` when piping the output. Thanks!

rusk

Pipe through cat should work

PhilippGille

Isn't copying without the formatting just a `<your diff command> | pbcopy` away?

genewitch

I have Gemini set to decipher HN comments that I don't immediately understand. This is a macos only command `pbcopy`?

Aside: Gemini mentioned it didn't want me to ask it questions about bikeshedding what shade of blue on a website header so I think it's got our number.

mplanchard

If you’re an emacser, you can even use delta with magit via the same author’s magit-delta package: https://github.com/dandavison/magit-delta

Looks like there are also instructions in the docs for using it with vscode

schacon

I really wanted to add this (I linked it in the last paragraph) but I really wanted to keep the recommendations globally applicable in vanilla git. Delta is awesome though.

chungy

My own ~/.gitconfig looks like this:

    [alias]
     co = checkout
     ci = commit
     st = status
     br = branch
     hist = log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short
     type = cat-file -t
     dump = cat-file -p
     dft = difftool
    [tag]
     sort = version:refname
    [tar "tar.xz"]
     command = xz -c
    [tar "tar.zst"]
     command = zstd -T0 -c
    [log]
     date = iso-local
    [pull]
     ff = only
    [diff]
     tool = difftastic
    [safe]
     directory = *
    [advice]
     detachedHead = false
    [init]
     defaultBranch = master

gosub100

Do your aliases even save you any keystrokes? Most shells support auto complete, and you still have to type "git" unless you have a shell alias for it.

I guess what I'm git-ing at is a truly efficient alias would be embedded in the shell. For a while I had "gsno = git status --uno" although it's been so long since I used it, I forget what the options even did. Somehow I get by with only stock commands.

Another helpful alias I used to use was ctrl-space, I had aliased for 'make'. Somehow I liked it because you can almost gesture it with slamming both hands down simultaneously.

cillian64

I have a load of these shell aliases as I spend a frankly ridiculous amount of time messing with git. `g` is `git status`, `d` is `git diff`, `gad` is `git add`, `ds` is `git diff --staged`, `gg` is `git grep`, `gbv` is `git branch -va`

chungy

Shortened aliases come from cvs/svn land, sorting tags by a logical manner, adding some extra archive types for "git archive", making it so git log always shows my local time zone, pull will never do a non-ff merge, make it so Git doesn't complain about repositories in places it doesn't like, turning off an annoying message about a detached HEAD state, and shut git up about the default branch.

schacon

Yeah, I didn't do aliases on purpose, because I wanted everything to be fairly global, where I feel like aliases are more personal. But yes, aliases are great.

feelamee

as for me, I want something more. Like git shell. Where I no need to write git, git, git again and again. Strange that there is no something like this yet.

tome

I agree with the recommendation to use (z)diff3. I think the article massively understates the case! Three way diff makes it possible to resolve some conflicts that are literally impossible to resolve without it. Why impossible? Because with default style adding conflicting things at the same place is indistinguishable from removing the same things at the same place. You need to be able to see the base to determine that.

I wrote up more here: https://stackoverflow.com/a/63739655/997606

I also wrote up how to use diff3 style to make resolving rebase (or merge) conflicts a mechanical procedure: https://h2.jaguarpaw.co.uk/posts/git-rebase-conflicts/

conaclos

Some extra options I like:

  [apply]
    # Remove trailing whitespaces
    whitespace = fix
  [color "diff"]
    whitespace = red reverse
  [diff]
    colorMovedWS = allow-indentation-change
  [format]
    pretty = fuller
  [log]
    date = iso
  [pull]
    ff = only

schacon

I did almost put `log.date iso` in there, I like that one too.

opello

I also use that color.diff.whitespace "red reverse" and along with it diff.wsErrorHighlight all. I recall needing to set both in the past but in trying to find out why that might have been superseded by only needing the latter. I'm not quite sure.

qbonnard

Related: Popular Git config options by Julia Evans [0]

[0] https://news.ycombinator.com/item?id=39400352

JulianWasTaken

Mine is here [1], I basically had all of these set already (other than column ui which I don't like), but I suspect that's just because I've probably previously read nice posts by Scott and others talking about them.

Maybe trading alias tips is another useful thing to do though, hence sharing the link.

[1]: https://github.com/Julian/dotfiles/blob/main/.config/git/con...

sandreas

I wonder why commit signing is not part of these configs... it is pretty easy to do with a modern ssh key:

  [user]
    name = xyz
    email = xyz@domain.com
    signingkey = ~/.ssh/id_algorithm.pub
  
  [commit]
    gpgsign = true
  [tag]
    gpgsign = true

  [gpg]
    format = ssh

  # restrict allowed signers
  # echo "$(git config --get user.email) namespaces=\"git\" $(cat ~/.ssh/id_*.pub)" >> ~/.git_allowed_signers
  [gpg "ssh"]
    allowedSignersFile = ~/git_allowed_signers  

On github you can add the ssh key for authentication but also for signing. Unfortunately you have to add the key twice but once you've done it, you get rid of the `unverified` label within a commit.

ajross

> Personally, I think the default behavior of Git should be to make your remote references as close to what is on the remote as possible. Prune stuff that’s gone, etc.

Yikes, no. Remote junk disappears all the time, and you never know when you'll have to recover something. Old versions of GitHub pull requests, in particular, tend to be garbage collected at the backend rapidly. It's a semi-regular occurrence for me that I have to dig through reflog to get to early work that everything else has forgotten about.

Just in general, don't delete stuff you don't know you don't need. That's just data robustness 101. nothing to do with git. Deletions should be as manual as possible, and generally done following a backup.

cassepipe

I discovered that you can have git use the pager you like so I set it to my darling : bat

    git config --global core.pager bat
https://github.com/sharkdp/bat/

lucasoshiro

You can also do that with delta (https://github.com/dandavison/delta), with additional options that you can put on your .gitconfig

oneeyedpigeon

Is there an advantage to doing this over setting the GIT_PAGER environment variable?

(Weirdly, git doesn't seem to honour the PAGER var (which would be even better), although its man page claims it does)

lucasoshiro

I never used that env variable, but, an advantage is that you can put all your git configs in one file and reuse it across different machines, just like any dotfile.

If you use --local instead of --global, you can configure just for the current repository, useful if may find that delta is or isn't the best choice just for that repository

Maledictus

Less env pollution.

betimsl

It just makes everything perfect.

rowanseymour

I really wish they'd update the default config once there's consensus that something new is optimal. I'm wary of even adding the config settings in this article in case things change in the future and I continue oblivious with a now dated setup.

neals

How much of this is for a noob like me that just uses vscode? I hardly ever see the git command line, and when I do see it, its trouble beyond what anybody can fix...

juancroldan

VSCode git interface is actually pretty powerful, 99.9% of the git actions I do are already covered there, including merging, stashing, tagging, getting output from the git hooks...

However changing the diff algorithm is still a nice one, both for solving conflicts and to avoid the ocassional bad automated merges (the latter is scarier as you don't even know you pushed something wrong).

lucasoshiro

I wouldn't like to be this kind of person, but, in the case of git, the best you can do you is forcing yourself little by little to use the Git CLI. It's far from being beginner friendly, but it shows the things the way the really are. GUI git tools hide things under their hood, which is ok for most cases but when you need a little more complex thing you are limited to their capabilities.

For instance, I wrote this post last year about how you can use Git as a powerful debugging tool: https://news.ycombinator.com/item?id=39877637

jbverschoor

Nothing wrong with a gui. Esp with git imo. The process doesn’t require blazing fast agility, but careful review and selection.

Graphical diff viewers are way better anyway.

pfg_

Setting merge conflictstyle diff3 or zdiff3 will improve your experience if you ever do any merging

vlovich123

I just use kdiff3 - automatically solves most merge conflicts & it’s rarely to never done so incorrectly. And when it can’t resolve the merge conflicts, line alignment is very nice. I prefer it to the cluttered experience of BeyondCompare and other more “feature-filled” options.

jeffwass

Of course, there's an xkcd for that : https://xkcd.com/1597/

eastbound

Should create an XKCD with “There is always n+1 Git client GUI”.

EVERY new employee arrives saying “Hey I’ve found this great UI for git, this one really nails it and makes git easy” and every time it’s a new Git UI that I’ve never heard of. It’s the “hello world” of startups: Creat their great git UI and publish it.

Then they commit with the default crappy commit messages and they don’t know how to git-rebase-i.

tex0

Maybe git is just too complicated for average users (myself included).

null

[deleted]

schacon

Of course, you can also try GitButler (https://gitbutler.com), it's a pretty nice GUI :)