心情日记 - Git 补锅记
纯粹记录职场发生的事情,不作专业知识分享~
人物介绍
- 我:被迫成为 Git 专家的菜鸟程序员
- 同事小W:无辜的受害者
- 打靶领导:Git 操作灾难制造者
事件经过
第一阶段:功能开发
- 分支A 编写了 A功能
- 提交分支A到test分支
- 分支B 编写了 B功能
- 提交分支B到test分支,发现有冲突,直接采用分支B代码覆盖了分支A代码
第二阶段:灾难开始
- 同事小w拉取test分支代码本地无法运行,发现功能A调用的一个函数不存在,注释了调用方法
- 第二天
- 前端同事说功能A怎么查询都没结果
- 打靶领导:"你去看一下代码看看功能A有没有问题"
- 小w说:"功能A调用的方法不存在,我直接在test分支注释掉代码了"
- 打靶领导:"你去从新弄一下吧,再合并"
- 我:"我tm头都大了,我哪弄过这种东西啊?" 😭
代码演变过程
初始代码
func CookFish() {
fmt.Println("鱼已经煮完了")
}
领导的 A 功能
func CookFish() {
AddSalt()
fmt.Println("鱼已经煮完了")
}
func AddSalt() {
fmt.Println("加盐")
}
领导的 B 功能
func CookFish() {
Deboning()
fmt.Println("鱼已经煮完了")
}
func Deboning() {
fmt.Println("拔掉鱼刺")
}
小W的功能
func CookFish() {
fmt.Println("小A我要负责挑一条鲜活的鱼")
fmt.Println("小A我还要负责用最少的钱买最好的鱼")
fmt.Println("鱼已经煮完了")
}
混乱合并过程
打靶领导合并分支(灾难开始)
这时代码已经是跑不起来了,报AddSalt()方法不存在
func CookFish() {
AddSalt()
Deboning()
fmt.Println("鱼已经煮完了")
}
func Deboning() {
fmt.Println("拔掉鱼刺")
}
小W被迫修复(继续恶化)
发现AddSalt报错注释掉然后继续开发自己的功能
func CookFish() {
//AddSalt()
Deboning()
fmt.Println("小A我要负责挑一条鲜活的鱼")
fmt.Println("小A我还要负责用最少的钱买最好的鱼")
fmt.Println("鱼已经煮完了")
}
func Deboning() {
fmt.Println("拔掉鱼刺")
}
问题爆发
过了一天,前端反馈为什么这鱼怎么传参都不咸?打靶领导就叫我去看一下他的代码,小W就说他昨天测试分支的代码报错,注释掉错误了。
打靶领导就叫我去看一下他的A功能分支的代码,我就震惊了。
冷静分析,现在A功能之前已经被合并过了,在不改动的情况下合并是没反应的。
解决过程
尝试 revert(失败)
git checkout Test
git revert 提交哈希 -m 1
失败原因:同事在注释这一行报错代码之后,还提交了很多次代码到Test分支,改了这个去测试还有其他报错
AI助手提供的解决方案
你遇到的是一个典型的 "分支被他人修改后如何安全重新同步" 的协作问题:
- 恢复分支 A 中被他人修改/注释/删除的代码
- 保留 Test 分支上其他人新增的功能提交
- 生成清晰、可追溯的提交记录
方案一:恢复单个文件(失败)
git checkout A -- path/to/your/file.go
失败结果:整个文件变成了功能A的代码,其他都丢失了
方案二:创建临时分支模拟合并(成功)
步骤详解:
# 1. 基于当前 Test 创建临时分支
git checkout -b temp-merge-fix
# 2. 将分支 A 的提交"变基"或"合并"进来
git cherry-pick <commit-id-from-A-that-modified-the-file>
# 3. 如果有冲突,Git 会自动标记
# 解决冲突后:
git add .
git cherry-pick --continue
# 4. 回到 Test,应用修复后的文件
git checkout Test
git checkout temp-merge-fix -- path/to/file.go
# 5. 提交并清理
git commit -m "fix: ..."
git branch -d temp-merge-fix
核心命令
重点:
git cherry-pick 提交哈希
执行后会按功能A分支和Test分支进行冲突提示,然后按需把功能A的代码传入Test分支,然后提交就行了。
最终解决方案
最终代码
func CookFish() {
AddSalt()
//AddSalt() // 这行是历史遗留,需要删除
Deboning()
fmt.Println("小A我要负责挑一条鲜活的鱼")
fmt.Println("小A我还要负责用最少的钱买最好的鱼")
fmt.Println("鱼已经煮完了")
}
func AddSalt() {
fmt.Println("加盐")
}
func Deboning() {
fmt.Println("拔掉鱼刺")
}
最终操作
删除重复的 //AddSalt() 注释,提交即可。
总结
这是一个典型的 Git 协作灾难案例,通过 cherry-pick 命令巧妙地解决了分支冲突问题,既保留了必要的功能代码,又修复了错误的修改。