How Core Git Developers Configure Git(blog.gitbutler.com) |
How Core Git Developers Configure Git(blog.gitbutler.com) |
If these options clearly make git better, why aren't they the defaults?
My config if you'd like to steal it, also here: https://github.com/silvanocerza/dotfiles/blob/master/git/git...
Mind that you need diff-so-fancy for this work correctly. https://github.com/so-fancy/diff-so-fancy
[alias]
co = checkout
ci = commit
cl = clone
st = status
f = fetch
br = branch
lg = log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) %C(bold green)(%ar)%C(reset) %C(yellow)- %an%C(reset)%C(auto)%d%C(reset)%n" "%C(white)%s%C(reset)' --all
lgg = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
type = cat-file -t
dump = cat-file -p
# Lists all local branches that have been deleted on remote
gone = ! "git for-each-ref --format '%(refname:short) %(upstream:track)' | awk '$2 == \"[gone]\" {print $1}' | xargs git branch -D"
[color]
ui = true
[push]
default = simple
[merge]
tool = meld
conflictStyle = zdiff3
[diff]
algorithm = histogram
colorMoved = dimmed-zebra
colorMovedWS = no
mnemonicPrefix = true
renames = true
[rerere]
enabled = true
[pager]
branch = false
[core]
pager = diff-so-fancy | less --tabs=4 -RFX
fsmonitor = true
untrackedCache = true
[color "diff-highlight"]
oldNormal = red bold
oldHighlight = red bold 52
newNormal = bold
newHighlight = green bold 22
[color "diff"]
meta = yellow
frag = magenta bold
commit = yellow bold
old = red bold
new = green bold
whitespace = red reverse
[diff-so-fancy]
markEmptyLines = false
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
required = true
[pull]
rebase = false
[init]
defaultBranch = main
[column]
ui = auto
[branch]
sort = -committerdate
[commit]
verbose = true> Personally, I don’t have a problem with master
> updating the default value. I wish Git had some taste here, but they don't
So author has no preference, but git does not have a good taste here, for not breaking backward compatibility. Typical passive agresive bullshit!
I think "main" is not inclusive enough, we should use something like "non-specific-but-strong-branch". Or something that includes even stronger message. And change it every year (or month). It could be automated using github actions on all existing repos!
Also please rename "git" command, it is very insensitive word!!!
Sometimes a repo uses “main” and sometimes “master”. It’s not like “master” was the only option before
I do care if someone tries to push this stuff onto me. Changes in Git defaults would break 20 years of compatibility! It is bloody important in Linux development!
And I find it very moronic, that someone who writes "git" on every second line, complains "master" was not renamed.
It's not really a major issue, but the way this "problem" was created and then forced onto the rest of us by someone with very strong opinions — but zero actual technical accomplishments in git development — is annoying, that's all. And it keeps reminding you of itself — see the first paragraph.
So, if you have a git mirror in a private location that you need to push to, you get royally fucked in the arse by every project deciding to change their value for HEAD. These people basically broke 'git push' for my usecase.
So either they fix 'git push' to update the symrefs as well or shut up about using anything else than 'master'.
Is the expected behavior when a remote changes its HEAD seriously just to break when you try to push?
You can't propagate (push/fetch will FAIL) a branch deletion to a repository if that branch is still referenced in the HEAD, and attempting to clone a repository where this has been forced will leave you in an empty directory with no checkout. This is the expected failure mode for all clones when a project changes to main and deletes master.
This is not specific to the main/master thing, it has always been a big pain, but with the main/master thing people started en masse to do it without technical necessity.
And there's a whole new breed of programmers out there who feel offended on behalf of others about renaming versus not renaming, for example, the word "robot" comes from slave in Slavic languages and it should be banned, etc.
I somewhat agree with either banning all potentially offensive words or none at all, so let's go with none? Otherwise git is now simply gatekeeping offensiveness, and that's absurd.
I assume many people, like me, would have git aliases which use a hardcoded master branch name. I several of these aliases. I've had to update them all to check what the actual master/main name is and use that instead, because our org started following the "main" naming convention and we ended up with various repos with "master" and others with "main".
I personally like standardisation, because I prefer to spend time thinking about more important things. So I was mildly (but only mildly) peeved when I had to start thinking about which repo I was on and what the "master" branch was called.
But I've updated all my aliases now, so not so much of an issue.
[alias]
out = "log @{u}.."
In my head I always hear it in the voice of The Terminator: https://youtu.be/8cdC1Y5oRFg?t=54Now I want to do: `git to-da-choppa`
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 =)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.
Looks like there are also instructions in the docs for using it with vscode
[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 = masterI 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.
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/
[apply]
# Remove trailing whitespaces
whitespace = fix
[color "diff"]
whitespace = red reverse
[diff]
colorMovedWS = allow-indentation-change
[format]
pretty = fuller
[log]
date = iso
[pull]
ff = onlyMaybe 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...
[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.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.
git config --global core.pager bat
https://github.com/sharkdp/bat/(Weirdly, git doesn't seem to honour the PAGER var (which would be even better), although its man page claims it does)
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
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).
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
Graphical diff viewers are way better anyway.
[alias]
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --branches
It shows a coincise colored graph of your commits and branches. git push --force-with-lease
Forces pushes are dangerous enough as it is, so I'm mystified on why git doesn't insist you know the state of upstream before running it.Sadly you can't make it the default, so I resort to:
[alias]
force-push = push --force-with-lease
As for the article, I must the the weird one because I prefer most of the settings are they are or don't care. Even some of those designated as "clearly better" don't look to me.I also discovered `fetch.prune` and `pull.autoSetupRemote` which will slightly enhance my workflow.
My only disagreement is with the diff prefixes. I prefer to display one path starting with ".", so that I can double-click it and paste it. So I don't want contextual prefixes, I'll keep my `diff.dstPrefix = ./`.
> [...]
> [push]
> autoSetupRemote = true
I strongly disagree. Publishing a new branch on the remote should be an explicit operation. And git push will already tell you the command you need to run so it isn't an issue with having to remember another random command.
The diff changes are awesome, and I always wondered why there isn't a global .gitignore file in the first place, seeing that every .gitignore file basically has (mostly) the same content
There's also a possible downside here in having things hidden for you but not for others since it's not in your `.gitignore` project file.
I'm honestly kind of on the fence about this one, I don't have much in that file for those reasons.
I think it's the most readable and understandable diff.
* https://github.com/so-fancy/diff-so-fancy
* https://github.com/dandavison/delta
Also both great TUI diff tools
Very useful if you want to add your own .envrc or shell.nix to a repo.
It's shorter, sounds nicer.
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.
# git alias
qp = "!f() { git add . && git commit -m \"$1\" && git push; }; f"
# usage
git qp "whatever your comment is"Then use the vscode wrapper, or whatever you choose.
People complain that "git" is complicated when what is really happening is that they're looking at a revision management problem like a merge conflict or regression bisection, or having to split/refactor a giant blob of changes as demanded by an upstream project, etc...
Those tasks are complicated, necessarily. And git is a tool for doing them. But people tend to get confused about this and blame the tool and not the problem. But a better UI isn't going to make that split not suck.
I find it annoying to have those folders on my machine, that I don't need, but yet are checked into the git tree, so I basically cannot delete them, without affecting another person, when they pull my changes. Why you check that in bro??? Ugh.
I don't check in my Emacs backup files and shit either. I would like to aee their long faces, when faced with all of the files and folders other tools leave behind. People just aren't capable to configure their editors properly I guess and therefore rely on local config for things that could be global config or in a ".editorconfig", like for example trimming trailing whitespace.
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.
On windows, powershell has Get-Clipboard and Set-Clipboard, and cmd.exe has `wsl` to fix the issue of having used cmd.exe to begin with.
Some examples that I can think of off the top of my head (in addition to git) are ripgrep and jq, both of which do the right thing and strip formatting.
Yes, if those files apply to all team members using the same tool absolutely check them in. What's the problem? It reads to me like maybe you don't know what these files are actually used for and why a team benefits from sharing them.