Git常用工作流
学习并记录自 @码农高天 十分钟学会正确的 github 工作流
我们假设在 GitHub 上面有一个项目仓库,有一个主分支 main (master)。这个远端的,所有人都共享的代码仓库,叫做 Remote。
当我想要修改或者贡献代码的时候,第一步就是要 Remote 仓库复制到本地,可以使用 git clone
命令。
git clone https://github.com/example/example.git
这样就会在本地复制一个一模一样的仓库。
对于新手来说,我们可以把本地的仓库想象成两个部分,一个是 Local git,一个是 Disk。Local git 就是本地 .git
中的数据,而 Disk 就是本地真正的文件数据,也是我们使用 VsCode 打开的文件数据。
当然,在我们刚 clone 完,三者的数据是完全一致的。
在正式修改项目之前,需要先建立一个新分支(feature branch),命名为 my-feature。
git checkout -b my-feature
这个命令会复制一份当前 branch 到新 branch 上,即复制了一份 main 到 my-feature 上。
这样就不会把主分支搞乱,搞得不能工作,一切的改变都先在新分支中进行,不会影响到主分支。
这样在 Local 中就有了两个分支,但是需要注意在 Disk 上只会存在一个分支,当使用 checkout -b
参数时,git 会自动将当前 Disk 上的文件切换为新分支中的文件数据,而不会保留原分支的数据。
接着就可以使用代码编辑器对 Disk 中的代码进行修改。当我们修改完成时,Git 对修改是一无所知的,也就是 Local 并没有跟随 Disk 发生改变。
这时可以使用 diff 命令,
git diff
来查看 Disk 中的数据和 Local 上分支数据有什么区别和改变。
然后可以使用 add 命令,
git add <changed_file>
将修改后的文件放入暂存区中,告诉 Local 修改了哪些文件。即 Local git 知道了你有一些修改需要 commit。
再使用 commit 命令,
git commit
将这些修改真正放到 Local git 中。即 Local git 中会新增一个 commit 记录。
为了方便理解,这里将 Disk 中的内容也增加了一个 commit 记录,但是实际上 Disk 中的数据是没有发生改变的。这个 commit 中,就是我们自己在代码编辑器中做的改动。我们只是把这些改动告诉了 Local git,并更新了 Local git 中的数据。
到现在为止,GitHub,也就是 Remote git 还什么都不知道。我们需要把本地的这些改动告知 GitHub。
我们可以使用 push 命令,
git push origin my-feature
这样 Remote 就会多出来一个新的分支 my-feature,并且有本地的 commit 记录。
一个非常常见的场景就是,在我们修改代码时,Remote git 中的 main 分支又有了其他人提交的更新 update。这时我们就需要测试一下,我们所提交的 feature 在新的 update 代码下还是否能够正常运行。
所以我们需要把 main 分支中的更新同步到 my-feature 这个分支中。
首先,第一步就是要让 Local git 中的 main 分支数据更新为与 Remote 一致。
那么我们要先将本地的 Disk 切换到 main 分支的代码数据,
git checkout main
在这个分支下,我们在使用 pull 命令,拉取 Remote 最新的代码。
git pull origin master
这时 Local 和 Disk 中的数据就会更新为 Remote 最新的代码数据。
接着,第二步就是把 Disk 中的数据切换为 my-feature 分支数据,使用 checkout 命令,
git checkout my-feature
再使用 rebase 命令,先将 main 分支最新的代码合并到 my-feature 分支中。
git rebase main
rebase 命令的含义是,先不管我的 commit,把 main 分支最新代码合并到这个分支中,在此基础上,再尝试将我们的 commit 尝试弄回去。
这个过程中是有可能出现 rebase 冲突,这时需要手动选择保留哪段代码,以解决冲突。
这就相当于我们在 main 分支上直接进行修改,因为此时 my-feature 的结构与 main 分支是一致的。这是使用 rebase 而不是 merge 合并的好处。
当我们在 my-feature 上测试或者编写完 update 后的代码,第三步,就是使用 force push 命令将本地的代码推送到远程仓库。
git push -f origin my-feature
由于我们做了 rebase,所以在推送时需要加上 -f
,表示强制推送。
到此为止,我们对于代码的所有修改就已经完成了。最后就需要将 my-feature 中的修改合并到 main 分支中。
这个过程被称为 pull request。
my-feature 分支是属于个人的,和 main 分支,也许是同一个人,但是它们拥有着不同的角色。
pull request 的意思就是请求这个项目的主人(main 分支的主人),把我这个项目分支中的新改变 pull 到这个项目中去。
在 GitHub 中可以非常容易进入 pull request,一般项目的主人审查了代码后,会使用 Squash and merge 将代码合并。
Squash 的含义是将这个分支上的所有 commit 和修改都压缩成一个 commit 合并进 main 分支,这样就不会让 main 分支看起来很乱,并且可以保证每个 commit 都是独立可运行的。
也就是我们的这些修改,可能会变成 update 2 这一个 commit 记录出现在 main 分支中。
这里我们只有一个 commit 记录,现实场景中可能有多个 commit 记录,都会被压缩成一个 update 2 记录,里面的所有修改都是不变的。
被合并成功后,我们就可以删除远端的 my-feature 分支,GitHub 上有一个 Delete Branch 按钮可以很方便地删除。
除此之外,在我们本地地 Local git 中也需要删除这个分支,我们首先使用 checkout 命令,
git checkout main
把 Disk 中的数据切换成 main 分支,再使用 branch -D
命令删除本地的 my-feature 分支。
git branch -D my-feature
接着,再使用一次 pull 命令,
git pull origin master
将远程合并后的最新数据同步到本地 Local git 中。
至此整个工作流结束。