【私人面试题】如果我在面试中问到git, 你又该如何应对?

如果我在面试中问到git,你又该如何应对?

本文从实际工作经验出发,叙述了工作种常见的、和git提交代码相关的场景问题,并从此场景中引申出的4点问题,并记录了这些问题的解决办法。

实际场景

我要开发两个功能A和B,公司目前实行的标准是:

  • 首先切换至main分支(也就是项目的主分支),使用git pull拉最新代码,然后使用git checkout -b feat/A切到开发分支,在feat/A上完成功能A的开发之后,commit然后push到远程仓库中;
  • 然后开始开发B功能,使用git pull拉最新代码,然后使用git checkout -b feat/B切到开发分支,在feat/B上完成功能B的开发之后,commit然后push到远程仓库中。

问题一

在feat/A上提交并推送至远程仓库之后,开始开发B功能,但是这个时候由于粗心,导致没有做切换到main,然后pull,然后checkout -b feat/B,所以此时我依然在feat/A上。开发完B功能之后,不小心commit了,但是没有push到远程仓库,请问此时我该如何做才能弥补错误,使提交符合规范?

我期望的答案

如果新的commit还没有被推送,处理的代价是最小的,按如下的步骤即可解决:

  1. 使用reset将提交内容返回到工作区
  2. stash feat B的内容
  3. 切换至主分支并拉新代码
  4. 创建B分支
  5. 将修改内容放到B分支上
  6. 提交并推送
bash 复制代码
# 使用reset将提交内容返回到工作区
git reset HEAD~
# stash feat B的内容
git stash
# 切换至主分支并拉新代码
git checkout main && git pull
# 创建B分支
git checkout -b feat/B
# 将修改内容放到B分支上
git stash pop
# 提交并推送
git add .
git commit -m "feat: B"
git push origin HEAD

问题二

在feat/A上提交并推送至远程仓库之后,开始开发B功能,但是这个时候由于粗心,导致没有做切换到main,然后pull,然后checkout -b feat/B ,所以此时我依然在feat/A上。开发完B功能之后,不小心commit了,并且push到了远程仓库,请问此时我该如何做才能弥补错误,使提交符合规范?

我期望的答案

如果新的commit已经被推送,处理起来是比较棘手的,但是又可以分成两种情况: 假设错误commit的hash值为:abc123

  • feat/A没有被合并到主分支
    1. 在feat/A上生成一次revert提交记录,覆盖B功能代码
    2. 将revert之后的本地分支推送到远程仓库
    3. 切换至主分支并拉新代码
    4. 创建B分支
    5. 使用cherry-pick将abc123提交记录复制一份到B分支上
    6. 提交并推送
bash 复制代码
# 在feat/A上生成一次revert提交记录,覆盖B功能代码
git revert abc123
# 将revert之后的本地分支推送到远程仓库
git push origin HEAD -f
# 切换至主分支并拉新代码
git checkout main && git pull
# 创建B分支
git checkout -b feat/B
# 使用cherry-pick将abc123提交记录复制一份到B分支上
git cherry-pick abc123
# 提交并推送
git add .
git commit -m "feat: B"
git push origin HEAD
  • feat/A已经被合并到主分支
    1. 回到主分支,拉取最新代码,创建然后切换到一个名为fix/revert-A的分支
    2. 在fix/revert-A分支上使用revert abc123覆盖B功能代码
    3. 将fix/revert-A分支推送到远程仓库并联系组长合并到主分支
    4. 切换至主分支并拉新代码
    5. 创建B分支
    6. 使用cherry-pick将abc123提交记录复制一份到B分支上
    7. 提交并推送
bash 复制代码
# 回到主分支,拉取最新代码,创建然后切换到一个名为fix/revert-A的分支
git checkout main && git pull && git checkout -b fix/revert-A
# 在fix/revert-A分支上使用revert abc123覆盖B功能代码
git revert abc123
# 将fix/revert-A分支推送到远程仓库并联系组长合并到主分支
git add . && git commit -m "fix: revert" && git push origin HEAD
# 切换至主分支并拉新代码
git checkout main && git pull
# 创建B分支
git checkout -b feat/B
# 使用cherry-pick将abc123提交记录复制一份到B分支上
git cherry-pick abc123
# 提交并推送
git add .
git commit -m "feat: B"
git push origin HEAD

