DEV Community

My Personal Git Tricks Cheatsheet

Antonin J. (they/them) on July 08, 2019

Besides the "basic" commands of Git, everyone has their own little Git tricks they use. I wanted to quickly write a list of my own which I tend to ...
Collapse
 
ivanalejandro0 profile image
Ivan Alejandro • Edited

Track upstream branch
alias git-up="git branch | sed -n -e 's/^\* \(.*\)/\1/p' | xargs git push -u origin "

Assuming that you have set your git-branch alias already, you could simplify this as:

alias git-up="git push -u origin \$(git-branch)"

EDIT: escaped $ to prevent running the alias on definition, thanks @darlanalves

Collapse
 
koffeinfrei profile image
Alexis Reigel

Git assumes the current branch implicitely, so the following also works:

alias git-up="git push -u origin"

Even better is to use a git alias for this:

git config --global alias.up 'push -u origin'

so you can use it like $ git up.

If you think you need to explicitly specify the branch anyway you can define an alias like this:

git config --global alias.up '!git push -u $(git-branch)'
Collapse
 
antjanus profile image
Antonin J. (they/them)

Nice! Thank you for the tips!

The git up alias is perfect.

Collapse
 
travisdock profile image
Travis

Not specifying the branch still gives me a Fatal: The current branch has no upstream. Any ideas why?

Thread Thread
 
koffeinfrei profile image
Alexis Reigel

Did you specify the -u flag?

Thread Thread
 
travisdock profile image
Travis

Yep, I copied and pasted this exactly
git config --global alias.up 'push -u origin'

Thread Thread
 
antjanus profile image
Antonin J. (they/them)

yeah, looks like I have the same issue!

Thread Thread
 
travisdock profile image
Travis

Ok, after some digging I got an alias to work. I have no idea why it works when nothing else I tried would but here it is anyway. I think it is best to paste the following into your .git-config file directly:

up = "!git push -u origin `git symbolic-ref --short HEAD`"

or if you have git 2.22

up = "!git push -u origin `git branch --show-current`"

I figured this out mostly by messing around with this Stack Overflow answer: stackoverflow.com/a/30529511/9770212

Collapse
 
antjanus profile image
Antonin J. (they/them)

the problem is that the git-branch got evaluated when I started my terminal. This is in zsh. :/

I'd immediately get "not a git repository" message.

Collapse
 
antjanus profile image
Antonin J. (they/them)

maybe a function would work?

function gitUp() {
  git push -u origin $(git-branch)
}
Thread Thread
 
ivanalejandro0 profile image
Ivan Alejandro

Oh, you're right... an alias would be immediately evaluated.
Using a function is the way to go.

Thread Thread
 
antjanus profile image
Antonin J. (they/them) • Edited

it kind of tripped me up! I was expecting it to evaluate when invoked, just like a function.

Thread Thread
 
ivanalejandro0 profile image
Ivan Alejandro

Yeah, it may not be intuitive at first... but is really useful to be able to rely on both behaviors (evaluate on definition or when run).
If you wanted to use other aliases within an alias you have to start playing around with eval (which I don't really recommend). Like:

alias testingEval="eval 'git-branch'"

But things get messy pretty quickly... I pretty much use alias for super simple things or functions when I need something a bit longer that could use some extra variables, or to use parameters, or runtime expansion.

btw, I use zsh too :) ... I use prezto and got some configs online if you want to take a look
github.com/ivanalejandro0/prezto/b...

Thread Thread
 
antjanus profile image
Antonin J. (they/them)

I get why it works like that and I'm ok with it :) It really just surprised me but then again, I don't do a lot of bash scripting.

Thread Thread
 
darlanalves profile image
Darlan Alves

The key to it is just escape the $ char in an alias.

alias git-up="git push -u origin \$(git-branch)"

Thread Thread
 
ivanalejandro0 profile image
Ivan Alejandro

Oh, cool. I didn't know about that, thanks.
I've edited my comment escaping the $.

Collapse
 
sandordargo profile image
Sandor Dargo

I like this kind of articles, we can get some ideas.

From your examples, I had the feeling that you're not sure how to include arguments or bash commands into aliases. You might be interested in one my articles:

Collapse
 
antjanus profile image
Antonin J. (they/them)

I do know. And the comments taught me a good deal but I don't like adding bash commands to git aliases since I use git on non Linux machines

Collapse
 
sandordargo profile image
Sandor Dargo

Sorry then. How come you use sed and xargs in your aliases? Or you want to maintain only one .gitconfig and push all the rest to OS-specific setenvs?

Thread Thread
 
antjanus profile image
Antonin J. (they/them)

That's it!

I write completely different aliases for Powershell but I get to still use identical git aliases

Thread Thread
 
sandordargo profile image
Sandor Dargo

Have you considered using Git BASH on windows?

Thread Thread
 
antjanus profile image
Antonin J. (they/them)

yep, quickly dismissed it. It's not worth it plus Powershell is just so damned good!

Collapse
 
chilcutt profile image
Kyle Chilcutt

