I use the Fish shell’s abbr (abbreviation) feature for my typing-saving Git aliases. Because Fish replaces the abbreviation with the full command before the command is logged and run, I can more easily spot when I ran certain Git commands when I browse my shell session or search through my command history.
For example, after defining this abbreviation:
abbr --add gitst "git status"
I can type gitst in my prompt:
$ gitst
But after pressing Enter, my session looks like this:
$ git status
…
nothing to commit, working tree clean
Then, if I leave my shell and go back to it later, I can see that I just ran git status. I don’t have to remember what gitst stands for.
Along the same lines, I can see the long form of flags in my history while spending as much time typing as if I had written their short forms. My gitspu abbreviation expands to git stash push --include-untracked, which is easier to read than git stash push -u.
Surprised noone has mentioned aliasing git push --force-with-lease yet (shame this wasn’t the original default implementation of --force). (Explanation)
[alias]
pforce = "push --force-with-lease"
or pf if you really hate typing.
(But +1 for using magit and rarely needing to run git commit line commands!)
I’ve never been sold on the idea of --force-with-lease being the “one true way” or a “correct” default. It seems to just trade-off between fetch vs push -f being ‘safe’. There are scenarios where that trade-off might be a good one to make, but it’s still a judgement call. At least to me, from a logical perspective it seems a more intuitive and consistent default that push would be the ‘unsafe’ operation rather than fetch.
And just in general I feel like encouraging forced pushes to shared branches is not how I would choose to balance things. It might sometimes be necessary, but I’m perfectly ok if it’s a bit awkward and requires some careful thought.
Agree that pushing to shared branches is still to be avoided.
However force-pushing to private branches is something people regularly do if their workflow involves any rebasing, so having the default be a behavior that fails if the branch has somehow become “not private”, rather than just overwriting whatever was there with no obvious sign it wasn’t what was expected, gives some comfort and avoids insidious problems.
Same if you accidentally go to push to a shared branch (or someone else’s feature branch) without knowing it. Failing is preferable to quietly removing commits.
In a perfect world where noone makes any mistakes, –force and force-with-lease would be 100% equivalent as the latter would never have a reason to fail.
Edit: Just realised what you mean about fetch: that with force-with-lease the danger becomes that you don’t notice the remote branch updated when you fetched, and then the force-with-lease succeeds anyhow. Is that right? This is a good point, although I still think some footgun protection beats no footgun protection.
[help]
autoCorrect = 10 # Run guessed command after 1s if there's only one guess.
$ git psuh
WARNING: You called a Git command named 'psuh', which does not exist.
Continuing in 1.0 seconds, assuming that you meant 'push'.
Everything up-to-date
I can also recommend the meta process: Once in a while look at the statistics of your shell history to see which commands you enter most often. Create shortcuts for those.
# most used commands
cat $HISTORYFILE | cut -d ' ' -f 2- | sort | uniq -c | sort -n | tail -n 32
# most used first words in commands
cat $HISTORYFILE | cut -d ' ' -f 2 | sort | uniq -c | sort -n | tail -n 32
The output for me currently is:
171 cd
197 g diff
205 g l
208 g st
542 ls
I do have a shortcut “l” for “ls” but somehow I don’t use it.
373 m
608 v
631 apt
747 cd
829 ls
1464 g
Interesting, I’m running apt more often than vim these days?
I have a ton, broken broadly into shortcuts and flow.
My most used shortcuts are
amend = commit --amend --no-edit
s = status
co = checkout
cof = checkout -f
cm = commit -m
a = add
staged = diff --staged
poh = push origin HEAD
sync = "!f(){ git stash && git pull && git stash pop; }; f"
On the flow side, basically we have a dev branch which each developer creates feature branches off (with a naming convention of <initials>/<feature name>). I have these helpers:
Ok, so this isn’t that practically useful. 😢 But, let me reiterate what I said earlier: it makes you feel efficient, and maybe there’s some kind of placebo effect that actually makes you more productive.
I’d say it’s more important than that. More characters is more cognitive overhead, it’s more places where you can typo and do the wrong command, and if you need to fix something, it’s more characters to erase.
Doesn’t it seem weird that there’s support for aliases in .gitconfig? I guess this is sort of the logical succession from things like the porcelain commands but it really seems like messy scope creep compared to people just making aliases themselves in their shells or whatnot.
The internals of git feel really clean, but the UI is really hard to deal with…
I use the Fish shell’s
abbr
(abbreviation) feature for my typing-saving Git aliases. Because Fish replaces the abbreviation with the full command before the command is logged and run, I can more easily spot when I ran certain Git commands when I browse my shell session or search through my command history.For example, after defining this abbreviation:
I can type
gitst
in my prompt:But after pressing Enter, my session looks like this:
Then, if I leave my shell and go back to it later, I can see that I just ran
git status
. I don’t have to remember whatgitst
stands for.Along the same lines, I can see the long form of flags in my history while spending as much time typing as if I had written their short forms. My
gitspu
abbreviation expands togit stash push --include-untracked
, which is easier to read thangit stash push -u
.I just use magit.
Surprised noone has mentioned aliasing
git push --force-with-lease
yet (shame this wasn’t the original default implementation of--force
). (Explanation)or
pf
if you really hate typing.(But +1 for using magit and rarely needing to run git commit line commands!)
I’ve never been sold on the idea of
--force-with-lease
being the “one true way” or a “correct” default. It seems to just trade-off betweenfetch
vspush -f
being ‘safe’. There are scenarios where that trade-off might be a good one to make, but it’s still a judgement call. At least to me, from a logical perspective it seems a more intuitive and consistent default thatpush
would be the ‘unsafe’ operation rather thanfetch
.And just in general I feel like encouraging forced pushes to shared branches is not how I would choose to balance things. It might sometimes be necessary, but I’m perfectly ok if it’s a bit awkward and requires some careful thought.
Agree that pushing to shared branches is still to be avoided.
However force-pushing to private branches is something people regularly do if their workflow involves any rebasing, so having the default be a behavior that fails if the branch has somehow become “not private”, rather than just overwriting whatever was there with no obvious sign it wasn’t what was expected, gives some comfort and avoids insidious problems.
Same if you accidentally go to push to a shared branch (or someone else’s feature branch) without knowing it. Failing is preferable to quietly removing commits.
In a perfect world where noone makes any mistakes, –force and force-with-lease would be 100% equivalent as the latter would never have a reason to fail.
Edit: Just realised what you mean about fetch: that with force-with-lease the danger becomes that you don’t notice the remote branch updated when you fetched, and then the force-with-lease succeeds anyhow. Is that right? This is a good point, although I still think some footgun protection beats no footgun protection.
My favorite yet cursed alias:
git config alias.save "commit --no-edit --allow-empty-message"
I say commit early, commit often, and then squash / rebase when you’re going to push something publicly.
I’ve broken tools that parse
git log
this way, though.I have “git ff” for “
git merge --ff-only
”. And “git lol” for “git log --format=oneline
”.I like these threads, I always learn a new trick. :)
Here’s mine:
I use three, but of those three, only one is worth mentioning:
Interesting option:
why not:
Then you 1) cannot misspell it and 2) save 3 key strokes!
Nice, I also have “g s” and “g l”.
I can also recommend the meta process: Once in a while look at the statistics of your shell history to see which commands you enter most often. Create shortcuts for those.
The output for me currently is:
I do have a shortcut “l” for “ls” but somehow I don’t use it.
Interesting, I’m running apt more often than vim these days?
I use similar ones. A few more suggestions I use regularly:
I have a ton, broken broadly into
shortcuts
andflow
.My most used shortcuts are
On the
flow
side, basically we have adev
branch which each developer creates feature branches off (with a naming convention of <initials>/<feature name>). I have these helpers:Sometimes I’m on a machine without my usual
.gitconfig
and I wonder if I’ve done the right thing muscle-memorizing all my own nonsense :)Instead of
sync
you can just usegit config --global rebase.autostash true
and the result will be similar.I only use
sync
in specific circumstances (between local clones on the same branch), so I don’t want it to be the default. But that’s cool to know.I use these:
I have a bunch of aliases, but nowadays I just use
magit
. The most useful ones I have that weren’t in the article are probably:fish to turn every git alias into a shell alias:
bash:
My history just looks like this:
It looks arcane but having git be so near at hand makes it very easy to move fast.
I’d say it’s more important than that. More characters is more cognitive overhead, it’s more places where you can typo and do the wrong command, and if you need to fix something, it’s more characters to erase.
Doesn’t it seem weird that there’s support for aliases in
.gitconfig
? I guess this is sort of the logical succession from things like the porcelain commands but it really seems like messy scope creep compared to people just making aliases themselves in their shells or whatnot.The internals of git feel really clean, but the UI is really hard to deal with…
git already is two layered CLI UI-wise. see: porcelain
I try to use even shorter aliases through my shell, here are mine: https://github.com/timvisee/dotfiles/blob/master/bash/bash_aliases#L66-L81
Mine: