git中有一些命令非常相似,使用时容易混淆。本文采用对比的方式总结了git中常用的一些核心命令。
第一组:git pull / git fetch / git pull --rebase
首先是git pull与git fetch,两者都是从远程仓库拉取代码的命令,其中git pull = git fetch + git merge. 相比而言,git pull从远程仓库中拉取代码到本地,并将代码merge进当前分支中;而git fetch则仅仅是将远程仓库的代码拉取到本地,并没有merge到当前分支的操作。一般情况下,我们很少使用git pull命令,而是使用git fetch+git merge的命令组合。原因在于,git pull命令直接将从远程仓库拉取到的代码merge到当前分支,使得我们在没有看清新的改动的情况下就已经将代码merge到本地当前分支,也容易出现冲突,并造成错误,而git fetch则给我们一个察看新的改动的机会,使得merge的工作更加顺利。
再看git pull --rebase,也是从远程仓库拉取代码的命令。简单来看,git pull --rebase = git fetch + git rebase, git pull --rebase不仅从远程仓库拉取代码到本地,而且它将远程仓库中拉取的所有commit直接提交到当前分支中去,并且这些提交的commit要早于当前分支中已提交且尚未push的commit。如果有冲突,那么我们需要手动解决冲突,并且运行命令git rebase --continue。使用git pull --rebase的好处在于,我们可以得到一个非常干净清爽的分支,使得分支走在一条直线上,而不存在各种merge的分支出现。
第二组: git reset --soft / git reset --mixed / git reset --hard
git reset是将代码或者操作进行还原的命令,它分成三类。
首先git reset --soft,这个命令是git reset中最为温和的一个,它仅仅是撤销之前的git的commit操作,但不会丢弃之前的改动,而且新的改动会被存放在index区中。最常用于撤销之前的commit,但需要保留commit中的修改。比如,当我们发现之前commit中存在编译错误的问题时,我们该如何修改呢?其中的一个很好的方法就是使用git reset --soft,它既做到了撤销之前的commit,并且还可以保留之前的改动,进而可以对编译错误的问题就行调试修改。
其次git reset --hard,这是这组命令中最为激进的一种方式。它不仅可以还原之前的操作,而且会丢弃之前修改的内容。这个命令需要慎用,因为命令执行之后,代码丢弃的代码将无法找回。git reset --hard最常使用在确实需要丢弃修改的地方,比如我们需要将当前工作区中的代码丢弃的时候,我们可以使用这条命令。
最后git reset --mixed,和git reset --soft更为接近,它也用于撤销之前的commit的操作,且不会丢弃修改的内容,但它执行完毕之后并不会将修改存放在index区,而是存放在unstaged区域中。
第三组:git checkout / git checkout -b
git checkout命令用于分支切换,它将在不同的分支间进行转换操作。一般的格式为git checkout <branch name>,在checkout之前,目标分支需要提前创建。因此我们切换分支的一般的流程是,首先利用git branch <branch name>创建一个新的分支,然后使用git checkout <branch name>切换到新创建的分支上去,进行具体的代码的开发。而git checkout -b <branch name>,是实现这些操作的简化的命令,可以达到同样的效果。
第四组:git add / git commit / git push
这组操作其实没有什么容易混淆疑难之初,放在这里的原因在于,它们是git正常工作流上的一些关键命令。一般情况下,我们使用git进行版本控制,首先我们工作与unstaged区域,我们使用git add的操作将修改的代码放入index区域,然后利用git commit将代码提交到本地仓库中去,最后使用git push将代码推到远程分支,完成任务。这条主线使得我们的工作方式更加清晰明了。
第五组: git commit / git commit -a
git commit命令将index区域中的内容提交到本地仓库中去,这个命令非常简单。我们知道要讲修改的内容提交到本地仓库,首先需要将unstaged区域中的修改放入index中,然后才可以提交。那么有没有一种方法可以使得我们无需手动将修改放入index区,而直接提交到本地仓库呢?有,就是这个命令git commit -a,它可以做到这一点。具体的命令实例如下:
git commit -a -m "commit message"
第六组: git stash apply / git stash pop
Stash区域是暂存修改的地方。比如,我们在当前分支上进行了修改,这些修改还不能commit到本地仓库中去,但是这时我们又需要切换到另外一个分支上进行工作。怎么办呢?这时候就是stash区域大显身手的时候了。我们可以通过将修改暂存于stash区域中,实现此操作,具体命令即: git stash。那么我们如何将之前暂存的修改取出呢?一般来说两种方法:
第一种:git stash apply,它可以将修改从stash区域中取出,且不会删除stash区域中暂存的内容;第二种:git stash pop则不同,它先将修改取出,然后删除stash暂存的此条记录。
第七组: git cherry-pick / git checkout
之前说过,git checkout可以用于切换分支,另外它还可以切换不同的commit。我们可以通过git checkout <commit id>命令来切换到不同的commit id上进行工作。
git cherry-pick则不同,它不会切换commit,而是从其他的分支上“采摘”一些commit到当前的分支,值得注意的是这些新“采摘”来的commit会被直接提交到当前分支的本地仓库中去。
第八组:git reset / git revert
刚才提到了git reset命令,一方面它可以撤销之前的commit操作,另一方面它还可以决定是否丢弃撤销的commit中的修改;
git revert和它有些相似之处,它也会撤销之前的commit,但是两者不同的是,git revert可以撤销仓库中任意一个commit而不改变commit历史结构,然而git reset则不同,它不能随意的撤销任意一个commit,而是在选择撤销的commit之后的所有的commit都会被撤销,这是它们的最大不同之处。