Some Git tips
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 | [color] |
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 | $ git log -p HEAD~10..HEAD~3 # see commits content between HEAD~10 to HEAD~10 |
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 | # To create a patch file for latest commit |
am
In the other side, people can apply that patch via am
commant
1 | $ git am 0001-update-view.patch |
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 | $ git archive -o /tmp/ouptut.zip HEAD # latest one |
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 | # In reverse order, display changed content from specific commit |
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 | $ git show <HASH> -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 | $ git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 \ |
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 | foobar |
- You start work from commit
foobar
, and you create 5 commits in branchnext
. You are in branchnext
now. - Some people works on
master
branch and have progress.master
branch got some commits. - 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 | foobar |