git 是一套内容寻址 (content-addressable) 文件系统,在此之上提供了一个 VCS 用户界面。其存在以下几种状态:
git init:用于初始化项目。当你写好一个项目,想让其被 git 管理,就可以执行该命令。如果并未执行该命令,那么其它 git 命令也无法执行。如果已经是一个 git 项目,那么则可以忽略这条命令。
git clone git地址:clone 后可跟随 -b 参数,参数后需加分支名称。这样可以保证只拉取指定分支的代码。
git remote -v:一般先执行该命令以获取别名。结果以别名后跟 git 地址的方式展示。如下:
通常我们会存在一个自己 fork 的仓库和一个原始仓库,为了方便我们日后提交代码,我们可以为不同的仓库起不同的名字,使用命令 git remote add yuanshi git地址:yuanshi 即为别名,可以随便写,但要唯一。这样就可以新增一个远程仓库。如果没有 fork 自己的仓库,可以选择新建一个分支。使用命令 git checkout -b "分支名",执行该命令之前,最好确保在 master 分支,这样可以获得最新的代码,从而减少冲突的可能性。
git fetch origin master:一般不建议使用这条命令,还需要我们再执行 git merge 命令。
git pull origin master:origin 代表 git 地址的别名;master 代表分支名称。
一般在提交之前,都最好看一下,我们都修改了哪些文件。使用命令 git status,效果如下所示:
虽然可以看到哪些文件被修改了,但我们并不知道,修改了哪些内容,我们可以借助 PyCharm 的可视化界面,如:
git add .:是把所有变化的文件都添加到索引库(即将修改添加到暂存区)。也可以添加单个文件,命令为 git add A.java,B.java:多个文件之间用逗号分割。也可以选择使用工具进行添加:
要提交的文件添加好后,需进行提交,使用命令 git commit -m "commit message" 提交,其中的 commit message 一般建议能较为清楚的表明你这次提交的目的。使用该命令可将代码由暂存区上传到本地仓库。也可以使用 PyCharm 进行 commit,如上图中的第一行,点击后会弹出如下页面:
从图中我们可以看到,分为上中下三部分:上面部分为你要 commit 的文件;中间部分为你 commit 时填写的信息;下边会展示版本信息,即该文件的改动。点击右下角的 commit 后即可 commit,但如果是第一次以这样的方式进行提交,则会弹出上图所示弹窗,要求填写用户名。
git push origin 分支名:这是提交的最后一步,将代码上传至远程仓库。
但在多人协作的场景中,通常提交代码的时候都会存在冲突。需要我们解决冲突后重新提交。
通常在验证以往问题的时候,需要进行版本回退,可使用命令 git reset --hard 版本号。该命令修改了 HEAD 的指向位置,令指针退回至你需要的版本。注意,回退至该版本后,后续 commit 都将消失。如果只是想要移除某个 commit,可使用 git revert commitid 命令。版本号可通过命令 git log 查看,如下图所示:
还可以在 github 页面上查找,如:
通常情况下,我们的代码不可能一次性就写好,可能需要进行合并、修改,下面将分情况进行说明。
可能在写代码的过程中,为防止丢失,我们多次 commit 了代码,但这些 commit 都是服务于同一个 issue,这时我们可以将多个 commit 进行合并。可使用命令 git rebase -i HEAD~~,这代表将最近两个 commit 进行合并,~~ 代表的意思就是 2,如果想要合并最近 3 次的,可以这样 ~3 写。然后会进入 vi 模式,如下所示:
通常修改的时候都是将后面的与前面的进行合并,即将上图中第二个 pick 改为 squash,然后保存,就会跳入下图所示的 vi 界面:
在该页面删除掉不需要的 commit message,然后保存。合并完成后可使用 git log 进行查看。
确认无误后,重新 push 代码即可。
很多时候我们会在不同分支进行代码的编写工作,假设现在 A 分支是一个稳定版本的分支,B 分支是一个不断开发新功能的分支。我们不能直接将两个分支合并,因为新功能未开发完毕或者是说还未稳定,但是该分支上有我们想要的一个 commit,这时候可以选择使用 git cherry-pick commitid 命令将该 commit 取来。cherry-pick 命令还可以选择选取多个 commit,即将 commitid 部分写为 (commitid1..commitidn]。
可能我们已经在新的分支开始了新的工作,但突然需要修改以前的代码,那我们首先需要将这个分支的代码保存起来,可以使用命令 git stash 将代码推入 git 栈,然后就可以切换分支了,使用 git checkout 分支名进行切换。当修改重新提交后,可以再切换回原有分支,然后使用 git stash apply (stashid) 命令将保存好的内容重新取出,但该内容不会被删除。如果不知道 stashid 是什么,可以使用 git stash list 命令查看。
理论需结合实践,用的多了自然也就会对其熟悉了,下面针对一些容易引起使用者疑惑的地方进行总结及扩展。
虽然本人的 rebase 操作是用于同一分支中 commit 合并,但其实也可以应用于不同的分支间获取需要的 commit,如:A 分支和 B 分支在某个点分叉了,各自有相应的提交,但 B 分支想要 A 分支后续的 commit,就可以执行 rebase 操作,将其取来(git rebase master B)。这样的需求 cherry-pick 也可以做到。同样可以做到的还有打 patch 包。既然他们都可以做到,那有什么不同或是适用的场景。下面我来简单的比较一下。
cherry-pick | patch | rebase | |
相同点 | 都可以将其它分支上的 commit 拿来,从而应用于自己的分支 | ||
灵活/操作简便 | 最高 | 最差 | 中间 |
文本保留 | - | 最好 | - |
分支管理 | 中间 | 最差 | 最好 |