Git diff
通常情况下,我们会在自己的独立分支中完成需求开发,此时就会有需求将自己的分支和其他分支进行对比。这个功能可以通过
1 | git diff branch1 branch2 |
如果希望对比暂存区和当前的 HEAD,那么使用
1 | git diff --cached |
命令会非常方便。普通的 git diff 命令默认对比的是没有加到索引中的文件。
恢复暂存区
如果已经将一些文件添加到暂存区后又后悔了,Git 提供了多个命令来实现这个功能,具体需要根据当时情况而定。
1 | git rm path/to/file --cached |
命令将文件从暂存区索引中删除,但是仍然会将文件保留在工作目录。这比直接使用
1 | git rm file -f |
命令直接完全删除文件会安全一点
Git reset
如果希望恢复一些已经提交的改动,我们可以使用
1 | git reset |
命令。该命令有许多不同的行为,因此需要按照实际场景进行使用。
如果希望的是去除所有修改,包括索引中的内容和工作目录中的修改,那么可以使用
1 | git reset --hard |
如果仅仅是希望重置索引,那么可以使用
1 | git reset --mixed |
命令,这也是 git reset 命令的默认行为。混合的重置会保留当前工作目录中的改动。最后,如果仅仅希望修改分支的 HEAD,可以通过
1 | git reset --soft |
实现
当运行 git reset 命令的时候,我们可以指定多个目标文件作为参数传入。当然可以通过
1 | git reset --hard COMMIT_ID |
恢复到指定的提交版本。
Git stash
大家应该对 git stash 命令并不陌生,它可以通过 git stash pop 命令方便的将之前的改动恢复回来。然而,如果工作目录中有未追踪的文件,默认情况下是不会将其存入临时储藏区的。为了能够临时保存未追踪的文件,可以使用
1 | git stash --include-untracked |
命令。另外一个非常有用的命令是
1 | git stash list |
它能列出临时储藏区中的内容。
历史记录
Git 自带了非常强大的工具来查看项目以及特定文件的变更情况。我个人非常喜欢用其中的一个命令:
1 | git log --graph --decorate --oneline |
用以展示经过修饰的提交历史。这个命令非常冗长,因此我建议可以为它创建一个别名(这可能是所有技巧中最有用的,因为许多命令都比较难记)。git log 命令可以显示 HEAD、所有提交的 ID 以及分支信息。有了这些信息之后,我们可以使用
1 | git show COMMIT_ID/HEAD/BRANCH |
命令来显示更详细的信息。
有的时候我们需要了解谁对一个文件做了哪些改动,这正是
1 | git blame path/to/file |
命令所提供的功能。
之前提到过 git diff 命令,它也是一个查看历史的工具。例如,如果需要对比当前 HEAD 和前两个提交,可以使用
1 | git diff HEAD HEAD~2 |
为了能够展示每个提交中的更详细的更新信息,可以使用
1 | git log --patch |
命令。如果只想要看包含关键字“apple”的提交,使用
1 | git log --grep apples --oneline |
命令。
需要查看历史提交记录中两个点之间的提交历史,我们可以用
1 | git log HEAD~5..HEAD^ --oneline |
命令,对于分支可以使用
1 | git log branch_name..master --oneline |
显示 master 分支的文件的改动
1 | git log master --name-only --oneline |
修复错误提交
注意:以下一些命令会修改提交历史,使用前请确保了解后再执行。 当提交出错时,我们可能会希望能够修改提交历史。我不建议修改已经推送到远程仓库的提交历史(即使 git 允许这样做),但是对于本地仓库的提交历史,我个人认为还是可以修改的。通过
1 | git commit --amend |
命令可以删除前一次提交,并创建一个新的提交记录以替代之前的提交。
另一个我最喜欢的 git 使用技巧是交互式变基 (rebase)。它可以用来编辑提交信息,或者将多个提交压缩成一个提交,这也是我最喜欢的一个功能。为了在远程仓库 origin 的 master 分支之后的所有提交上执行交互式变基,可以使用
1 | git rebase -i origin/master |
该命令会显示提交列表和可执行操作的详细描述。例如以下操作将会把多个提交压缩成一个:
1 | 1 pick 80f2a48 Add feature X |
最终的结果会是生成一个提交消息为“Add feature X”的提交。
如果需要恢复一个有问题的提交,我们可以使用
1 | git revert COMMIT_ID |
该命令会创建一个新的提交,让当前项目状态恢复到指定提交之前。
如果我们在修复问题时出现了误操作,例如不小心删除了不应该删除的文件。我们还是可以从版本库中恢复回来,因为 git 保存了所有修改的版本,包括被移除的提交。git reflog 命令就是用来实现这个功能的。
挑拣提交(cherry-pick)
假设我们和同事在各自单独的分支上进行开发,同事有一个重要的提交我们也想应用到自己的分支上来,但是不需要对方分支的其他提交。这时我们可以使用
1 | git cherry-pick COMMIT_ID |
将log 输出成工整好看的形式
1 | git log --pretty=format:"%C(auto)%h %ad | %C(auto)%s%d %Cblue(%an)" --date=short |
要看在某个时间段内的commit
1 | git log --since="2018-10-01" --before="2018-10-02" |
把当前代码提交到另一个远程git仓库
假如仓库repo_a当前位于branch_a,要求将branch_a的整个数据(包括提交历史)全部提取出来,并建立一个新的仓库repo_b。这里假设仓库repo_b已经被建立。 git remote add基本语法如下。name和url是必须的。
1 | 1、 将仓库repo_b的URL添加到工作仓库的remote。 |
以下命令用于将本地的分支推向远端的分支:
1 | git push origin_repo_b local_branch:origin_branch |
将单个文件回退到某一版本
如果文件名为 a.js
- 首先到 a.js 所在的目录, 查看 a.js 的更改记录
1 | git log a.js |
- 找到要回退到的版本, 例如 hash 为 fcd121512
1 | git reset fcd121512 a.js |
- 提交本次回退
1 | git commit -m "commit message" |
- 选中该文件
1 | git checkout a.js |
- push到远程目录
1 | git push origin branch |