• 作者:老汪软件技巧
  • 发表时间:2024-10-31 21:01
  • 浏览量:

一个项目经常会由多人共同维护,即便我在开发之初拉取了最新的代码,但当我编写完代码要提交时,很有可能有其他同事已经在此分支提交了新的代码。那么我将面临如下问题:

如何让提交历史保持线性而不是麻花状交错在一起?出现分支合并后,如何将多条分支合并为一条?1. 保持提交历史为一条主线的最佳实践:

# 1. 始终在开始新功能前,先同步最新代码
git checkout master
git pull origin master
# 2. 创建新的功能分支
git checkout -b feature/new-feature
# 3. 在功能分支上开发并提交
git add .
git commit -m "feat: add new feature"
# 4. 【重要】在合并代码之前,先切到主分支并同步主分支代码为最新代码(因为rebase前会拉取主分支代码)
git checkout master
git pull origin master
# 5. 在功能分支进行变基操作(此操作后,变更的代码还未同步到主分支)
git checkout feature/new-feature
git rebase master
# 6. 如果需要,可以将多个提交合并为一个
git rebase -i HEAD~3  # 合并最近3个提交
# 7. 【重要】切换回主分支并合并功能分支(此操作后,主分支同步了功能分支的代码)
git checkout master
git merge feature/new-feature  # 这将是快进合并
# 8. 推送到远程仓库
git push origin master
# 9. 可选:删除功能分支
git branch -d feature/new-feature
git push origin --delete feature/new-feature  # 删除远程分支

2. 当出现多条分支时,合并分支的主要方法:A. 使用 merge 合并(保留完整历史):

# 1. 切换到目标分支
git checkout master
# 2. 合并功能分支
git merge feature/new-feature
# 3. 解决冲突(如果有)后提交
git add .
git commit -m "merge: feature branch into master"

B. 使用 rebase 合并(创建线性历史):

# 1. 切换到需要合并的功能分支
git checkout feature/new-feature
# 2. 将主分支的更新变基到功能分支
git rebase master
# 3. 解决冲突(如果有)
git add .
git rebase --continue
# 4. 切换回主分支进行快进合并
git checkout master
git merge feature/new-feature

C. 使用 squash merge(将整个分支压缩为一个提交):

# 1. 切换到主分支
git checkout master
# 2. 使用 squash merge
git merge --squash feature/new-feature
# 3. 提交更改
git commit -m "feat: add feature (squashed)"

关键建议:

团队开发准则:

预防分支混乱:

修复错误合并:

# 如果合并出错,或者已经合并,可以撤销
git reset --hard HEAD~1  # 撤销最近一次合并
# 或
git reset --hard ORIG_HEAD  # 撤销最近一次合并操作

在团队协作时如何管理 Git 分支和提交历史_在团队协作时如何管理 Git 分支和提交历史_

查看分支情况:

# 查看分支图
git log --graph --oneline --all
# 查看所有分支
git branch -a
# 查看已合并的分支
git branch --merged

3.git rebase底层实现过程rebase 的作用:当你在 feature 分支上执行 git rebase master 时,Git 会:

# 执行 rebase 前:
      A---B---C (feature)
     /
D---E---F---G (master)
# 执行 rebase 后:
              A'--B'--C' (feature)
             /
D---E---F---G (master)

为什么还需要合并:

# 执行 merge 后:
D---E---F---G---A'---B'---C' (master, feature)

简化的操作步骤对比:

不使用 rebase 直接 merge:

# 在 feature 分支
git checkout master
git merge feature  # 创建一个合并提交
# 结果:
      A---B---C (feature)
     /         \
D---E---F---G---H (master) # H 是一个合并提交

使用 rebase 后 merge:

# 在 feature 分支
git rebase master  # 将 feature 分支移到 master 分支最新位置后面
git checkout master
git merge feature  # 快进合并,不会创建新的合并提交
# 结果:
D---E---F---G---A'---B'---C' (master, feature) # 完全线性的历史

关键区别:可以跳过最后的 merge 吗?

如果你只是想在 feature 分支上工作,不需要将更改合并回 master,那么确实可以跳过最后的 merge 步骤。但如果你想将更改整合到主分支中,merge 步骤是必需的。