gpt4 book ai didi

git - 撤消已推送的 merge

转载 作者:行者123 更新时间:2023-12-02 11:38:32 24 4
gpt4 key购买 nike

好吧,我有点混乱。显然,在我家里的机器上,develop分支未更新。我做了一个承诺,并推动了。结果是实际的起源/开发分支已合并到我的本地开发分支中-由于某种原因,它们被视为不同的分支!

一方面,我真的不明白这是怎么发生的,其次,我能撤消吗?

为了说明这一点,网络现在看起来像这样:

 local-develop ---------------------------------- C*--- M -
origin/develop --- C --- C --- C --- C --- C --------- /


我真正想要的是C *将致力于源/开发而不是合并分支。

正如我所说,这已经被推动了。有没有办法删除更改并按我想要的方式提交?

例如,我这样做:

git reset --hard HEAD~1


我不确定这是否会取消合并,并且我有两个不同的开发,然后合并删除等...?

最佳答案

合并不是在推送上发生的,它们是在git merge上发生的(嗯,和pull,但这实际上只是获取+合并,因此合并发生在合并上)。

您似乎更可能执行了以下操作:

<get copy from origin/develop>
<wait around for remote's origin/develop to acquire new commits>
git checkout develop # get onto (local) develop branch
<edit>
git commit -m message # create some new commit(s)
git push origin develop # attempt to push -- but this fails!
git pull


这是创建合并提交的最后一步(上面的 M),因为 pull表示 fetch(获取所有现在在 origin/develop中的所有新提交),然后是 merge(使用本地 develop并将您的提交与刚刚提取的那些提交合并)。

如果您尚未 git push获得此新结果,则远程存储库将没有您的本地提交(已标记为 C*M的本地提交)。在这种情况下,您身体状况良好! (您可以通过再次运行 git fetch来确保本地仓库的 origin/develop与远程仓库中的仓库匹配,然后执行 git log origin/develop来查看其中的内容来进行检查。)

记住这里有两个完全独立的git repos可能会有所帮助:您的,带有您的东西;还有您在此处呼叫 origin的那个。 (让我们将该计算机称为 X。)如果要登录 X,它具有自己的单独提交历史记录和分支名称,依此类推。在那儿,您可以将目录更改为存储库,运行 git log -1 develop,然后查看该分支顶端的内容。

现在,如果您注销 X并回到自己的计算机上,则可以运行 git log -1 origin/develop。如果与您在 X上看到的内容相同,则 get fetch没有任何更新,因为 git fetch的作用实际上(但更有效)是登录到 X并查看< cc>在那里。 develop中没有的所有内容, X都会带来并添加到 origin/develop中。现在,您已与 fetch同步。 origin/develop没有您的东西,但您有他们的东西。

如果您随后采取额外的步骤来执行 X(包括 X所隐含的内容),则git将(如果必须)进行合并提交...但是所有这些都在您的仓库中,提示分支(在这种情况下仍为 merge)。除非并且直到您将此合并提交推送到 pull(或者 develop上的某个人从您那里提取您的提交,但现在暂时忽略它:-)), X才不会拥有它。

无论如何,只要远程主机(此处为 X)没有您的合并提交,您就是黄金。由于他们没有,所以也没有人做。您可以对 X分支进行 X,将提交( rebase)放在 develop之上。这将摆脱合并提交( C*),然后可以将简单的快进推送到 origin/develop

如果 M确实有您的合并提交(即,如果您在 origin/develop完成并合并后就进行了推送),则您会被卡住(在某种程度上),因为大概其他人可以访问 X并且正在使用您的合并提交。可以回滚 pull上的存储库,类似于使用 XX在自己的存储库中执行此操作的方式,依此类推,但这通常是一个坏主意。

现在,假设您实际上已经推送到另一个存储库(在计算机 git reset上),但是您绝对可以确定没有其他人看到您的更改,并且您肯定会重置它们,而不是还原它们(还原等于“费劲了”,留下了乱糟糟的记录,这使其他所有人都可以轻松地从中恢复过来,还可以让他们看到您的错误:-)).1

诀窍是:您首先需要获得计算机X的存储库,以说“分支 git rebase的尖端是提交C7”,其中C7在您自己的图表中,较早时才进行了重新编号,以便我可以对每个提交进行不同的命名:

--------------------------- C*--- M
--- C4 --- C5 --- C6 --- C7 ---- /


那么,你该怎么做呢?好吧,一种方法是登录 X,2 devel进入仓库(即使它是 X),然后在其中使用 cd。假设C7的SHA1实际上是 --bare(如“ git log”所示)。然后,您可以这样做:

localhost$ ssh X
X$ cd /path/to/repo.git
X$ git update-ref refs/heads/develop 50db850


但是,如果您无法登录 git update-ref,甚至根本不想登录,都可以使用 50db850 .3进行相同操作(这还有其他优点:特别是,您的git repo会知道 已经倒回,一旦 X成功完成。)只需使本地分支提示指向正确的commit:4即可。

localhost$ git branch resetter 50db850
localhost$ git log resetter # make sure it looks right
...
localhost$ git push -f origin resetter:develop
Total 0 (delta 0), reused 0 (delta 0)
To ssh://[redacted]
+ 21011c9...50db850 resetter -> develop (forced update)
localhost$ git branch -d resetter # we don't need it anymore


完成此操作后,计算机X将返回所需状态,就可以继续进行操作,就好像您从未按过不喜欢的合并一样。

请注意,当您执行 git push -f时,如果其他任何人在 origin/develop之上进行了新提交,则这些提交也将变得不可见(从技术上讲,它们仍与合并提交一起存在,但它们“丢失”了)从 push -f的意义上讲,几个月后,它们将永远消失。)5

再次且非常重要:这种“回退共享存储库”对于该共享存储库的其他用户来说是一个很大的痛苦,因此在执行此操作之前,请确保它可以确定。



1这种微不足道的合并甚至不需要还原。将合并保留在那里根本没有任何错误。但是,如果您要处理更严重的错误合并,则还原合并还有另一个缺点,除了“哎呀”的记录外:这会使以后“重做”更改更加困难,因为稍后“合并”故意”将看到之前的合并,并认为:好,我不需要重新合并这些更改。然后,您必须改为“还原还原”。

我认为这里的正确总结是:在进行推送之前先查看( push -f),以确保要推送的内容就是要推送的内容。

2或者,更轻松,更简单: M。这使用获取协议代码来查看遥控器具有的内容。但这隐藏了我要在这里使用的主题,即:遥控器就像您一样,是一个仓库。

3即将发布的git版本2具有新的“安全功能”,可与 lost+found一起使用。但是他们还没有出来,所以这对您没有帮助。稍后,我将对其进行重新编辑,以注意它们。在此之前,请务必格外小心:此时,您正在与其他尝试将新内容推送到共享存储库的人进行竞争。

4您甚至可以通过原始SHA-1 ID来执行此操作。分支名称更容易连续多次正确键入。

5保留和到期是通过git的“ reflogs”进行的。共享服务器可能未记录所有引用更新;如果不是,那么只有已经拥有新提交的私有仓库会保留它们。默认的最短到期时间是30天,即大约一个月,这是因为分支尖端不再提供的提交。但是请注意,在所有人从共享存储库强行推动“丢失的工作”之后,使每个人都在存储库中搜索“丢失的”提交是一种无聊的疯狂争夺。

关于git - 撤消已推送的 merge ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10176352/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com