如何保留最新Commit ID同时撤销其代码变更?
问题解答
首先明确:Git的commit ID是由提交的完整内容(包括代码快照、父提交指针、作者信息、提交说明等)通过哈希算法生成的唯一标识,只要提交的内容(哪怕是一行代码)发生变化,对应的commit ID必然会改变。所以你想要“撤销代码变更同时保留原commit ID”的需求,从Git的设计逻辑上来说是不可能实现的。
你的伪步骤存在的问题
git cherrypick G1完全没必要:因为你已经在包含G1的B1分支上,cherrypick重复提交会直接报错。git commit --amend会替换当前分支的最新提交,生成全新的commit ID,原G1的ID会被覆盖(仅本地未推送的情况下,原提交会变成游离状态,但不会保留在分支历史中)。
两种可行的替代方案
方案1:保留原提交记录(推荐,适合协作场景)
如果只是想撤销G1的代码变更,但希望保留G1的提交ID和历史记录(让团队能看到这个提交被撤销的过程),直接用git revert命令:
# 切换到B1分支 git checkout B1 # 生成一个新提交,内容为撤销G1的所有变更 git revert G1 # 推送到Gerrit git push origin B1
这个操作不会改写历史,原G1的ID和提交记录会完整保留在分支中,新增的撤销提交会和G1形成清晰的历史关系,是Gerrit协作场景下的标准做法。
方案2:改写原提交(不推荐,仅适合私有分支)
如果你非要让原提交的内容变成“撤销自身变更”的状态(但必然会生成新的commit ID),可以这样操作:
git checkout B1 # 软重置到G1的前一个提交,保留G1的代码变更 git reset HEAD^ --soft # 撤销所有代码变更,回到G1提交前的状态 git checkout . # 改写原提交(会生成新的commit ID) git commit --amend --no-edit # 强制推送到Gerrit(会覆盖远程分支的历史,仅限私有分支使用) git push origin B1 --force
注意:这个操作会改写远程分支的历史,会给其他协作者带来冲突和混乱,除非是你独自维护的私有分支,否则绝对不要这么做。
内容的提问来源于stack exchange,提问作者Dr. Essen
相关产品推荐
相关产品推荐

