git工作流

yuanheci 2025年02月13日 130次浏览

搬运自牢瑞的博客:https://brrblog.netlify.app/SkillShared/git.html


git rebase

step1. 项目初始化

  • romote — main(master) [init]
  • localGit
  • disk
    首先,拉取项目到自己本地。
git clone <url/ssh>

之后,切换到最新分支main/master(为方便叙述,后续段落统一使用 main),并新建分支,切换到对应分支。

git checkout main
git branch <namedev_branch>
git checkout <namedev_branch>

之后便可进行开发工作。

step2. 日常开发

  • romote — main(master) [init]
  • localGit
    • main(master) [init]
    • <namedev_branch> [init]
  • disk [init]
    如上,完成初始化后,我们的代码管理的状态,注意disk中不包含任何分支信息,它只存储当前最新代码。

日常的代码处理为如下步骤:

git add .
git commit -m "feat: ..."
git push -u origin <namedev_branch>

step3. 检查origin状态

若 origin 的 main 分支代码未发生更新:
在完成日常开发任务并提交远程分支后,我们会获取到如下状态:

  • romote
    • main(master) [init]
    • <namedev_branch> [init] --> [my-commit]
  • localGit
    • main(master) [init]
    • <namedev_branch> [init] --> [my-commit]
  • disk [my-commit]
    则跳转 step5 进行合并。

若 origin 的 main 分支代码发生更新:
在完成日常开发任务并提交远程分支后,我们会获取到如下状态:

  • romote
    • main(master) [init] --> [update]
    • <namedev_branch> [init] --> [my-commit]
  • localGit
    • main(master) [init]
    • <namedev_branch> [init] --> [my-commit]
  • disk [my-commit]
    则进行 step4 同步修改。

step4. rebase

明确一点,一切以主分支上代码为基准,主分支更新,本地的更新必须建立在主分支更新上。

所以,首先在本地,切换到主分支,获取更新。

git checkout main
git pull origin main

此时的代码状态为:

  • romote
    • main(master) [init] --> [update]
    • <namedev_branch> [init] --> [my-commit]
  • localGit
    • main(master) [init] --> [update]
    • <namedev_branch> [init] --> [my-commit]
  • disk [init] --> [update]
    之后,切换到私人分支,进行 rebase 在本地合并代码。
git checkout <namedev_branch>
git rebase main

解释一下 rebase 操作,先将个人的修改 [my-commit] 扔一边,先同步主分支的 [update] ,之后在 [update] 的基础上进行 [my-commit] 的修改。
自然地,这个过程可能出现 rebase conflict,即代码冲突,这时候就需要手动选择保留哪一段代码。

这里再补充一下git merge和rebase的区别:
image-1739427909971

这两种方法之间的最大区别在于,merge保留了commit的完整历史记录,包括按时间顺序排列,而rebase使提交变得整洁,仅与分支上的commit相关。
Merge具有更高的可追溯性,而Rebase则更整洁且易于审核。

若 rebase 操作成功,再将结果push到远程个人分支。

git push -f origin <namedev_branch>

由于进行了 rebase 操作,所以需要使用 -f (force) 提示符。

之后获取到如下的代码状态:

  • romote
    • main(master) [init] --> [update]
    • <namedev_branch> [init] --> [update] --> [my-commit]
  • localGit
    • main(master) [init] --> [update]
    • <namedev_branch> [init] --> [update] --> [my-commit]
  • disk [init] --> [update] --> [my-commit]

step5. PR合并代码

恭喜,已经完成了所有的准备工作,现在可以提 PR 了。

以 GitHub 为例,作为开发者,只需要新建 PR 请求,即点击 [New pull request] 按钮,请求将私人分支的代码更新合并到主分支。

作为项目所有者,或管理员,会收到 PR 请求,可以选择合并或拒绝,以合并为例,点击 [Squash and merge] 合并代码。

Squash(压缩) 就是将分支上的所有改动 commit 合并到一个 commit(这里称作update2) ,这是必要的,分支上可能有许多小改动,而我们希望主分支的每一次代码版本都是可用且功能完整的。

一般来说,在仓库所有者合并代码后,开发者需要删除个人开发分支,远程个人分支可以在GitHub上操作,本地分支操作如下:

git checkout main
git branch -d <namedev_branch>
git pull origin  main

此时代码状态:

  • romote
    • main(master) [init] --> [update] --> [update2]
  • localGit
    • main(master) [init] --> [update] --> [update2]
  • disk [init] --> [update] --> [update2]
    至此,一整套代码管理工作流程完成。

git rebase -i (交互式变基)


MR conflict

问题:
  当我的dev分支发起MR时发生了冲突,于是我在本地dev上merge master,手动解决了dev上的冲突,然后push到远程的dev,此时我的mr会发生什么?

回答:
  当在本地 dev 分支上合并 master 分支,手动解决了冲突并将修改后的 dev 分支推送到远程 dev 分支后,对应的 Merge Request(MR)通常会发生以下变化:

  1. MR 状态更新
    冲突状态解除:原本 MR 可能因为存在冲突而处于冲突状态,在你解决冲突并推送更新后,Git 托管平台(如 GitLab、GitHub 等)会自动检测到远程 dev 分支的更新,并且重新检查合并情况。如果冲突已经完全解决,MR 的冲突状态会被解除,显示为可以合并。
    更新评审信息:平台会提示评审人员 MR 有新的更新,评审人员可以查看你解决冲突的具体修改内容。
  2. 代码差异展示更新
    新的代码对比:MR 页面上的代码差异展示会更新为最新的 dev 分支与目标分支(通常是 master 分支)之间的差异。由于你已经在本地合并了 master 分支的内容,所以新的差异展示中会包含你解决冲突后的最终代码,以及 dev 分支上其他未合并的新修改。
  3. 自动化流程触发
    持续集成(CI)任务:如果项目配置了 CI 流程,推送更新后的 dev 分支会触发新的 CI 任务。这些任务可能包括代码编译、单元测试、集成测试等。如果 CI 任务全部通过,这会增加 MR 被合并的可能性;如果有任务失败,评审人员可能会要求你进一步检查和修复问题。
  4. 评审流程继续
    重新评审:解决冲突后的 MR 需要重新经过评审流程。评审人员会检查你解决冲突的方式是否合理,是否引入了新的问题,以及代码是否符合项目的规范和要求。他们可能会提出新的评审意见或建议,你需要根据这些反馈进行进一步的修改。

示例说明
  假设你在 GitLab 上发起了一个从 dev 分支到 master 分支的 MR,由于 dev 分支和 master 分支对同一文件的相同部分进行了不同的修改,导致 MR 出现冲突。你在本地进行了如下操作:

切换到 dev 分支
git checkout dev

从远程仓库拉取最新的 dev 分支代码
git pull origin dev

合并 master 分支到 dev 分支
git merge master

手动解决冲突
...

将解决冲突后的文件添加到暂存区
git add <冲突文件路径>

提交修改
git commit -m "Resolve merge conflicts"

推送到远程 dev 分支
git push origin dev

  完成上述操作后,回到 GitLab 的 MR 页面,你会看到冲突状态消失,代码差异展示更新,并且可能会触发新的 CI 任务。评审人员也会收到通知,开始重新评审你的 MR。


git cherry-pick

git cherry-pick
git merge