一套常用的工作流
Git 可以分为 Remote
、 Local
,其中 Remote
代表远程仓库比如 Github, Local
又可以分为两个部分,一个部分就是我们拉下来的 Local git,另一个部分则是Disk
磁盘部分,这部分是我们源文件真正存在磁盘里面的样子,我们用 VSCODE 之类的编辑器修改都是在这个部分进行的。
初始状态:
Remote
- main(master)
- Initial commit
- main(master)
Local
- main(master)
- Initial commit
- main(master)
Disk
- main(master)
- Initial commit
- main(master)
1. 本地修改
在我们要修改代码的时候,第一件事是建立一个新的 feature branch(名字自定),然后在这个分支上进行修改,而不是直接在 main 分支上进行修改,这样做的好处是,它可以让我们在修改的时候,不会影响到其他人的工作,也不会影响到 main 分支,这样就可以保证 main 分支的稳定性。
git checkout -b feature-branch
这时我们的状态应该是这样的:
Remote
- main(master) 这个分支一般被认为是公共的分支,所以不要在这个分支上直接进行修改
- Initial commit
- main(master) 这个分支一般被认为是公共的分支,所以不要在这个分支上直接进行修改
Local
- main(master)
- Initial commits
- feature-branch 这个分支是我们自己建立的,认为是个人的部分,用来进行修改的
- Initial commit
- main(master)
Disk
- feature-branch
- Initial commit -> ...changes...(还未放入暂存区)
- feature-branch
2. 将修改真正放到 git 里面
在使用 git add <changed_file> 放入暂存区之前,推荐先使用 git diff 查看修改的内容,之后在用 git add <changed_file>告知 git 修改了的部分,最后用 git commit 来把修改真正放到 git 里面。
此时我们的状态应该是这样的:
Remote
- main(master)
- Initial commit
- main(master)
Local
- main(master)
- Initial commits
- feature-branch
- Initial commit -> changed-commit
- main(master)
Disk
- feature-branch
- Initial commit -> changed-commit(实际上 Disk 是没有 commit 概念的,这里这样写只是为了方便理解)
- feature-branch
3. 将修改的分支推送到远程仓库
git push origin feature-branch
此时我们的状态应该是这样的:
Remote
- main(master)
- Initial commit
- feature-branch
- Initial commit -> changed-commit
- main(master)
Local
- main(master)
- Initial commits
- feature-branch
- Initial commit -> changed-commit
- main(master)
Disk
- feature-branch
- Initial commit -> changed-commit
- feature-branch
4. 合并分支
在我们合并分支之前,我们经常会遇到这样的情况,就是 main(master) 分支上的代码已经更新了,而我们的 feature-branch 分支上的代码还是旧的,这时候我们就需要先将 main 分支上的代码拉下来。首先我们需要切换到 main 分支上(git checkout main),然后使用 git pull origin main 来拉取 main 分支上的代码,这时我们的状态应该是这样的:
此时我们的状态应该是这样的:
Remote
- main(master)
- Initial commit -> update1
- feature-branch
- Initial commit -> changed-commit
- main(master)
Local
- main(master)
- Initial commits -> update1
- feature-branch
- Initial commit -> changed-commit
- main(master)
Disk
- feature-branch
- Initial commit -> changed-commit
- feature-branch
然后我们要用 git checkout feature-branch 回到我们的 feature-branch 分支上,然后使用 git rebase main 或者 git merge main 来合并 main 分支上的代码,如果有冲突代码的部分,我们需要手动选择需要留下的部分。
这时我们的状态应该是这样的:
Remote
- main(master)
- Initial commit -> update1
- feature-branch
- Initial commit -> changed-commit
- main(master)
Local
- main(master)
- Initial commits -> update1
- feature-branch
- Initial commit -> update1 -> changed-commit
- main(master)
Disk
- feature-branch
- Initial commit -> update1 -> changed-commit
- feature-branch
5. 将合并后的分支推送到远程仓库
git push -f origin feature-branch
因为我们使用了 rebase 或者 merge 修改了 commit 的历史,所以我们需要使用 -f 参数来强制推送。
此时我们的状态应该是这样的:
Remote
- main(master)
- Initial commit -> update1
- feature-branch
- Initial commit -> update1 -> changed-commit
- main(master)
Local
- main(master)
- Initial commits -> update1
- feature-branch
- Initial commit -> update1 -> changed-commit
- main(master)
Disk
- feature-branch
- Initial commit -> update1 -> changed-commit
- feature-branch
6. 合并(PR)分支到主分支
我们可以在 github 上使用 New pull request
按钮,将我们的分支合并到主分支上。在项目的维护者审查完代码之后,一般情况下会使用 Squash and merge
按钮来合并分支。因为我们新增的 Commit 可能会有很多,这时候我们希望我们的 main(master) 分支尽可能的简洁,所以我们会将多个 Commit 合并成一个 Commit。
此时我们的状态应该是这样的:
Remote
- main(master)
- Initial commit -> update1 -> update2
- feature-branch
- Initial commit -> update1 -> changed-commit
- main(master)
Local
- main(master)
- Initial commits -> update1
- feature-branch
- Initial commit -> update1 -> changed-commit
- main(master)
Disk
- feature-branch
- Initial commit -> update1 -> changed-commit
- feature-branch
一般情况下,合并完成之后我们就可以删除我们的 feature-branch 分支了,在 github 上有个 Delete branch
按钮,我们可以使用这个按钮来删除我们的分支。接下来是删除本地的分支,我们先使用 git checkout main 切换到 main 分支上,然后使用 git branch -D feature-branch 来删除本地的分支。最后使用 git pull origin main 来更新本地的代码。
最后我们的状态应该是这样的:
Remote
- main(master)
- Initial commit -> update1 -> update2
- main(master)
Local
- main(master)
- Initial commits -> update1 -> update2
- main(master)
Disk
- main(master)
- Initial commits -> update1 -> update2
- main(master)