下面这些是我在使用git的过程中屡试不爽的命令,我相信有些命令一定会让大家相见恨晚。在介绍这些技巧之前,先明确几个概念
- working tree:就是当前看到的文件,中文名叫工作区,与版本库(.git目录)对应
- index:版本库里的暂存区,用于存放将要提交的文件
- HEAD:指向当前分支,分支名指向对应分支的最后一次commit
1. 只add修改过的文件,忽略新增的文件
git add -u
2. 查看对某个文件的改动
当我们对很多文件做了修改后,希望看到对某个文件改动了哪些地方,如果用git diff将显示所有文件的改动,查看一下git help diff发现确实有针对某个文件的diff,命令如下:
git diff HEAD -- path/to/file
3. 查看某个文件的修改历史
我们常常要看某个文件的commit历史纪录,比如找到某行代码是谁修改的,可以使用如下命令:
git log -p <filename>
4. 查看某个人的提交
下面这条命令会显示出author行里包含yanxr的所有commit记录
git log --author=yanxr
--author
选项的值可以是一个正则表达式,如果要查看多个人的提交则指定多个--author
5. 克隆某个指定的分支
使用git checkout git clone -b <branch name> <repo-url>
6. 比较两个分支有哪些不同
当我们在dev分支上开发的时候常常需要和master分支做比较,看多了哪些commit,可以执行
git log master..dev // 或git log master..HEAD
git diff master...dev
7. 切换到远程的某个分支
在协作开发中,如果要在别人的某个分支上开发,需要先使用fetch拉下该分支,然后checkout到该分支,其实可以用一条命令就搞定:
git checkout -b dev origin/dev
git branch -vv
8. 回到过去的某次commit的状态?
自从我接触git以来我就一直有这个问题,相当长的时间里我都不知道,我还一度以为git做不到,其实很容易啦
git checkout <commit-hash-id>
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
git branch -b <new-branch-name>
9. 回退某个文件到以前的某次commit
(可选)使用如下命令查看该文件与指定commit的差别
git diff <commit hash> <filename>
git checkout <commit-hash-id> <filename>
10. 修改上一次的commit
使用add命令将需要的修改添加到index,然后执行
git commit --amend
git push -f origin master
11. 撤销最近的1次或n次commit
如果我们要彻底abondon上次的commit,可以执行:
git reset --hard HEAD~1
12. 修改最后一次commit以前的某次commit
这个也勉强可以办到,但下面的做法不适用于涉及到merge的commit。
- step 1
git rebase -i <commit-hash-id>^
注意不要漏掉^
运行这个命令会将你带入到一个文本编辑器中,开始的n行正序列出了从commit-hash-id开始的所有commit - step 2 将想要修改的commit(第一行)的前面的pick改成edit,可以同时修改多行,保存退出。git会回退到列表中的第一个commit
- step 3
修改内容后,使用
git commit --amend
更新commit(要修改的commit位于当前最后一个commit) - step 4
执行
git rebase --continue
这个命令会自动应用后续的提交,你就完成任务了。如果你将多行的 pick 改为 edit ,你就能对你想修改的提交重复这些步骤。Git每次都会停下,让你修正提交,完成后继续运行。<commit-hash-id>..HEAD
范围内的每一次提交都会被重写,无论你是否修改。不要覆盖你已经推送到远端的提交,否则会使其他开发者产生混乱,因为你提供了同样变更的不同版本。 - step 5
运行
git status
可以看到当前处于detached状态,新建一个分支git branch new
13. 移除以前的某次commit(不是最后一次commit)?
在实际应用中我们经常有这个需求,比如临近上线发现主分支中的某个commit暂时不能上线,怎么移除呢?有很多种方法,但没有哪种方法可以保证100%顺利的完成这个任务。我使用的是revert命令:
git revert <commit-hash-id>
git是一个由linux之父最先开始用来管理linux源码的工具,它的功能强大无比,没有办不到的,只有我们不知道的。 但是git的使用并非那么简单,有很多技巧是需要不断积累的。在我写下这篇博客时stack overflow上按vote数排名前10的问题有4个都是关于git,由此可见一斑。