Git的工作流分享
假设一开始在github上有一个仓库,这个仓库的主分支是main(原来是master),假设一开始只有一个commit叫做Init。同时,这样一个所有人都共享的远端的代码仓库(在Github上)叫做remote。
Local Git就是本地的git仓库,这里保存着所有你告诉git的信息。
Disk是磁盘,即存储文件的地方。
当我们想修改或者贡献代码时,要做的第一件事就是将remote仓库复制到本地。
我们可以通过git clone命令将remote仓库一模一样地复制到本地。
注意,在刚刚执行完git clone操作后,remote,local和disk的状态都是一样的。
git clone https://github.com/example/example.git
当我们要修改代码的时候,第一件事就是要新建一个分支,即feature/branch,而不是直接往主分支main上push代码。这样子有利于项目管理,如果加任何新功能都往主分支上push代码,可能会导致主分支不能工作。如果是多人同时协作的场景,更要对主分支进行保护,当其他人的功能分支要合并到主分支时,需要进行Code Review等手段保证代码是正常运行的。
建立分支的命令是git checkout
建立feature/branch的方法是使用git checkout -b my-feature命令,-b意味着branch,即创建新分支,这条指令合起来意思是创建并切换到my-feature分支。相当于复制了一份main branch到my-feature branch上。
git checkout -b my-feature
接下来就可以开始愉快地修改代码了,当把代码改好之后保存后,disk硬盘上的文件是有变化的,但是git对此一无所知,这个时候我们可以使用git diff命令来看disk硬盘上的改变和git保存的分支有什么区别。
git diff
当我们决定把修改之后的文件告诉git的时候,就可以使用git add <filename>,该命令的参数就是要修改文件的文件名字。这个命令会把这个文件加入到暂存区中。
git add <changed_file>
如果要把当前路径下所有的文件都添加到暂存区中,可以使用以下命令:
git add .
- 工作区:用来编辑保存项目文件的地方,也是用户能直接操作到的地方。
- 暂存区:保存了下次将提交的文件列表信息,一般在 Git 仓库目录中,是一个叫index的文件,通常多数说法还是叫暂存区域;
- 版本库:也叫本地版本库,之所以说git 快,是因为它是分布式版本控制系统,大部分提交都是对本地仓库而言的,不依赖网络,最后一次会推送的到远程仓库。
在用git add 添加了所有想要修改的文件之后,就可以使用git commit命令来把这些修改真正地放到git里,该命令的参数是你想要commit的注释信息,比如描述修改了代码的哪些内容,实现了什么功能等等。此时可以发现我们的local git新增了一个commit。此时我们的my-feature branch和main branch已经不一样了。
git commit "Your Commit Message"
到目前为止,我们只是把代码改动告知了local git,但是对于remote git(即远端的github代码仓库)对此是一无所知的。因此我们需要将改动也告知给远端仓库。这个时候我们可以使用git push命令。在使用这个命令之后,可以发现github多出来了一个my-feature branch,远端的my-feature branch和本地的my-feature branch是一致的。
git push origin my-feature
有一个非常常见的情况是,在我们将我们的代码push到远端仓库之后,main branch的代码有了更新(比如你的同事增加了新的功能),发现main branch有了一个新的update commit。我们可能需要测试一下我们的代码在新的这个update commit下是不是正常工作。所以需要把main branch的更新同步到my-feature branch中。
为了做这件事,我们首先要同步我们的local git。我们可以看到当前我们的local git的main branch是和远端仓库的main branch是不一样的。首先我们需要将local git的branch从my-feature branch切换到main branch。使用git checkout命令。这个时候我们硬盘的源代码就是Init的状态。
git checkout main
在checkout切换完分支之后我们使用git pull命令。具体命令如下:
git pull origin master
这段命令的意思是把远端的main branch同步到本地的main branch,做完这个操作之后,远端update这个commit就会同步到本地。
然后我们需要回到我们的my-feature branch,使用git checkout命令。
git checkout my-feature
那当前的源代码就是有我们修改的f-commit的变化但是没有远端的update的变化。
为了同步main代码的改变,使用命令git rebase main
git rebase main
这段命令的意思是把我的修改先扔到一边,然后把main最新的修改拿过来,接着在这个最新修改的基础之上,再把我的这个commit给尝试弄回去。在这个过程中可能会有rebase conflict。如果出现了rebase conflict,就需要自己手动选择要哪一段代码。rebase成功之后,代码就变成了现在这个样子:相当于在最新的update commit之后做了我们的修改。这也是使用rebase而不是merge的好处。
在更新完my-feature branch之后,就需要使用git push将local git的变动push到remote git上。由于我们做了rebase,因此需要使用-f参数,表示强制push。
git push -f origin my-feature
到此,一切准备就绪。我们就要把我们更新的代码合并到main branch上。这个过程叫做pull request。pull request的意思是项目的主人将这个新的分支的改变给pull到项目里面去。
在这个项目main branch的维护者,审查了代码之后,一般情况下会用squash and merge,意思是把这一个分支上面的所有改变合并成一个改变/commit,然后把这个commit放到main branch上。这样子就保持了commit history的简洁。尤其希望main branch上的每一个commit都是正常工作的。
最后,我们将github上的my-feature分支删除,并且将local git上的my-feature分支删除。然后我们在本地切换回main分支,再使用git pull命令把main最新的更新给pull到local git。经过了这些操作之后,我们的local git,remote git,disk又保持一致了。
git pull origin master
引用资料
大家可以看这个视频对Git获得更加深刻的理解。