- 作者:老汪软件技巧
- 发表时间: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 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 步骤是必需的。