前言
Git(以下方便起见称 git)是一种代码版本控制工具,现在多人开发的项目基本都是用 git 了。自己对 git 用的一直比较迷糊,加上最近实习时用了一些之前没用过的 git 操作,所以在这里总结一下,对 git 的常用命令做简单的演示,以期加深对一些命令的理解。
本文不讲解 git 的原理(主要是本人也不太会它的原理),只是对一些本人常用的命令进行演示,过程可能稍显流水账,但是难度不高,应该比较适合 git 小白。
事前准备
- GitHub 上的远端仓库:
由于要演示 git 的操作,所以肯定得在 GitHub 上有一个仓库,这里我就不新建了,几年前弄了一个。怎么建仓库的就不演示了,这也不是本文的重点。
- 电脑上安装 git:
这里我也早就安装好了,具体怎么安的也不演示了。
话不多说,下面直接进入正题。
常用命令演示
克隆项目
本地没有项目仓库时,运行git clone
命令来把整个完整仓库复制到本地。
这里我在 e 盘下的 gitShow 目录下git clone
了远端仓库:
可以看见,相应的代码确实搞下来了。
git add 和 git commit
我们对项目的某文件进行了修改之后,就可以先运行git add
将此文件加入暂存区,再运行git commit
提交暂存区的修改。这两个命令的原理大家可以自行查阅资料,这里不赘述了。
由于原项目是个 Python 项目,为了方便操作,这里用 PyCharm 打开,新建了 master 文件,并向其中写入了一些语句:
用git status
查看一下状态:
我们先后运行git add .
和git commit -m 'master first'
来进行一次 commit。
可以看到,除了新建的 master 外,还有很多什么.idea/xxx
的文件,应该是用 PyCharm 打开项目自动创建的吧。。。
这里为了省事用的 git add .
,也可以git add filename
来手动添加一个个文件,不同的文件命名不同的 commit。
git push
commit 弄完了之后,可以用git push origin xxx
来把代码 push 到远端仓库:
去 GitHub 上查看,可以看到我们刚刚的 push。
分支操作
这里用git checkout -b xxx
创建两个分支:
在 PyCharm 的控制台也可以看到三个分支:
除了控制台之外,用git branch
可以列出本地所有的分支:
git checkout -b xxx
是创建并切换到分支 xxx,如果不加-b
,就是切换到本地已经存在的分支 xxx。
另外如果之前没有用过 git 的,可以尝试在其中一个分支上修改,然后切到另一个分支,你会发现明明打开了同一个项目,不同分支的内容也是不一样的,这就是 git 的能力了,这个我几年前第一次用的时候,感觉还是挺神奇的。。。
git pull
下面我们再创建一个分支:dev3:
在其上面进行一些修改:
再把它 push 上去,这个过程就不演示了:
我们在 GitHub 后台将这次提交合并入 master。
那么问题来了,现在远端的 master 分支和本地的 master 分支就不一样了,切到本地的 master 分支,再用git pull origin xxx
来更新本地的 master 分支:
生效了,在本地的 master 分支上,看到了 dev3 的改动。
分支合并
分支合并有两种方法:git merge
和git rebase
,我们在 dev1 和 dev2 上用两种方法合并一下,看看区别。
现在 master 分支已经变了,这很正常,毕竟你开发的时候,别人肯定也在开发,master 难保不变。我们在 dev1 和 dev2 上分别做两次 commit,来模拟实际的开发流程:
修改之后的两个分支内容为:
OK,现在本地分支 master 和 dev1,dev2 都不一样,在提交 push 之前我们希望把本地的 master 合并一下,减少之后向远端 master 合并的麻烦(因为早晚要和最新的 master 合的),分别用git merge
和git rebase
合并,看看区别。dev1 用 merge 合并:
发生冲突了,这也很正常,master 和 dev1 都修改了同一文件,那肯定有冲突啊,可以看到原文件也变成了那个奇怪的样子,这时候我们可以手动合并,把这些奇奇怪怪的符号删掉。
对于手动合并,我的意见是:可以,但没必要。我们在 PyCharm 的文件编辑区右键->Git->Resolve Conflicts,即可:
点击右边那个蓝色的 Merge...,可以进入下面的页面:
列出了三列,冲突什么的一眼就可以看出来,比手动合并强太多了,IDEA 也有此功能,JetBrains 家的产品应该都有此功能。
解决了冲突后,按提示git commit
,接着进入此页面,直接:wq
保存即可。完成之后,会收到下面的提示:
接着来到 dev2,用git rebase master
来合并:
出现了冲突,和 dev1 一样,解决冲突(这个过程就不演示了,一模一样),之后,按提示运行git rebase --continue
:
还是和上面一样的页面,多说一句,这其实是个 vim 风格的编辑页面,vim 的命令在这个页面是适用的,其实就是让你给这个合并产生的 commit 取个名。下面看一下 git merge
和git rebase
的区别:
可以看出,用git rebase
提交,提交线更清晰,git merge
就复杂很多,不过,git merge
可以记录每一次 commit,git rebase
则会丢失 commit,哪个更好,见仁见智吧。
压缩 commit
拉出了自己的分支进行开发,可能 commit 了七八次,每次的 commit 信息都是诸如fix bugs
这类无意义信息,那么这七八次 commit 实际上可以合为一个,还是用git rebase
。
在 dev1 上提交了3次无意义的提交,如上。现在用git rebase
来压缩 commit。首先git log
查看提交记录:
接着用git rebase -i commitId
来压缩,这个 commitId 就是你想压缩的最早的 commit 的前一个 commit 的 id,在这里就是9c6d0b9dd815e4e2e2b006b883fcd1e950b86eef
,那么我们运行git rebase -i 9c6d0b9dd815e4e2e2b006b883fcd1e950b86eef
:
又来到这个交互编辑页面,这里 pick 就是保留此 commit,s 也就是 squash 表示把这个 commit 压缩到上一个,我们在这里把 2 和 3 的 pick 都改为 s,再:wq
保存。完了会来到下面这个页面:
这个页面其实就是让你给压缩后的 commit 取个名字,随便取一个:
再用git log
查看,可以发现 3 个 commit 成功合为了一个:
git log
上面已经用到git log
了,实际上还可以让结果更可视化一点,如运行git log --graph
:
和上面展示过的 IDE 自带的 git 可视化工具其实差不多。你要是嫌 git log
的记录太长了,也可以用--oneline
来缩减行数,如下:
常用命令演示就到这里了,本人目前为止也就用过这些命令。
用 git 多人开发的流程
比方说让我开发个新功能,我一般先git pull --rebase
拉一下最新的 master 的代码;然后从本地的 master 分支切一个分支,命名为feature/xxx
,表示我要开发的功能;接着就一顿开发,一顿 commit,在代码没问题之前,一直在这个分支操作;最后一系列 code review,测试什么的都过了之后,再次去本地 master 拉最新代码,然后git rebase master
一下,解决冲突什么的;最后把自己这一堆 commit 用git rebase
压缩一下,保证一个feature/xxx
就一条 commit 记录;最后提合并请求就完事儿了。
总结
本文演示了一些 git 的常用命令,最后总结了一下 git 多人开发的流程,如果有什么理解的不对的地方,评论区友好交流。