Nice post!

For the "get the name of the current branch" there's a git plumbing command that can help you get the current branch name reliably without the text manipulation:

alias git-branch="git rev-parse --abbrev-ref HEAD"

I tend to keep this one as part of my git aliases:

git config alias.current "rev-parse --abbrev-ref HEAD"

Here's a quick write-up if you're interested!

Collapse
 
ivanalejandro0 profile image
Ivan Alejandro

Current branch
alias git-branch="git branch | sed -n -e 's/^\* \(.*\)/\1/p'"

My approach to get the current branch is this:

alias gcb='git symbolic-ref --short HEAD'

(gcb to remind me of Git Current Branch)

I like it more because it uses only git and I don't depend on piping through another app.

Collapse
 
vishnuharidas profile image
Vishnu Haridas

I am afraid to do git cherry-pick without the -n parameter because cherry-picking automatically commits after picking the changes. Most of the time I want to review the changes and commit them manually. So I do:

git cherry-pick -n HASH
Collapse
 
antjanus profile image
Antonin J. (they/them)

ooh, i wasn't aware of the dry run. I tend to not care because I can always do an interactive rebase and delete those commits.

Collapse
 
stefant123 profile image
StefanT123 • Edited

Quick amend
git commit --amend --reuse-message HEAD

My approach for this is git commit --amend --no-edit

Collapse
 
antjanus profile image
Antonin J. (they/them)

I like that better. 👍

Collapse
 
vonc profile image
VonC

On the current branch alias, don't forget git branch --show-current with Git 2.22: stackoverflow.com/a/55088865/6309.

I used it in stackoverflow.com/a/56713414/6309

Collapse
 
slash5toaster profile image
Clyde

also if you've got git > 2 this works

git status --porcelain=v2 --untracked-file=no --branch \
| grep branch.head \
| cut -d ' ' -f 3

Collapse
 
antjanus profile image
Antonin J. (they/them)

I HAD NO IDEA. This is awesome! Thank you! :)

Collapse
 
antjanus profile image
Antonin J. (they/them)

looks like I'm still a little behind on versions. I'm on v2.17.x

Neat tip though, I'll have to remember to come back and change my rc files to use this :)

Collapse
 
goodevilgenius profile image
Dan Jones

Why use shell aliases for something that's git specific? You can just use git aliases.

Instead of:

alias git-branch="git branch | sed -n -e 's/^\* \(.*\)/\1/p'"

Do:


git config --global alias.this-branch '!'"git branch | sed -n 's/^\* \(.*\)/\1/p'"

Now, from within any repo, you can run git this-branch, and you didn't have to add anything to your shell, and if you switch shells, it will continue to work.

Collapse
 
antjanus profile image
Antonin J. (they/them)

That's pretty cool! I basically just learned about that from people on this post

Collapse
 
iamandrewluca profile image
Andrei L • Edited

Git aliases

# ~/.gitconfig
[alias]
    spull = "!git stash && git pull --rebase && git stash pop"
    spush = "!git stash && git pull --rebase && git push && git stash pop"
    pushf = push --force-with-lease
    ameno = commit --amend --no-edit
    anarchy = "!git add . && git ameno && git pushf"

System aliases

# ~/.bashrc, ~/.zshrc, ...
alias cdg='cd $(git rev-parse --show-toplevel)'
Collapse
 
kjellski profile image
Kjell Otto

Thank you for the nice writeup Antonin! I'll definitively take over a few :)

Might not be totally related, but in order to not be able to commit things that are not to be committed, we're using (husky)[github.com/typicode/husky] and a pretty strict linting :)

Collapse
 
antjanus profile image
Antonin J. (they/them)

We actually use husky too!!

Collapse
 
jordybaylac profile image
Jordy Baylac

great! also take a look to this: ohshitgit.com/

Collapse
 
darlanalves profile image
Darlan Alves

Great tips, Antonin!

I've been using similar tricks in my daily flow... And they definitely help productivity!
I've added them to a repo so I can share between my machines and with other devs :)

github.com/darlanalves/faster-git

Collapse
 
mliq profile image
Michael Liquori

You can simply do git push -u origin HEAD and not have to mess around with evaluating the branch name.

Collapse
 
tuanht profile image
Anthony-Tuan Ha • Edited

Your trick git reflog saved my today working. Thanks :)

Collapse
 
antjanus profile image
Antonin J. (they/them)

That's awesome! I'm happy to hear that!

Collapse
 
shotasenga profile image
Shota Senga

Thanks for sharing!! I have a question about git log -1. Why don't you use git show instead? Does it have any benefits?

Collapse
 
oli8 profile image
Olivier

I just do this to get the current branch:
git branch | grep '*'

Collapse
 
yaron profile image
Yaron Levi

Great thanks!

Collapse
 
shushugah profile image
shushugah

I had no idea about cherry-picking a list of commits! This is a game-changer!

Collapse
 
waynejwerner profile image
Wayne Werner

You should also have *.log in your .gitignore

And *.sw[a-p] if you have vim friends.