My favorite line in my .gitconfig is an alias that prints out the commit history as a tidy graph. (The default `git log --graph` uses 6 whole lines per commit!)
You just gave me a lesson "why one should not just paste things he found online into his terminal".
Your parameters have Em dash instead of a hyphen... I reinstalled git from dedicated official repositories before I realized my git is not old... the param is indeed incorrect.
Good list, definitely concur with the top ones and can't think of anything major to me that's not listed.
rebase.autosquash combined with an alias I have (called 'fixup') to make that commit and then do the rebase is probably my top one by an absolute long shot, at least in terms of frequency of use. pull.rebase is important to me, but I fixup so frequently, I really don't know how people get by without it.
(Well, I do, generally they create a snaking history by merging master or whatever into their own branch repeatedly, swapping the parents, and make lots of new commits to fix things in the old ones. But I don't know how you can put up with doing that to yourself, is I suppose the long version of what I mean.)
Oh - semi-missed - insteadOf is more useful than implied: I have 'gh:' mapped to the full thing, so I just `git remote add somefork gh:someforker/the-project`, for example.
Some other minor ones: advice.statusHints=false; include.path (if you need it you need it - I use it to set my signing key according to which Yubikey is plugged in, plugging can write the whole file because it's all that's in there, no parsing required); remote "origin".fetch set to get PRs; oh and interactive.singleKey = true if that was missed - not a minor one at all! Makes staging changes so much faster and easier. Obviously not as fast as `add .` or `commit -a`, but don't do that.
True. If I'm only using it for git though makes sense to keep the config there IMO. But certainly that's handy when you're sshing interactively or doing other things with that host.
If you've evolved an SSO solution from brownfield, or just merged with another company you can easily end up in a spot where you have 2 user names across the systems, and that's before you get into doing things like pushing bug fixes to Github straight from your work machine.
Make yourself an .ssh/config file. Set your user, and your ssh key for where it matters (I don't use the same key for ssh to servers and for talking to github or bitbucket)
> Make yourself an .ssh/config file. Set your user, and your ssh key for where it matters (I don't use the same key for ssh to servers and for talking to github or bitbucket)
Another good setting for your ssh config if you use different keys for different servers is to require passing a key for all hosts rather than it trying each of your keys to see which one works:
I really loved the idea of fixup + rebase, but of course we didn't have an example here :)
So I spend half an hour to learn about git shell commands in aliases (had to learn the hardware that arguments require functions) and came up with the following.
No, I'm not a fan of it. It's been master since forever and it's a perfectly good term, fits regular English convention of "master branch" too.
> Personally, I use diff configs depending on oss vs personal vs work. So I combine mine with “[includeIf gitdir:~/oss…]” …
I'd stuff such things into the local repos' .git/config files instead of the global. It's rare that I do it, but sometimes I do work with projects with differing conventions.
Typing 'ma<Tab>' is the same in both cases. I don't like the change because the reason behind the change is political. Give an inch take a mile etc, it's getting out of hand. But I don't care enough to stand out.
Never used Mercurial in any serious capacity. The abbreviations mostly stem from CVS and Subversion experience (and really glad I haven't touched either in many years).
For the "I want to use different emails for different repos" issue, I've seen the `includeIf` technique but it felt fiddly. What I've done is set `user.useConfigOnly = true` and commented out `user.email` in ~/.gitconfig.
Now the first time I commit in a new repo, it errors out with "Author identity unknown" and I punch in "git config user.email ADDR" for the email I want to use and re-run the commit.
I also don't like the `includeIf`, but I ended up with a completely different way of doing things.
I just use different accounts depending on the context, usually by either SSH or by starting a Docker container with all the environment already configured.
At least for me, using different identities[1] when I want to use different identities[2], seems less brittle and less likely for my future self to accidentally forget to do something (e.g. change a config when I reinstall an OS).
[1]: OS user, directly (SSH) or indirectly (container).
I occasionally clone repos into /tmp for some small tweaks without switching branches or whatever, and that’s usually when I commit with the wrong email. Neither includeIf nor useConfigOnly are ideal in this scenario because a) it’s cloned in a generic location that can’t be differentiated using path-based includeIf, or b) manually setting it multiple times for the same repo is even more annoying.
I’ve tried conditionally setting email based on the remote [1], but for some reason I did not manage to make it work. I didn’t try too hard, and I might try again with more patience.
Sometimes, from my personal machine, I need to check something work-related ; then on my personal machine, I checkout in `~/dev/myorganization/`.
Inversely, it happens sometimes that at work I need something I wrote for myself ; then on my work machine, I checkout in `~/dev/myusername/`.
This allows me to use `gitdir:` rules that handle anything `~/dev`, and I have fallbacks for everything else (who never checkouts in `tmp`?).
#
# Superman vs Clark Kent
#
# Debug Includes with: git config --list --show-origin
# the default identity, for checkouts outside of `~/dev`
[include]
path = ~/.config/git/gitconfig-default
# on my work machine, this defines Clark Kent ; on my personal machine, this defines Superman (or is it the reverse?)
# this one is not commited in my dotfiles
[include]
path = ~/.config/git/gitconfig-local
# work-related repos on personal machine
[includeIf "gitdir:/home/myusername/dev/myorganization/"]
path = ~/.config/git/gitconfig-myorganization
[includeIf "gitdir:/home/myusername/dev/gitlab.com/myorganization/"]
path = ~/.config/git/gitconfig-myorganization
# personal repos on my work machine
[includeIf "gitdir:/home/myusername/dev/myusername/"]
path = ~/.config/git/gitconfig-myusername
[includeIf "gitdir:/home/myusername/dev/gitlab.com/myusername-namespace/"]
path = ~/.config/git/gitconfig-myusername
This works nicely since years^W `includeIf` was a thing.
However, there are situations at work where I'm on a server where I didn't created `~/.config/git/gitconfig-local` (which is a manual step I always forget) and any commit from `/usr/local/src/something/` will end up configured with Superman identity.
I found out about `hasconfig:` some time ago, and took note of it for when the option would hit `git` from Debian Stable ; your comment comes the day after I accidentaly commited as Superman on some work repo checked outside of `~/dev/`. Time to add more rules!
One git option that I almost never see in other people configs is
[core]
autocrlf = input
safecrlf = true
It prevents commiting CRLF files and forces you to convert those to LF before commit (you can still override it with gitattributes if necessary). I hate CRLF so much that I spent lots of time digging out this combination of configuration values.
Oh that's great. I always used the following `.gitattributes`:
# Enforce `lf` for text files (even on Windows)
* text=auto eol=lf
I'll try your config too.
My current position is that anywhere you can choose between CRLF and LF (git, editor, program output), it should always be LF regardless of the platform. Simple LF just works on Windows, and removing this variation point simplifies so much of code. For example, you can check reproducible outputs or hashing with a single reference value.
My personal favorite additions to my git config are using delta[1] as my pager for much more readable and syntax highlighted diffs. And adding the following alias, which means I no can always check out to the default branch of the repo, no matter if it's called master/main/develop/whatever
IMO, git needs to change the default for merge.conflictstyle. The default "merge" style is abysmal, it does not give you enough information to correctly resolve conflicts in isolation -- you have to actually look up the changes separately to understand what each was doing. diff3 gives you sufficient information so you don't have to look up anything. I haven't tried the enhanced versions like kdiff3 or zdiff3 or whatever, it sounds like they may be marginally better, but the difference between the default and diff3 is night and day.
I've seen so many new engineers struggle for years not being able to figure out conflicts until someone tells them about diff3. The default here has likely wasted millions of dollars of productivity.
Those merge tools typically take the raw conflict markers as input, and cannot give you as nice of a UI if they are two-way markers instead of 3-way. So you still want to change the default conflict style.
Parent comment is saying that the merge tool is not going to be able to interpret the conflicts in the file without having diff3 configured as the marker format.
Fine. But if someone knows to use mergetool, they probably don't have a problem to begin with. My concern is for all of the junior developers out there who are getting conflicts with terrible default conflict marker style and are struggling through it because they didn't know there was a better option. Educating everyone on how to use `git mergetool` would be great but it is hard. Changing the default so that conflict markers is understandable is easy and benefits everyone.
pull.ff only should have been the default option, or at least pull.rebase true. I've helped so many git newbie at work and this is probably the thing that caused the most confusion to people. The merge commit resulted from the default pull behavior caused nothing but pain.
The fundamental thing people fail to understand is the distributed nature of git. They don't understand that their master branch is not the same as your master branch, which isn't the same as GitHub's master branch etc. In fact, every time you clone you are also making a new branch!
The default behaviour of pull makes complete sense in the distributed system. It goes wrong when developers are also pushing to remotes and doing feature branches and the like. I love forges like GitHub, but I understood git first. Developers nowadays are using a decentralised version control tool to do centralised version control. No wonder it goes wrong.
I switched to trunk back when the witch hunt started raging. Fossil uses it, it's the original[0] term, and it completes the metaphor. What do the branches branch off? Why the trunk, of course.
As a matter of policy, I refuse to be swayed by the opinions of busybodies as to what is or isn't offensive. I will continue to use blacklists, for example, but am happy to retire the master/slave pairing: it's not a great metaphor to begin with, and a reasonable person can see where those of recent descent from the enslaved might take exception to it.
There's nothing at all wrong with having a master branch, either, the metaphor is entirely anodyne and no honest person takes umbrage at it. But that whole absurd episode got me thinking about the nomenclature, I had been working with Fossil on a hobby project shortly before, and figured that if there's another word which I prefer, I may as well take the opportunity to switch.
>I switched to trunk back when the witch hunt started raging.
>As a matter of policy, I refuse to be swayed by the opinions of busybodies as to what is or isn't offensive.
Well, you have said multiple ways that you have been swayed. I agree with you about all of this whining and word-policing coming from people who have dubious intentions. Nobody sane is offended by these terms. It's just a way for "victims" to seek clout and bully everyone else.
Fossil is cool but alas it will never be mainstream. It does have some nice features, but there are technical downsides such as storing files in a single binary sqlite database (which is a benefit for small projects, but a bad solution for large projects). If nothing else, backing up Fossil repos will take an ever-increasing amount of space compared to an equivalent git repo, as git repos can be backed up incrementally.
> Well, you have said multiple ways that you have been swayed.
I tried to address this in my first post, but don't mind elaborating.
I think trunk is the better term. I felt that way before all the absurdity surrounding master branches, but not so strongly that it had even occurred to me to set it as a git default and migrate my projects to use it. The sick power games of moral busybodies were causal in the sense that it started "a conversation" (ugh) about branch naming, with the result that I now use trunk on my own projects.
If I had stuck with master despite preferring trunk, just to show them what's what, that is also being swayed by the opinions of busybodies, just in the other direction. The busybodies of the world also want me to wear a seatbelt, after all. We have a confluence of wants there.
Similar deal with referring to various software components as slaves. I find that distasteful. I didn't need the language police to raise that topic to have that opinion. It's not even a good metaphor! Should I insist on using it just because the people who throw a hissyfit about blacklists share my dislike for that terminology? That is also being swayed by their opinions.
Anyway:
> Fossil is cool but alas it will never be mainstream.
Indeed, a nice bit of software, pleasure to work with. Rather too narrowly tuned to D. Richard Hipp's needs to be mainstream. I proposed on the Fossil mailiing list (right before they shipped a built-in forum) to separate the core features into a libfossil so people could use it as a component of other systems, but for a few reasons (which I found persuasive fwiw) they don't plan to do so.
I would still like to see pijul displace git, but as the years pass the odds of that steadily decrease. Ah well.
I used to find git slightly confusing as well, but it just takes a bit of patience to learn. The last thing we need is a dozen roughly-equivalent VCS tools to worry about, so I'm sticking with git. People can come up with aliases or something for people who don't get it.
>If I had stuck with master despite preferring trunk, just to show them what's what, that is also being swayed by the opinions of busybodies, just in the other direction.
This is pretty subtle. I would discourage the use of unconventional names for your branches, just because it creates more confusion. Were you influenced if you kept things the same because you didn't like the idea of change or the messengers asking you to do it? I guess technically, you could be psychologically influenced and not make any actual change. But to other people, your state of mind is not the object of interest, especially if it produces no outcome. They only care if you made the change or not. Thus, if you were not persuaded to change anything, then you weren't influenced.
>Similar deal with referring to various software components as slaves. [...] It's not even a good metaphor!
It is a good metaphor in fact. Slaves are workers that take assignments from their owner (and not others), among other things. At least in some contexts, you could list several things that a master/supervisor does that directly mirror how human slaves operate. If it was a bad metaphor, semantically speaking, then people would be legitimately confused when it was used. Nobody ever said they found it confusing before the language police rolled up.
I will admit that having "slave" stuff is perhaps in poor taste. You could make a far better case for that than the use of the word "master".
The trouble with all of this is, language policing is not primarily about the words. We won't be rid of the language police after making the suggested changes. They want power. Language and preferences are coming full circle to where "colored people" is bad but "person of color" is good, segregation and discrimination are ok again (especially to the exclusion of whites), etc. Martin Luther King would be appalled at the modern left.
> I would discourage the use of unconventional names for your branches, just because it creates more confusion
trunk has been the conventional name for the trunk branch of version control systems longer than anything else. "Child branches are branches that have a parent; a branch without a parent is referred to as the trunk or the mainline." https://en.wikipedia.org/wiki/Branching_(version_control)
git provides a way to determine which branch is the trunk, which it calls the default. Software which tries to guess at this is already broken, and for software which does it correctly, the name itself is completely irrelevant.
> It is a good metaphor in fact.
I disagree. In databases, for one example, what was conventionally called the slave is a replica. Is a slave a replica of his master? No, that's absurd. There are contexts in which one part of the system controls things, and the other is purely responsive or helpful, and I will grant you that in those cases, master/slave is a coherent metaphor, but the word "servant" can be used without loss of expressive power, and I see adequate reason to prefer that usage. In most cases where master/slave is used, master/replica or primary/secondary are in fact clearer than master/servant.
> The trouble with all of this is, language policing is not primarily about the words. We won't be rid of the language police after making the suggested changes.
Well yes, of course, we agree vigorously on this. I ask you: how does one grant these control freaks the least possible power? Clearly bowing to their every whim is a losing approach: if someone wants to pick a fight with me about the use of the term "blacklist", very well, they'll get their fight, because I won't stop.
But making a point of using terminology just because they don't like it is granting them a certain power as well, through the very act of rebellion. I genuinely think trunk is the best term for a trunk branch, so I use it. If you think master is better, I will disagree, and say no, trunk is better! But I won't call it offensive, that's just silly.
>Well yes, of course, we agree vigorously on this. I ask you: how does one grant these control freaks the least possible power? Clearly bowing to their every whim is a losing approach: if someone wants to pick a fight with me about the use of the term "blacklist", very well, they'll get their fight, because I won't stop.
I've been wondering about this myself. It seems to be part of a communist-adjacent power grab. The objective is to install useful idiots in all the right places so certain people can use fear to keep others in line, and ultimately advance more ambitious agendas of oppression. I'm still doing research on this subject. I just found a blog today at https://newdiscourses.com that seems dedicated to fighting this fight. It's relatively high-IQ stuff.
Anyway I agree that "trunk" is a better name than "master" or "main" for a new version control system, at least if it uses "branch" terminology. But git has been established for many years and we are only talking about an inconvenient change because of activists. Simply ignoring the activists and continuing as usual is not "granting them power"... Unless you are making a change away from something else over to "master" naming lol.
Unfortunately, there is no consistent meaning for what the master/main branch actually is out in the wild. It could be the stable branch or it could be the development branch, or it could be an old ref retained out of fear by someone who decided to jump on the renaming bandwagon. But I think for developer-centric projects, master is the stable dev branch. For user-centric project, it is often the last stable release branch. Both of these make sense.
Nearly everything and everyone uses git, and git is awfully good. If you have to learn git already, why would you learn a tool that is 10% easier than git, probably slower, and alien to everyone else? Ultimately, you can't make them share your enthusiasm for a tool that is just an incomplete imitation of something they are already expert with.
Yes, I do it too. 'master' is too ingrained to change and has nothing to do with slavery or anything sinister IMO. If I ever work with someone on a project we're in control of who feels otherwise and affected personally then it won't be much effort to change it. Until then I don't need to pointlessly spend effort rewriting it when I get it wrong on my own projects. (It only affects what git init does.)
I was used to typing "master", too. I also think a bit much was made of using "master" (although using it together with "slave" in other contexts does kinda highlight the problem people have with it).
But you know, some people around me strongly dislike calling it "master". I don't have strong feelings about it. They do. Their desire to call it something else is far greater than any desire I might have to not to. Switching to "main" cost me nothing, saves a couple keystrokes, and makes other people happy. Fine, let's do it.
If you want to use "master" on your own internal projects, go for it. No one's stopping you. I definitely wouldn't use it on a shared project because the potential cost of irritating someone isn't worth it. And because I don't want to have one set of muscle memory for my own projects and another for shared projects, I just use "main" everywhere.
Are the people around you who strongly dislike "master" genuinely offended by it, or are they more akin to the virtue signaling busybodies mentioned by a comment above?
I’m sure there’s at least some of the latter, and I haven’t heard anyone in the same physical room as me saying they were personally deeply offended by it. I heard some online people who seemed genuine say that this was something that bothered them a little bit each day at work, and they asked if we could collectively use another word. It didn’t seem like an unreasonable position that someone would have to go out of their way to be offended by.
I might feel that way if work had felt the need to switch (or started after the default changed), but as it is I spend most of my time with master, so using that for projects that I init only increases that majority.
I found that `main` was actually easier to type and say than `master`. You should keep doing what you're doing of course. But now that the change is becoming popular, I'm happy to keep using it, even in the absence of any particular moral reasoning.
Yes, and as it happens, “master” was a bad metaphor for what that branch actually is and does. It would have been a better metaphor for what is usually called “origin.”
It's not a bad metaphor at all. I've never met anyone confused by it. People want to change it because of the political grifters, not for want of clarity.
I am aware of the reasons why people decided to change it, and I am choosing not to argue about that here. I am, however, insisting that it is a bad metaphor. We all learned it the very first time we opened a git tutorial, so we accepted it as the way things were. But I am old enough to know what we meant by “master” long before git existed. Its meaning was not “a template you can use as a pattern for new work,” or “a branching point that many derivative works have in common.” A “master” is “a pristine original copy you can make many copies of.” Think about it.
You're not wrong about the "old" meaning of "master" but in most projects, the master branch is expected to function and be reasonably up to date. So it is a reasonable jumping off point for both deployment and development. Consequently, Linus didn't make a mistake with that, and it is not a bad metaphor. There are many projects that don't work this way because they chose to violate conventions. That does not mean "master" is a bad choice of name, it means people are not conforming to the original pattern. Any other "main" type name would suffer from the exact same workflow dependence.
It has nothing to do with slavery yes, but main is shorter to type. It didn't take much effort to switch when I started working in a project that used it.
IIRC if you don't do that, it will spam you with "the default branch is master, it may change" every time you make a new repo, so you have to set it explicitly to get rid of the nagging.
Funny how nobody talks about the aftermath of switching to “main” - did it achieve its original goal? No papers written on it, no researches. Like nobody wants to admit how stupid it was to push for it and insult those who resist it (which ironically achieved the opposite goal of making things more toxic instead of “inclusive”).
DEI is proven to divide people. That's why it's embraced with both arms. Switching the branch names has probably wasted tens of thousands of hours of maintenance work in the world. I doubt if there are even a dozen people in the world who were actually offended by the term master in that context or even the master-slave pairing in others. But there are probably hundreds of people at least (out of millions of developers) pretending to be offended for clout.
I have witnessed several outages caused by switching from master to main. Think nobody in a company with thousands of engineers could commit code for half a day.
It really isn’t worth it. I can agree with using ‘main’ when making new repos but trying to shoehorn ‘main’ into existing stuff is a giant pain for little to no gain.
Yes. GitHub really overstepped the mark by pushing main onto unwitting newbie devs. Really not cool. Almost like they want to control people or something.
Most people on HN probably disabled "usage report" in all places they can. Otherwise it is possible to produce a report on "which option is more popular".
The general conclusion is that relatively few FOSS tools collect usage information the way commercial software now does. Interesting opportunity to potentially improve things.
It's interesting how many people assume telemetry is just for spying on users and not an honest attempt to actually improve the product. Usability on most FOSS tooling is garbage. Even gems like Blender have incredibly rough edges compared to their commercial counterparts and that's one of the best examples of UX in FOSS. If users are spending a disproportionate amount of time performing operation X, I want to zoom in on operation X and find out what is holding them up and if it can be streamlined. I get that a lot of these metrics can be used more nefariously, but if you want to improve something you've first got to measure it or you have no baseline to determine if your "improvement" actually made a difference.
Telemetry and usage information is not bad in and of itself. It's a perfectly valid tool that can be used to find rough edges on your product and improve them. It's a great way to determine the most commonly used operations. Every developer who has worked on products used by real people inevitably discovers that their users approach their software in ways completely different than intended. Some of these unintended ways represent valid use cases the developer or product owner never anticipated. If you discover these things, you can improve the product by making that operation a first class operation instead of a weird workaround. If you're not collecting metrics, you're only listening to the most noisy parts of your user base who are by definition a small minority.
People are desensitized to claims of possible product improvements because closed-source software says it's collecting telemetry for that reason too, despite the fact it is used for all kinds of nefarious purposes. While it could be possible to get useful information from telemetry, there's no way for the collector to verify anything about popularity without violating your privacy. I don't think there is anything wrong with having an opt-in system for people who want to be involved while leaving everyone else alone. I think AUR and maybe NPM have voting systems. Github also acts as kind of a voting system, with its stars. Package downloads are a good semi-anonymous metric that works without telemetry. It could be gamed, but if someone was enthusiastic enough to game it then maybe their project should be considered active.
I would probably rather nothing logged, but I must say that when working on a language inside a company (rather than open source) and being able to do telemetry is a massive win.
I find disturbing that don't mentions kdiff3 with diff and merge tool. Specially when kdiff3 does the smae thing that diff3 and zdiff3 output formats...
I don't understand the popularity of meld. I always felt that meld it's pretty inferior to kdiff3. And I give a few try to it...
My favorite free (though not open source) visual diff and merge tool is Perforce's P4Merge. It's available for Linux, macOS (including as a Homebrew cask), and Windows. My favorite feature is its conflict resolution listing the conflicting lines vertically in the source file (like diff3 conflict markers but a GUI) instead of side-by-side panes.
My favorite aliases (these scripts keep working and I wrote them YEARS ago so they might be optimize-able)
[alias]
fb = !fzf_prompt.sh # prompts the user with an fzf prompt to fuzzy search for branches
cheese-touch = "log -n 1 --format=format:'%an' --" # displays who edited a file last
destroy = "!git reset HEAD~1 && git add --all . && git reset --hard" # destroys top commit
sc = "commit --amend --no-edit" # *jackie chan's uncle voice* one more thing!
pushf = "push --force-with-lease" # *lego batman voice* first try!
all = "!git add --all . && git status" # I forget that this doesn't exist on everyone's computer.
cp = "cherry-pick" # this one feels obvious but that saves me so many letters
---fzf_prompt.sh---
#!/usr/bin/env bash
branch=$(git for-each-ref --shell --format='%(refname)' refs | cut -d/ -f3- | grep -Eo "[^']+" | fzf-tmux -d 15);
if [[ ! -z "$branch" ]]; then
if [[ $branch == origin/* ]]; then
branch=$(echo $branch | cut -d/ -f2-)
fi
git checkout "$branch"
fi
It's from the book diary of a wimpy kid. In the book there is some gross cheese on the street and someone is dared to touch it. Once they touch it they become an outcast, obtain the "cheese touch" and no one wants to talk to them. However once they touch someone else the "cheese touch" transfers to that someone else freeing the original person from being an outcast.
So cheese touch is the last person to touch that file. Every time someone touches the file the cheese touch transfers. And if that file broke the build or something you can find out who has the cheese touch on that file and t̶r̶e̶a̶t̶ ̶t̶h̶e̶m̶ ̶l̶i̶k̶e̶ ̶a̶n̶ ̶o̶u̶t̶c̶a̶s̶t̶ ask them nicely if they know what's happening.
At the risk of angering all the vim-heads (this tip isn’t for anyone who likes vim or even emacs):
editor = "nano -t"
This nano option is aka --saveonexit
Things accomplished:
- avoids using an overpowered modal editor that requires several keystrokes just to save and quit when done writing my couple of sentence commit message
- avoid even having to tell it I want to save. Of course I want to save. ^x - all done
(In the unlikely event you decide you want to abort the commit, just hit ^k a few times to kill the text and then ^x)
(Edit: Updated to the default exit keybinding which is ^x)
> - avoids using an overpowered modal editor that requires several keystrokes just to save and quit when done writing my couple of sentence commit message
Funny, I find I do way less keystrokes in modal editors. I feel handicapped without. My patience runs out as soon as I have to use the arrows to fix something a few words back.
> - avoid even having to tell it I want to save. Of course I want to save. ^x - all done
ZZ and ZQ isn't very difficult. And shift is usually easier on the pinky than ctrl.
You don't have to like vim, that's ok, but there's no need to exaggerate when comparing. When I was new I was so terrified of getting stuck in vim that I learned to use the `-m` option in all my commits. I still use it, but with vim keys even in my shell because it's so useful.
Thanks for your reply. I wanted to clarify because of these 2 statements:
> I do way less keystrokes in modal editors. I feel handicapped without. My patience runs out as soon as I have to use the arrows to fix something a few words back.
nano and micro do support lots of types of cursor movement (the same ^a and ^e emacs bindings that work across the mac os work fine, for instance. They also have word-forward and word-back) without resorting to hammering the arrow keys. And mouse support too, for the times when that makes more sense. And all of this without having modes, and with most of the bindings visible on screen (which there is more than enough room for in modern usage so I'm a big fan of that).
> ZZ and ZQ isn't very difficult.
Keeping track of what mode you're in is the primary reason it doesn't speak to me, is all. I haven't met many people (anecdotal disclaimer!!) who actually use vim by choice, compared to how many young developers I've met who seem to have been told they have to use it when using the Terminal, so they subsequently wrote down "ESC, :wq" on a sticky note, and get flummoxed if they accidentally do something wrong because they have no idea how to use it. I saw these developers actually shying away from using things like git cli -- they became afraid of editing text in a terminal due to the unforgiving vim learning curve.*
Of course, I also agree you don't have to dislike vim and am glad your expertness with it makes you more productive. I've seen several developers who have mastered vim zipping around multiple documents and who knows what, with great efficiency. (While I don't feel like I'm missing anything by using a GUI app for such tasks, I'm still very impressed by those people!) I just want you to know I don't dislike vim completely irrationally :)
* As an example, this very thread has about 5 vim experts who didn't even know about your neat ZZ and ZQ trick! If lots of pros don't even use vim as effectively as it's designed to be used, what hope do new users have?
> And all of this without having modes, and with most of the bindings visible on screen
> Keeping track of what mode you're in is the primary reason it doesn't speak to me, is all.
Both vim and neovim has the mode on the bottom unless you're in normal. I first started using vim to get away from electron apps eating my ram. But it clicked pretty quick and fixed my RSI among other things. Modal editing is underrated.
That's a nifty option! In (neo)vim, I like to use the ZZ keybinding to quickly save if modified and then quit. If I want to abort the commit, I'll type ZQ to discard changes and quit.
Ya, it's somewhat surprising that ZZ isn't the binding that is burned into people's minds instead of :wq<cr>. I've even met regular vim users who don't know ZZ which, to be a bit hyperbolic, is mindboggling.
EDIT: And of course there is vim -y to make vim behave more like a "normal" editor than even nano :D (ie, you get ctrl-s and ctrl-q).
For me, it's because when I learned BSD 4.2 vi in the mid-80s the emphasis was on learning the decomposed commands then building up. If you learned w and q , wq is obvious and non-magical.
I've been using vi variants for decades and didn't know ZZ or ZQ. This solves a major pain point for me (mis-typing :q, trying again, now I'm off in the weeds).
ZZ is particularly nice since it sorta "does the right thing" in that if you have an unwritten empty buffer, it will silently discard it and quit. I guess I haven't really run into this as I was taught ZZ from the beginning but I imagine hitting :wq<cr> on such a buffer is pretty annoying.
If you are in `git commit --amend` or am/rebase/cherry-pick, the message did not start empty, and using ZQ will proceed with committing. :cq is a good idea.
No one's going to make you use vim, don't worry. But I don't find ^x vs jk:x compelling as a reason not to. Nor the difference between opening instantly (nano) vs. opening instantly (neovim). But I might :q! out of more commits than you do, who knows.
I used nano for about five years for git commits before I decided to embrace the Vim Way. No need to feel defensive about it, it's there for a reason.
Somehow I knew there would be a half dozen members of the vim brotherhood out to defend it against a perceived lack of reverence for it.
<edited to remove pointless debate> To the rest of us, it boils down to "learn vim so you can prove you are a Real Hacker."
I acknowledge that knowing a thing I don't know (how to use vim to do anything useful) technically makes you smarter than me in the sense of 'possessing more knowledge about vim.' So, good for you. On the other hand, I don't accept that that knowledge is more useful than the knowledge of how to use literally any other good program that edits text. And I don't think anything should be that obtuse and seemingly intentionally non-obvious (onscreen visibility of important bindings or commands would aid in learning, and could be turned off by the true elite such as yourself, couldn't they?)
I stole these from stackoverflow some time ago. Shows the branches with a bit more useful information
[alias]
# show a list of local git branches sorted by the commit date
branches = "for-each-ref --sort=-committerdate refs/heads --format='%(authordate:short) %(color:yellow)%(objectname:short) %(color:green)%(refname:short)%(color:reset) (%(color:cyan)%(committerdate:relative)%(color:reset)) %(authorname)'"
# show a list of local and remote git branches sorted by the commit date
branches-remote = "for-each-ref --sort=-committerdate refs/heads refs/remotes --format='%(authordate:short) %(color:yellow)%(objectname:short) %(color:green)%(refname:short)%(color:reset) (%(color:cyan)%(committerdate:relative)%(color:reset)) %(authorname)'"
> branch.sort -committerdate, makes git branch sort by most recently used branches
No, it makes it sort by the committer date of the commit pointed to by the branch. Personally I find that to be of little use. To actually sort by recently used (i.e. switched-to), I wrote https://github.com/amarshall/git-recent-branches
Some commands are used so often that it makes sense to further shorten them by placing them in `.bash_aliases` or a similar file for your favorite shell:
Not necessarily I'd say, it could be something that's confusing to a newcomer or (or even doesn't make sense) on first use. But that doesn't exist anyway, that was a wish for it to exist. If the tool had it, it could decide to change the defaults as you say, and so the worth-looking-at number would just be 35% or whatever instead.
`git init` itself hints that you should globally configure an initial branch name in your git config, and suggests "main", "trunk", and "development" as alternatives. It will continue to make this suggestion until you make a choice. Here's the full output from `git init` with no additional config on my machine:
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
Initialized empty Git repository in /private/tmp/test/.git/
I think people that set this actually get to that point because they don't want to keep seeing the warning, and "main" is as good a value as any. In light of this, your harsh moral ascription seems fairly silly.
I'm not sure which "this" you're referring to here, but I don't think there's anything wrong with choice. It's like being prompted to choose a browser. Some people choose the default, others prefer Firefox.
There is a problem when the choice creates confusion and randomness. Not that projects used the main/master branch consistently... In some it is the development branch. In others, it is the stable branch. And the default branch you get upon cloning the repo is something else still (one of those, or something else entirely). With git supporting different workflow styles, it would be hard to demand consistency. But a little consistency would be nice.
When I archive repos from Github, I keep track of which branch the API says is default. Otherwise there might be no way to figure it out in the future!
I think most people don't even remotely care about master vs. main, but it definitely gives me pause when someone is so bothered by another persons choice not to use master.
I care, because it introduced a ton of unnecessary pain into my workflow. Yes really. I now have a mix of repos using `master` and `main`, and I have to remember which one to use.
One repo uses `master` but a subtree uses `main`. If you make a mistake and checkout `main` you end up clobbering your whole working tree with the subtree.
I also have tooling that used to happily assume `master`, which worked fine 99% of the time. Now it works 50% of the time, and even worse the name of the main branch is just a convention, so you can't even read a setting to see which one to use.
I don't care about the specific name. `main` would definitely have made more sense from the start (classic terrible Git naming). But I do care about pointlessly changing it and breaking everything.
I think the fact that so many tools were setup to assume `master` and have no way to configure it differently was the real problem, and as annoying as it was to have GH switch to `main` it did force a lot of tools to be updated to make that configurable. Whether you use main, master, trunk, development, or anything else, the fact is the name is arbitrary and treating it any other way was incorrect.
> One repo uses `master` but a subtree uses `main`. If you make a mistake and checkout `main` you end up clobbering your whole working tree with the subtree.
If you replace checkout with switch/restore, that foot gun goes away.
You can put this in your .gitconfig and do 'git checkout-default' to always checkout the default branch of the repo you're in, no matter what it's called:
It's not clear what you're complaining about here. The fact that many people use this option, the fact that Julia included it in the article, or the fact that it's an option to change the default branch name in the first place.
Also it's pretty sad that this is the only part of a very informative article that you deigned to comment about.
`git init` whines (hints) if it is not set. GitHub decided to generate 500 StackOverflow answers by switching to `main`, which makes things really confusing if you init locally, create GitHub repo, and try to push to it. Setting it to `main` for me is the path of least resistance since I don’t care either way.