不丢失新提交的情况下回滚到上一个稳定提交

5
我是一个新手,对于git还不太熟悉,所以在做任何不可恢复的错误之前都会先询问... :-)
最近几天,我对项目进行了一些更改,以升级我使用的一些库的版本,但我失败了(也因为文档不足... :-()。
我只好放弃升级,现在需要回滚到上一个稳定提交。
我也已经推送到远程,但这不应该是问题,因为我目前是该项目唯一的开发者。
以下是我的当前git日志:
$ git log --oneline
22c0713 Upgrading to Firebase 1.1
6d5f9f4 Porting customers to angularfire 0.8
fd9db42 Porting to Angularfire 0.8
d728b82 Working out authenticating on authenticated session problems
d511245 Testing authWithOAuthRedirect
abd9849 Porting to firebase 1.1.2
8884b88 Testing loadRemote() with relative path on public repositories
7830eea Testing loadRemote() with relative path on public repositories
f36c2f5 Finished working on I18N
...

f36c2f5提交(上面我展示的最后一个)是最后一个稳定版本,我想要恢复到那个版本。

我还想避免丢失新的(不好的)提交,以备未来参考。

针对此任务,哪种策略最为可取?

更新:多谢您的回答,我差不多完成了(待会就要接受答案了……)。只有一个小问题:我也有一个“gh-pages”分支,用于将我的dist子文件夹推送到GitHub的gh-pages预备站点。
现在,在

git checkout -b my_branch_for_future_reference
git checkout master
git reset --hard f36c2f5
git push -f

进行中

git subtree push --prefix dist origin gh-pages

我遇到了这个错误:
git push using:  origin gh-pages
To git@github.com:MYUSER/MYREPO.git
 ! [rejected]        3febf7c0812441c7379710d0a1f5f1ec26adbd9e -> gh-pages (non-fast-forward)
error: failed to push some refs to 'git@github.com:MYUSER/MYREPO.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

我查了一下,但是git subtree push没有'-f'标志... :-(

更新2: 我想我自己找到了上一个问题的答案:

git push origin `git subtree split --prefix dist master`:gh-pages --force

可能是解决方案,对吧?(我还没有运行它...:-))

更新3:是的,这就是强制推送子树的解决方案。

5个回答

2
我会这样做:
git checkout -b upgrades
git checkout master
git reset --hard f36c2f5
git push -f

解释:

  • 将最新的(有问题的)提交保留在一个单独的分支中,以备后用。
  • 切换到主分支。
  • 将主分支重置到您提到的提交:这会丢弃主分支上以后的提交(但“升级”分支仍将具有它们)。
  • 推送主分支,使用“-f”=“强制”标志,因为您想要覆盖远程存储库以放弃某些提交(如果没有“-f”,git不允许您这样做)。

这段代码可以运行,但是没有必要多次执行检出操作。你可以只使用 git branch 命令创建一个新分支而不进行检出。 - Rich
是的,你说得对。我只是太习惯立即检查新创建的分支了,但在这种情况下并不需要。 - Tom De Leu

1
我的常规策略是在这种情况下创建一个新的分支(git branch <new_branch_name>),然后将你当前的分支重置为你指定的提交(git reset --hard <commit>,在这种情况下是 git reset --hard f36c2f5)。但要小心使用 git reset --hard,因为它会清除你工作树中未提交的更改。
你当前的分支将回到稳定的提交状态,但你的其他提交仍然可以在新创建的分支中轻松访问。

这个方法是可行的,但是没有必要进行多次检出。你可以使用 git branch 命令创建一个新分支而无需检出它。 - Rich
@Rich,你说得对。我已经相应地简化了我的方法。 - pattivacek

0

有几种不同的方法可以解决这个问题。您可以简单地使用一系列git revert命令创建新的提交,以撤消您不再需要的提交中所做的更改。

git revert 22c0713
git revert 6d5f9f4
...
git revert 7830eea

(请注意,git revert 命令可以接受多个提交,因此您可以在单个命令中完成此操作,但我个人对此的结果有所保留。)

或者,您可以在当前 HEAD 处创建一个新分支:

git branch for_future_reference

然后将您当前(已存在的)分支重置为指向您想要的提交:

git reset --hard f36c2f5

请注意,使用后一种方法时,您需要“强制”将更改推送到远程 (git push -f) 以重写历史记录。因此,即使作为独立开发人员,前一种方法可能更可取。

如果你喜欢,也可以使用标签代替分支。 - Rich

0
一种可能性是创建一个指向最近的“坏”提交的本地分支。
git branch most-recent-bad-commit

然后将您当前的分支指向最后一个“稳定”的提交

git reset --hard f36c2f5

请注意,后者还将删除对已跟踪文件的任何未提交更改。未跟踪的文件不会被修改。

0
假设您现在在master分支上,您可以创建一个名为experiment的新分支,然后将主分支还原到f36c2f5。例如:

确保您没有未提交的数据,然后创建新的experiment分支。

git branch experiment 

master 分支重置到最后一个良好的提交:

git reset --hard f36c2f5

1
这个方法是可行的,但是没有必要进行多次检出。你可以使用 git branch 命令创建一个新分支而无需检出它。 - Rich
@Rich 谢谢,我知道这个,但大多数时候我使用的是checkout方法。 - dan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接