Git is so popular around the developer world, as well as Github. Nowadays almost every developer could use git a bit. It was hard to imagine this situation in several years ago.

To master your development tool would help you focus on development itself. And provide more information when hacking code.

Git has so many commands, and each commands have many parameters. It is common that people says “Oh! I don’t know we can use Git like that!”. This article is for sharing some commands I use often. Hope it helps, and I hope you can share your tips as well.

Git config

This is most basic. Make your own ~/.gitconfig. I did, and put lots of alias into it. Part of my ~/.gitconfig is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[color]
ui = auto
[user]
name = YOUR_COMMIT_NAME
email = YOUR@commit.email
[alias]
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
ld = log --decorate --graph
ln = log --decorate --graph --name-status
lf = log --pretty=fuller --decorate --graph
s = status
amd = commit -a --amend
cm = commit --amend
co = commit
ca = commit -a
ck = checkout
ri = rebase -i
ri5 = rebase -i HEAD~5
ri10 = rebase -i HEAD~10
ra = rebase --abort
rc = rebase --continue
cp = cherry-pick
rb = rebase
fp = fetch -p --tags
g = grep
sm = submodule
[diff]
algorithm = patience
[core]
editor = vim
autocrlf = input
quotepath = false
paginate = true
pager = less
[push]
default = simple
[url "git@github.com:"]
insteadOf = https://github.com/

tig

tig is a very useful command line interactive tool. Even in Mac you can install it via brew

Range

In Git, you can specify a range by this format <HASH1>..<HASH2>, for example

1
2
$ git log -p HEAD~10..HEAD~3 # see commits content between HEAD~10 to HEAD~10
$ git log -p bfd4dd408cf..af9c8c9b6 # similiar, buy specify specific hash

Sharing

Sometimes you will co-work with people who cannot access full repository. We can send some changes to him by patches. Because Git is patch-based tool, manipulating patches is natural for Git.

format-patch

To format patches, we should specify a range to command.

1
2
3
4
5
6
7
8
9
10
11
# To create a patch file for latest commit
$ git format-patch HEAD^..HEAD
0001-update-view.patch
# To create patch files for recent 5 commits
$ git format-patch HEAD~5..HEAD
0001-bison-add-empty-mycoach-fragment.patch
0002-bison-Render-basic-MyCoachFragment.patch
0003-bison-use-xml-to-define-tab-layout-in-MyCoach-and-fi.patch
0004-working-on-tab-steps.patch
0005-update-view.patch

am

In the other side, people can apply that patch via am commant

1
2
$ git am 0001-update-view.patch
Applying: update view

The benefit of format-patch and am is that it remains commit message.

archive

If you gonna to share a snapshot to people who cannot access full repository. For example, you co-work with another company, and they want source code in a specific version.

1
2
$ git archive -o /tmp/ouptut.zip HEAD # latest one
$ git archive -o /tmp/ouptut.zip <HASH> # another version

of course you can use tag, if you manage tags in proper way.

Browsing

log

Everyone uses git log. It can provide many information in pretty format.

1
2
3
4
5
# In reverse order, display changed content from specific commit
$ git log -p <MD5>..HEAD --reverse
# To see merge graph and what file was changed
$ git log --decorate --graph --name-status

show

Not only to see the content of one commit, we can also see full content of one file in specific commit.

1
$ git show <HASH>:./path/to/file

Sometime when I want review a Pull-Request. But you know, usually if you cannot see the whole file, you cannot get overview of the change, then it is hard to understand “Is this change safe?”.

I will use this command to see diff in whole file.

1
2
3
4
5
$ git show <HASH> -U10000
or
$ git show HEAD~5 -U10000
or
$ git show origin/SOMEONE/branch -U10000

10000 is just a large-enough number. of course you can adjust it. Sometime I use vim to review patch

1
$ git show <HASH> -U10000 | vim -R -

diff

The basic usage of diff is to see different conent between two commits.

1
$ git diff HEAD~10..HEAD

To see What changed in a specific file, between two commits?

1
$ git diff <HASH>..<HASH> Thefile

If we want to see What files were changed, between remote master and my current work tree?

1
$ git diff origin/master..HEAD --name-status

Others

gc

If you found there are too many small object files under .git/objects/, this command could pack them into one large file.

1
$ git gc

ps. Git is more like a object filesystem. The way Git works is to manage many objects.

clean

If you want to clean up EVERYTHING doesn’t be tracked by git, such as generated files.

1
$ git clean -xdf

Be careful, I usually use command and mis-cleaned my config files.(orz)

reflog

This command will save your ass in some day.

Sometimes you use reset to change your HEAD, or to delete a branch. We know the content still exist in the git repository, we cannot get it back because we don’t know its hash.

That is why git reflog matters. It records every action you did in your git repository, so you can get everything back.

1
$ git reflog

clean with gc

This is a bit dangerous.

If you found your git repository is huge, full of objects you really don’t need. The command will prune not-tracked-objects. For example, if you had ever fetch objects from another remote server, but you don’t need them anymore. Even if you delete every branches in your repo, those objects still exists in your git repo. (a bit like dangling object)

This command will clean them. And it definitely effects reflog, so pleae be careful for this command.

1
2
$ git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 \
-c gc.rerereunresolved=0 -c gc.pruneExpire=now gc

Rebase

Well. I don’t wanna talk about rebase. rebase is too IMPORTANT so it should be a standalone topic. In my personal opinion, a people don’t udnerstand Git until who know how to use git rebase -i.

rebase is not only doing rebase, but can also edit previous commits.(remove, edit, squash). To use rebase in proper way will make you commits looks perfect.

This is one of most useful git-rebase command. Please read git help to understand how to use git rebase, if you don’t know about it.

1
$ git rebase -i <HASH>

At least, in here I want introduce a common situation in development process.

1
2
3
4
5
6
foobar
o---o---o---o---o master
| \
| o'--o'--o' topic
\
o---o---o---o---o next
  1. You start work from commit foobar, and you create 5 commits in branch next. You are in branch next now.
  2. Some people works on master branch and have progress. master branch got some commits.
  3. Your colleage create new branch topic, and he gave 3 commits into it.

If you wanna get his effort to your branch. It means I wanna develop base on my colleague’s work. Then we can use rebase like this

1
$ git rebase -i --onto topic --fork-point foobar

Then the result looks like

1
2
3
4
5
6
foobar
o---o---o---o---o master
\
o'--o'--o' topic
\
o---o---o---o---o next
Using Mockito ← Prev Next → RxJava Javadoc