您可能也不想更改服务器中的任何引用(git reset
可能会将任何分支HEAD
点移动到master
,但您说您不想恢复或重置本地系统,因此基于此,我假设您不这样做'也不想恢复或重置您的裸存储库)。
在这种情况下,只需登录到服务器、cd
裸存储库,然后运行:
git checkout --work-tree=/path/to/live checkout -f <commit-ID>
或者:
GIT_WORK_TREE=/path/to/live git checkout -f <commit-ID>
换句话说,您只是在做更新钩子所做的事情,但是使用原始提交 ID 来提取该特定版本,而无需更改存储库本身中的任何分支。
虽然我认为这是对您问题的字面回答,但我想指出其他一点:如果您git revert
在自己的本地存储库中提交了错误的提交,您将获得一个新的提交,该提交取消了错误提交的影响,但是错误的提交还在里面。然后,您可以按通常的方式将结果推送到服务器:
... - o - X - o - U <-- master, origin/master
X
错误的提交在哪里,并且U
是“取消”所做的提交X
。只是为了说明,我o
在它们之间也包含了一个无趣的提交。
现在您可以简单地还原您的还原,以便您的本地回购以再次重播“错误”提交结束:
... - o - X - o - U <-- origin/master
\
X' <-- master
哪里X'
是错误提交的副本,它“取消”了U
所做的撤消。您现在可以修复它,在 top or 上再次提交git commit --amend
,等等,当一切正常时,git push
将结果再次发送到服务器。这将是处理该问题的更典型的方式。
根据评论,这是另一个选项,它可能适合也可能不适合,更好等:与其在本地重置或恢复,不如创建一个新的本地分支或标签(让我们在这里使用分支)指向您要恢复的提交服务器。您可能还需要服务器上的名称,这样它就不会垃圾收集提交(这意味着您以后必须再次通过网络发送它们)。
例如,假设上面的树local
看起来像这样,画了一个扭结,这样我就可以添加一个标签:
... - o - R
\
X - o - o -...- o <-- HEAD=master, origin/master
这R
是您希望服务器重置为的提交,而X
其他提交是更新 Wordpress 插件的提交等。(我假设您正在处理分支master
;根据需要进行更改。)
同时,在服务器上,情况如下所示:
... - o - R
\
X - o - o -...- o <-- HEAD=master
如果你想保留服务器上的所有提交,我们应该给最终o
提交一个新的分支名称,因为我们必须在那里强制更新master
。等等local
,我们可能会运行这个:
$ git push origin master:save
这将在服务器上创建一个名为 的新分支save
,因此它现在看起来像这样:
... - o - R
\
X - o - o -...- o <-- HEAD=master, save
钩子将update
执行通常的git checkout -f
,它检查HEAD
分支(因为没有指定分支),在这种情况下是master
,所以服务器被更新到最后一次o
提交(毫无意义,它已经在那里)。但接下来,我们再次这样做local
:
$ git branch for-server <commit-ID-for-R>
这会将设置更改local
为如下所示:
... - o - R <-- for-server
\
X - o - o -...- o <-- HEAD=master, origin/master
还不是很有趣,但是接下来:
$ git push --force origin for-server:master
这(带--force
)告诉服务器强制更新其master
指向 commit R
,之后它有这个:
... - o - R <-- HEAD=master
\
X - o - o -...- o <-- save
该save
标签将剩余的提交保存在服务器上的存储库中。同时,post-update
钩子运行并执行 a git checkout -f
,其中使用HEAD
,指向master
,指向提交R
。所以现在 Web 服务器应该已经R
部署了提交。
回来local
,您只需要记住遥控器上的for-server
映射即可。master
(如果您愿意,您可以重命名所有本地分支以匹配服务器上的命名:例如更改master
为save
和更改for-server
为master
。这完全独立于此。)
请注意,服务器上唯一要做save
的就是保持提交X
和所有后续o
s。如果您想直接在服务器上工作,或者不想通过网络发回这些提交,那就太好了。但是,如果在服务器上(它有一个工作目录,因为它不是一个裸仓库),你git checkout save
将更HEAD
改为指向save
并且下次post-update
运行钩子时,它将部署save
版本,而不是master
版本.