问题三

使用revert之后,导致feat/A中commit记录多了一次revert记录,我不想要这个revert记录,如何使其消失?

我期望的答案

这属于问题二的第一种情况,只需在执行``之前rebase一下,将revert记录抹平即可: 假设在feat/A上正常提交A功能产生的commit的记录的hash值为:xyz456

bash 复制代码
# 在feat/A上生成一次revert提交记录,覆盖B功能代码
git revert abc123
# 使用rebase抹平此次revert记录
git log # 找到xyz456
git rebase -i xyz456^ # 表示将xyz456这个commit之后的提交合成一个
# 根据自己的需要填表,保存,关闭;其实就是把自己不想要的commit前面的pick改成fixup

# 将revert之后的本地分支推送到远程仓库
git push origin HEAD -f
# 切换至主分支并拉新代码
git checkout main && git pull
# 创建B分支
git checkout -b feat/B
# 使用cherry-pick将abc123提交记录复制一份到B分支上
git cherry-pick abc123
# 提交并推送
git add .
git commit -m "feat: B"
git push origin HEAD

问题四

刚才提到了rebase,请问rebase和merge的区别是什么,使用时机有什么不同?

我期望的答案

  • 使用merge合并代码,会保留开发分支上的提交记录,这有利于之后定位问题和改bug;
  • 使用rebase不是commit记录的引用,而是对改动的复制,这样的方式不会保留分支上的提交记录;
  • 使用merge的缺点是会产生非常多的无用的提交日志;而使用rebase则恰好相反,没有足够多的提交信息;
  • 正如上面三个问题所述,在开发分支上使用rebase合并了自己不想要别人看到的revert提交记录,而合并到主分支main上的时候,总是以merge的方式;
  • 于是rebase主要用在私有分支内部,而merge主要用在私有分支向主分支合并的时候;
  • 总之,不论是使用merge还是rebase,核心依据是为了方便其他开发者,当然这也是为了方便自己。

最后

这就是我平时工作中遇到的问题,以及我希望我的同事在遇到这些问题之后的处理方式,并且我会把这个当成面试题积累下来,那么您有没有更好的做法呢?欢迎留言和吐槽~

相关推荐
ShineWinsu17 小时前
对于Git:远程操作的超详细保姆级解析
linux·git·gitee·github·远程仓库·分布式版本控制系统·远程操作
梦帮科技18 小时前
从 Guest 到 Platinum:Prompt 配额、API Key 与访问控制的安全闭环
javascript·git·架构·node.js·reactjs·html5·visual studio
zho_uzhou1 天前
Git入门概念
git
爱奥尼欧2 天前
【Git】远程分支删了本地还在、两个分支历史不相干?两招故障排解
开发语言·git
Java后端的Ai之路2 天前
Git冲突完整排查与实战:本地修改覆盖报错到成功推送全流程复盘
开发语言·人工智能·git·python·pop
一个心烑2 天前
配置项目git的 SSL 证书
git·网络协议·ssl
IT从业者张某某2 天前
【鸿蒙PC命令行适配】GitUI 移植的工程实践:双 Git 引擎(libgit2/gitoxide)的鸿蒙适配之路
git·华为·harmonyos
xinjia_ctrl2 天前
暑假实习总结
git·后端·spring·maven·intellij-idea
Molesidy2 天前
【Git】分别给出添加到Keil工程和IAR工程中的gitnore文件以便不跟踪编译文件的git记录
git·vscode·插件
颜颜yan_3 天前
Git Cola 鸿蒙 PC 版适配全记录:从 Qt 桌面工具到 ArkTS 原生应用
git·qt·harmonyos