前言碎碎念
自从使用Git作为版本控制工具以来,通过教程学习、手册查阅方式了解了Git的相关原理和Git的命令,能够顺利使用。但由于还不熟练,实践经验也还不够丰富,每次遇到问题都需要重新搜索,多次下来十分麻烦。另一方面,查阅手册往往是不够的,因为手册只会告诉你什么命令做什么用,不会根据不同场景告诉你应该用什么命令。
所以在这篇文章中,我将常用的Git命令根据不同的使用场景做一个整理,加深印象的同时也方便自己日后进行查阅。
四个概念
这里借用阮一峰老师的文章《常用Git命令清单》中的图。
几个专有名词的译名如下:
- Workspace: 工作区,也就是正在编辑的文件目录
- Index / Stage: 暂存区
- Repository: 本地仓库,.git文件夹管理的版本库
- Remote: 远程仓库,也就是github.com上面的仓库
例如,在最常用的命令串中:
1 | $ git add <file> |
建立工程
在工作目录中建立与远程仓库关联的Git
工程主要有两种情况:第一种是由本地上传到远程仓库;第二种是从远程仓库克隆到本地。
本地上传
在这种情况下,远程仓库应该是没有工程的。在本地工程文件夹下:
1 | $ git init |
此时已经建立了本地仓库与远程仓库的关联,可以通过git push
推送上传。
第一次推送采用:
1 | $ git push -u origin master |
远程克隆
这种情况下,远程仓库已经有工程,只需要在本地工程文件夹下用git clone
命令克隆:
1 | $ git clone <url> |
此时本地仓库已经与对应远程仓库建立关联,为主机名origin
的地址。
克隆其他分支
git clone
命令默认克隆远程项目的master
分支及其历史,若还需克隆别的分支,可通过以下方式进行(以克隆dev
分支为例):
1 | $ git checkout -b dev origin/dev |
或者:
1 | $ git checkout -b dev |
托管到新的远程仓库
在克隆需要的内容后,有时会希望托管到新的远程仓库。
此时可以增加新的远程主机名:
1 | $ git remote add <new_remote_name> <url> |
或者干脆更改原来origin
的地址:
1 | $ git remote origin set-url <url> |
分支管理
查看分支
1 | $ git branch |
新建本地分支
新建分支(不切换):
1 | $ git branch <new_branch> |
新建分支并切换到新分支:
1 | $ git checkout -b <new_branch> |
删除本地分支
1 | $ git branch -d <branch> |
新建远程分支
相当于把远程未添加的本地分支push到远程:
1 | $ git push origin <local_branch>:<remote_branch> |
删除远程分支
相当于push
一个本地的空分支:
1 | $ git push origin :<remote_branch> |
或者用--delete
:
1 | $ git push origin --delete <remote_branch> |
合并分支
1 | $ git merge <branch> |
rebase
从前面的分析我们可以看出,多人在同一个分支上协作时,很容易出现冲突。即使没有冲突,后push
的童鞋不得不先pull
,在本地合并,然后才能push
成功
这样每次合并再push
以后,分支看上去会很乱。有强迫症的童鞋会问:为什么Git的提交历史不能是一条干净的直线?
其实是可以做到的!Git
有一种称为rebase
的操作,有人把它翻译成“变基”rebase
操作的特点:把分叉的提交历史“整理”成一条直线,看上去更直观。缺点是本地的分叉提交已经被修改过了
1 | $ git rebase |
撤销与版本回退
撤销工作区修改
有时修改工作区后,发现修改错误,希望回到原来未修改时(上一次提交或暂存)的状态。可以采用git checkout
命令:
1 | $ git diff |
撤销暂存区修改
1 | $ git reset HEAD <file> |
版本回退
希望将版本库回退到之前的提交时,采用git reset
命令:
1 | $ git log |
有必要整理一下git reset
命令的三个参数:
1 | $ git reset --soft HEAD^ |
在没有将之后的提交推送到远程仓库的情况下,git reset --hard
是个很危险的操作。若是已经推送到远程仓库,使用git pull
可以重新获得之后的版本提交。
若是在没有远程备份时使用--hard
进行版本回退,又想恢复到之后的版本,在一定时间内(一般为30天)可以通过git reflog
查看操作id,再使用git reset --hard <ID>
恢复。
删除文件
在Git
中,删除也是一个修改操作,来让我们实战一下
1 | $ rm <file> |
stash储藏
有时手头的工作进行到一半,需要切换分支做一些其他事情,可以采用git stash
命令将当前的工作区储藏起来。
1 | $ git stash |
多人协作
推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
1 | #默认推送的为master主分支 |
抓取分支
多人协作时,大家都会往master
和dev
分支上推送各自的修改。
当你的小伙伴从远程库clone
时,默认情况下,你的小伙伴只能看到本地的master
分支。不信可以用git branch
命令看看:
1 | $ git branch |
现在,你的小伙伴要在dev
分支上开发,就必须创建远程origin
的dev
分支到本地,于是他用这个命令创建本地dev
分支:
1 | #注意:本地分支名称最好与远程分支保持一致。 |
现在,他就可以在dev
上继续修改,然后,时不时地把dev
分支push
到远程。
你的小伙伴已经向origin/dev
分支推送了他的提交,而碰巧你对同样的文件也做了修改,并且试图推送。
这个时候会推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单: 先用git pull
把最新的提交从origin/dev
抓下来,然后,在本地合并,解决冲突,再推送。
1 | $ git pull |
如果git pull
提示“no tracking information”
,则说明本地分支和远程分支的链接关系没有创建,用命令
1 | $ git branch --set-upstream branch-name origin/branch-name |
最后再将你改好的解决冲突之后的分支push
到远程仓库。
这就是多人协作的工作模式,一旦熟悉了,就非常简单。
其他
状态查看
1 | $ git status |
任何情况下都可以使用git status
命令查看当前的版本控制状态(包括工作区、暂存区、仓库区),并给出当前状态下可能会用到的命令提示。
经常使用该命令是好习惯。
查看历史信息
1 | $ git log [--pretty=oneline] |
查看远程库信息
1 | $ git remote -v |
配置git用户
1 | $ git config user.name "your name" |
协议更改
有时版本克隆是采用的是https协议,以至于每一次提交都需要输入用户名密码,很麻烦。而使用ssh协议就会方便很多,需要将当前的仓库协议进行更换。
事实上,重置远程仓库名为ssh协议地址就可以了。
1 | $ git remote origin set-url git@example.com.... |