DEV Community

Cover image for 🔱 Git Commands You Didn't Know
Ephraim Duncan
Ephraim Duncan

Posted on

🔱 Git Commands You Didn't Know

TL;DR

One of my favorite things about Git is being as simple as it is and also being customisable and one of those features is aliases. Git supports aliases which means you can give your commands any name you want. I prefer to set aliases for really long commands to avoid searching for them everytime I need it.

The alias config in Git works like this.

git config --global alias.[new_alias] "[previous_git_command]"

# Example
git config --global alias.save commit
Enter fullscreen mode Exit fullscreen mode

From the example above, I won't need git commit again. git save will work good enough.

Add quotes around commands with multiple options.

git recommit

git config --global alias.recommit 'commit --amend -m'
Enter fullscreen mode Exit fullscreen mode

git commit --amend allows you to change the last commit message. recommit is simpler and much easier to remmember.

# Change the last commit message with recommit
git recommit "New commit message"

# [master 64175390] New commit message
#  Date: Tue Sep 22 15:09:11 2020 +0000
#  1 file changed, 2 insertions(+)
#  create mode 100644 vue.js
Enter fullscreen mode Exit fullscreen mode

git commend

git config --global alias.commend 'commit --amend --no-edit'
Enter fullscreen mode Exit fullscreen mode

Commit amend with --no-edit flag allows you to commit the new changes in repo with the last commit made, so you don't have to repeat the commit messages again.

git search

git config --global alias.search 'grep'

# Example
git search [search_term]
Enter fullscreen mode Exit fullscreen mode

git grep allows you to search in the repository for a keyword and it returns the various matches. It is cool, but I don't know what grep means, please tell me if you do. I prefer search instead, easy to remmember and easy to use.

git here

git config --global alias.here '!git init && git add . && git commit -m "init 🦄"'
Enter fullscreen mode Exit fullscreen mode

Usually when I initialize a new repo, I'll stage all the files and I'll commit with an initial commit message. git here does it all in one step. Just run it in the folder you want to make a new repo and you are good to go.

git who

git config --global alias.who 'blame'

# Example
git who index.ts
# 641753902 (Ephraim Atta-Duncan 2020-09-22 15:09:11 +0000 1)
# 641753902 (Ephraim Atta-Duncan 2020-09-22 15:09:11 +0000 2) console.log("who?") 

Enter fullscreen mode Exit fullscreen mode

git blame is used to examine the contents of a file line by line and see when each line was last modified and who the author of the modifications was. If there was a bug, in a line, you find who who did it and blame them.

git zip

git config --global alias.zip 'archive --format=tar.gz -o ../repo.tar.gz'

# Example
git zip [branch_name]
Enter fullscreen mode Exit fullscreen mode

The archive commands allows you to create tarballs and zips of your whole repo or some. git zip will make it easy to remmember. Just add the branch name.

git newbie

git config --global alias.newbie 'checkout --orphan'

# Example
git newbie [new_branch_name]
Enter fullscreen mode Exit fullscreen mode

git checkout with the --orphan flag allows you to create a branch without any history from the parent branch. No commit, fresh out of the box branch.

git clonely

git config --global alias.clonely 'clone --single-branch --branch'

# Example
git clonely [branch_name] [remote_url]

git clonely v3 https://github.com/vuejs/vue-apollo
# Cloning into 'vue-apollo'...
# remote: Enumerating objects: 2841, done.
# remote: Total 2841 (delta 0), reused 0 (delta 0), pack-reused 2841
# Receiving objects: 100% (2841/2841), 1.92 MiB | 330.00 KiB/s, done.
# Resolving deltas: 100% (1743/1743), done.
Enter fullscreen mode Exit fullscreen mode

git clone with --single-branch --branch flags allows you to clone a specific branch from a repo and I can say, I've googled it more than 10 times. Aliasing it is better.

git plg

git config --global alias.plg "log --graph --pretty=format:'%C(yellow)%h%Creset -%Cred%d%Creset %s %Cgreen| %cr %C(bold blue)| %an%Creset' --abbrev-commit --date=relative"

# Example
git plg # plg - Pretty Log
Enter fullscreen mode Exit fullscreen mode

There is nothing wrong with git log except that it is a little ugly, no color differences and if you want to customize it, you'll have to do some amount of googling. Fortunately, we have aliasing. Alias the command and you'll get a very pretty log of everything.

git fresh

git config --global alias.fresh "filter-branch --prune-empty --subdirectory-filter"

# Example
git fresh [subfolder] [branch_name]
git fresh src main # Don't do this unless you know what you are doing
Enter fullscreen mode Exit fullscreen mode

