情景一 文件被修改,还没有git add。
这时候文件还没有被添加到object database中,可以使用index中的版本来覆盖工作区。
git checkout -- [filename]
情景二 文件被修改,且已经git add。
此时修改过的文件已经作为一个新的object添加到object databse中,可以使用当前HEAD中的版本来覆盖index。
这时候文件还没有被添加到object database中,可以使用index中的版本来覆盖工作区。
git reset HEAD -- [filename]如果还想重置工作区,可以继续:
这时候文件还没有被添加到object database中,可以使用index中的版本来覆盖工作区。
git checkout -- [filename]
情景三 已经提交commit,需要撤销commit。
这种情况又分为多种子情景,详细讨论,首先给出一个模拟的提交历史,从左到右一次提交,master执行提交H。
A---B---C---D---E---F---G---H | master子情形1. 要撤销最近1个commit,要撤销H。
可以使用2个命令:
git reset --hard G或
git revert H二者区别在于git reset不会产生新的提交,而是将分支指向指定的commit,生成的提交历史为:
A---B---C---D---E---F---G---H | master而git revert会产生一个新的提交,生成的提交历史为:
A---B---C---D---E---F---G---H---I | master
子情形2. 要撤销的提交不是最新的提交,即在错误提交之后又有若干个提交。
比如我们想撤销E,F两个提交,此时git reset已经无法胜任,因为我们在E,F后又有多个正常提交。这时可以使用git revert,但是要操作两次。这种情况下,推荐使用git rebase:
git rebase --onto D G^ H
情形四 执行merge操作,但是遇到conflict,想要撤销merge操作。
此时并为生成新的提交,当前分支头并未移动,因此可以简单的:
git reset --hard HEAD
情形五 执行merge操作,且已生成新的提交,要撤销merge操作。
这是简单的git revert
git revert -m [parent-number] [refs]-m指定要采用哪条主线(编号从1开始)。
如果还有其他情形本文未考虑到,请留言写出,大家一起讨论。
没有评论:
发表评论