如何轻松撤消git重基?冗长的手动方法是:
签出两个分支的提交父级创建并签出临时分支手工挑选所有提交重置故障的重基分支以指向临时分支
在我目前的情况下,这是可行的,因为我可以很容易地发现两个分支的提交(一个是我的东西,另一个是同事的东西)。然而,我的方法给我的印象是次优且容易出错(假设我刚刚用自己的两个分支重新建立了基础)。
澄清:我所说的是一个重基,在重基过程中,多次提交被重复,而不仅仅是一次。
如何轻松撤消git重基?冗长的手动方法是:
签出两个分支的提交父级创建并签出临时分支手工挑选所有提交重置故障的重基分支以指向临时分支
在我目前的情况下,这是可行的,因为我可以很容易地发现两个分支的提交(一个是我的东西,另一个是同事的东西)。然而,我的方法给我的印象是次优且容易出错(假设我刚刚用自己的两个分支重新建立了基础)。
澄清:我所说的是一个重基,在重基过程中,多次提交被重复,而不仅仅是一次。
当前回答
如果您在分支机构,可以使用:
git reset --hard @{1}
HEAD不仅有一个引用日志(通过git reflog获得),每个分支也有reflog(通过gitreflog<branch>获得)。所以,如果您在master上,那么git-relog master将列出该分支的所有更改。您可以通过master@{1}、master@{2}等引用这些更改。
gitrebase通常会多次更改HEAD,但当前分支只会更新一次。
@{1} 只是当前分支的快捷方式,因此如果您在master上,它等于master@{1}。
git reset——如果在交互式重基过程中使用git rese,硬ORIG_HEAD将无法工作。
其他回答
实际上,rebase将您的起点保存到ORIG_HEAD,因此这通常很简单:
git reset --hard ORIG_HEAD
然而,reset、rebase和merge都会将原始HEAD指针保存到ORIG_HEAD中,因此,如果您在尝试撤消rebase之后执行了这些命令,则必须使用reflog。
最简单的方法是找到分支的头部提交,因为它在reflog中的rebase开始之前。。。
git reflog
并将当前分支重置为它(通常需要注意的是,在使用--hard选项重设种子之前要绝对确定)。
假设ref日志中的旧提交是HEAD@{2}:
git reset --hard HEAD@{2}
在Windows中,您可能需要引用引用:
git reset --hard "HEAD@{2}"
您可以通过执行git-log head@{2}(Windows:git-log“head@{2}”)来检查候选旧标头的历史记录。
如果您没有禁用每个分支的reflog,您应该能够简单地执行gitreflog branchname@{1},因为在重新连接到最终头之前,rebase会分离分支头。我会再次检查这个,尽管我最近没有验证过。
默认情况下,为非裸存储库激活所有reflog:
[core]
logAllRefUpdates = true
如果您在分支机构,可以使用:
git reset --hard @{1}
HEAD不仅有一个引用日志(通过git reflog获得),每个分支也有reflog(通过gitreflog<branch>获得)。所以,如果您在master上,那么git-relog master将列出该分支的所有更改。您可以通过master@{1}、master@{2}等引用这些更改。
gitrebase通常会多次更改HEAD,但当前分支只会更新一次。
@{1} 只是当前分支的快捷方式,因此如果您在master上,它等于master@{1}。
git reset——如果在交互式重基过程中使用git rese,硬ORIG_HEAD将无法工作。
尽管这些答案应该是自动的(至少大部分是自动的),但没有一个答案是完全自动的,这让我非常恼火。我创建了一组别名来尝试解决这个问题:
# Useful commands
#################
# Undo the last rebase
undo-rebase = "! f() { : git reset ; PREV_COMMIT=`git x-rev-before-rebase` && git reset --merge \"$PREV_COMMIT\" \"$@\";}; f"
# See what changed since the last rebase
rdiff = "!f() { : git diff ; git diff `git x-rev-before-rebase` "$@";}; f"
# Helpers
########
# Get the revision before the last rebase started
x-rev-before-rebase = !git reflog --skip=1 -1 \"`git x-start-of-rebase`\" --format=\"%gD\"
# Get the revision that started the rebase
x-start-of-rebase = reflog --grep-reflog '^rebase (start)' -1 --format="%gD"
您应该能够对其进行调整,以允许非常容易地返回任意数量的重基(处理参数是最棘手的部分),如果您连续快速地进行了多次重基,并在过程中搞乱了一些事情,这将非常有用。
注意事项
如果任何提交消息以“rebase(start)”开头(请不要这样做),这会让人感到困惑。通过为正则表达式匹配以下内容,可以使正则表达式更具弹性以改善情况:
--grep-reflog "^rebase (start): checkout "
警告:未测试(正则表达式可能需要调整)
我之所以没有这样做,是因为我不是百分之百地认为重新启动总是从结账开始。有人能证实这一点吗?
[如果您对函数开头的null(:)命令感到好奇,这是为别名设置bash补全的一种方法]
git reset --hard origin/{branchName}
是重置rebase所做的所有本地更改的正确解决方案。