git reset 到之前的提交然后推送

jim*_*iki 0 git git-revert

尝试通过 git reset 恢复到之前的提交(例如 123abc)时

git reset --hard 123abc 
git commit -a -m "revert to 123abc"
Run Code Online (Sandbox Code Playgroud)

我不能推动这个(我需要在拉之前拉动我向前)。我带着这几行来了:

for i in `git diff --name-only 123abc`; do git checkout 123abc $i; done
git commit -a -m "revert to 123abc"
Run Code Online (Sandbox Code Playgroud)

从现在开始哪个有效

 git diff --name-only 123abc
Run Code Online (Sandbox Code Playgroud)

是空的

我想知道这是 hack 还是 git 方法。如果不是,如何正确完成此操作?

tor*_*rek 5

当尝试恢复之前的提交时(例如 123abc)......

我在这里添加的对介词“to”的强调,就像在revert to 中一样,是至关重要的。该接受的答案在你的链接的问题(我如何恢复一个Git仓库到以前提交)调用了这一点:

这在很大程度上取决于您所说的“恢复”是什么意思。

git revert单个提交上运行可能还不够。如果需要,请参阅有关还原多次提交的答案。

运行git reset --hard 可能就足够了,但会引入您遇到的问题。这里要理解的事情是:

  1. 一个分支的名字只是让Git的发现一个特别的承诺。我们说分支名称指向提交。使用git reset,我们可以更改某个分支名称指向的一个特定提交。 存储库中还没有发生任何其他事情,尽管取决于git reset您运行的类型,在git reset完成之前可能会发生其他事情:第一步git reset只是更改您自己的一个分支名称。由于您正在考虑(或已经使用)--hard,您的存储库中会有更多内容发生变化,但目前它们不那么重要。

  2. 每个 Git 存储库都有自己的分支名称。 移动您的分支名称之一不会影响任何其他存储库。

  3. 您需要做的是让其他一些 Git 存储库更改分支名称之一。这就是你遇到这个问题的地方:

    我不能推动这个(我需要在拉之前拉动我向前)。

    git push命令是您询问或使用--force命令的方式来更改或创建或删除某些其他 Git 存储库的名称(分支名称、标记名称和其他此类名称)。但是每个 Git 存储库都设置为轻松接受新的传入提交,但同时拒绝丢弃任何现有提交的建议

当您使用git reset“向后”移动分支名称之一以恢复到(而不是revert像 add-a-commit-that-backs-out 那样)之前的某个提交时,您是故意丢弃一些现有的提交)。由于您控制自己的 Git 存储库,因此您绝对可以对自己的存储库执行此操作。由于该git reset命令旨在进行这种丢弃,1它毫无怨言地这样做。但git push 不是他们的Git 抱怨。

一旦您使用git pull他们的存储库就会放回您从自己的存储库中剪下的所有提交。毕竟,Git 旨在尽可能轻松地添加提交!这让你处于你所处的境地。

你现在有一个选择:

  • 强制另一个 Git 存储库放弃一些提交。这需要足够的权限。这也意味着使用其他 Git 存储库的每个人都需要对他们所做的任何克隆采取行动,因为他们的克隆会热情地放回您试图修剪的所有提交。所以这对其他人来说有点意思。

  • 或者,使用git revert或其他一些命令将一些提交添加到您的存储库,最终导致将文件放回,但不要删除任何提交。新提交只是添加到旧提交。对于任何想要询问它们 ( git log) 或使用它们 (例如 ) 的人来说,旧的仍然存在。git switch --detach hash-id

添加新的提交是 Git 的设计目的,所以后者是要走的路,除非有一些非常充分的理由放弃旧的提交。

正如您链接注释的问题,所有这些对于未发布的提交都容易得多:只有您拥有的提交,在您自己的私有存储库中,根本不在任何其他 Git 存储库中。如果你从你自己的分支上删除这些提交,没有人会知道。他们不会能够给对象一个git push刮胡子了其分支机构的提交,因为这些提交不了分支机构。(同样,每个分支名称对于每个 Git 存储库都是本地的。一个存储库可以向另一个存储库显示存储在其分支名称中的提交哈希 ID,但每个存储库负责将自己的哈希 ID 保留在自己的分支名称中。提交分享;该分支名称没有。)

由于您正在查看的提交已发布,因此您无法使用此快捷方式。


1这制造git reset了一种非常强大的工具,比如某种火焰喷射链锯,或工业钢切割激光器,或其他东西。这种强大的功能是 Git 2.23 现在拥有的部分原因git restore:您可以做的一些事情,过去需要使用git reset,现在可以使用更温和的git restore. 如果您询问,这两个命令都会丢弃正在进行的工作,但git restore更像是手锯、断线钳或类似的东西。