The series of commands that fresh replace is used to create a new repository out of the contents of a subfolder. filter-branch with it many flags take a the contents of a specified subfolder and replaces the content in the while repo with the content of the subfolder.

TL;DR

Add this to your .gitconfig file.

[alias]
    recommit = commit --amend -m
    commend = commit --amend --no-edit
    here = !git init && git add . && git commit -m \"Initialized a new repository\"
    search = grep
    who = blame
    zip = archive --format=tar.gz -o ../repo.tar.gz
    lonely = clone --single-branch --branch
    plg = log --graph --pretty=format:'%C(yellow)%h%Creset -%Cred%d%Creset %s %Cgreen| %cr %C(bold blue)| %an%Creset' --abbrev-commit --date=relative
    fresh = filter-branch --prune-empty --subdirectory-filter
Enter fullscreen mode Exit fullscreen mode

Top comments (22)

Collapse
 
eljayadobe profile image
Eljay-Adobe

My aliases:

st = status -s -uno
co = checkout
coffee = "!f(){ if [ `date -j +%a` = 'Fri' ]; then echo 'Friday! Time for beer!'; else echo 'Time for a coffee break. Go get a cup of joe.'; fi };f"
master = checkout master
rmbr = "!f(){ git branch -d \"${1}\"; git push origin --delete \"${1}\"; };f"
mkbr = "!f(){ local args=\"$*\"; local gituser=$(git config user.email); gituser=${gituser%@*}; if [ \"$args\" = \"\" ]; then args=\"$(date \"+%Y-%b-%d\")\"; fi; args=${gituser:-${USER}}/$args; args=$(echo \"$args\" | tr ' [A-Z]' '_[a-z]'); git checkout -b \"$args\"; };f"
ls = "!f(){ if [ -z \"${1}\" ]; then echo 'git ls [HASH] • show the files involved in the commit'; else git diff --name-only \"${1}^..${1}\"; fi; };f"
at = rev-parse --abbrev-ref HEAD
unstage = restore --staged
unadd = restore --staged
discard = checkout --
alias = config --get-regexp ^alias\\.
d = difftool
ds = difftool --staged
branches = branch --all

git ls hash
— is useful to show the files involved in a commit.

Collapse
 
ephraimduncan profile image
Ephraim Duncan

I must say, they are pretty awesome.

Collapse
 
catriel profile image
Catriel Lopez

Grep stands for "Global Regular Expression Printer". It gives you a clue about how it works, which is important, but "git search" doesn't.

I really like the plg and zip aliases, so I'm definitively stealing those! Thanks for writing!

Collapse
 
bloodgain profile image
Cliff • Edited

That's more of a backronym, really. It actually comes from the relatively ancient ed line editor's command g/re/p which basically means "global search / for a regular expression / print matching lines". So it's at least a fairly accurate backronym to the source.

The g command still sort of lives on in vi/Vim's ex mode commands. The most common use these days is probably for g/pattern/d, which does a global search for the pattern and deletes matching lines, sort of the opposite of the original g/re/p command.

Collapse
 
catriel profile image
Catriel Lopez

Oh, I didn't know that! Thanks!

Collapse
 
ephraimduncan profile image
Ephraim Duncan

Thanks for grep too. I guess search isn't

Collapse
 
winstonpuckett profile image
Winston Puckett

Oh man. That git here. Where has that been all my life?

Collapse
 
eabase profile image
eabase

Nice one there Ephraim.
Been using git for years, and still found something useful here.
PS. "grep" is selecting something using regular expressions.

Collapse
 
ephraimduncan profile image
Ephraim Duncan

Wow. Thanks

Collapse
 
goodevilgenius profile image
Dan Jones

en.wikipedia.org/wiki/Grep

Read a bit more about standalone grep. It's an important part of any unix system.

Collapse
 
0xwdg profile image
Wesley de Groot

My favorite is git recommit.

Collapse
 
srepollock profile image
Spencer Pollock • Edited

This one is my current favorite. Highly recommended after a git fetch --all to visualize where the branches are at.

[alias]
    tree = log --graph --oneline --all
Collapse
 
ankitbeniwal profile image
Ankit Beniwal

Now I will have the proof in order to blame someone for a bug. 😂😂

Cool.

Collapse
 
ephraimduncan profile image
Ephraim Duncan

😀

Collapse
 
gusdecool profile image
Budi Arsana

My only and must have alias git up

alias.up=pull --all --prune

It fetch all branches, delete tracking remote branches that not exist and pull the update.

Collapse
 
ephraimduncan profile image
Ephraim Duncan

Nice.

Collapse
 
dsbarnes profile image
dsbarnes

I learned of git cherry-pick top of last week, thought I'd toss that one in here too.
Great article!