撤消已推送的合并

2024-04-03

好吧,我弄得有点乱了。显然,在我家里的机器上,开发分支没有更新。我做出了承诺并推动了。结果是实际的 origin/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 means fetch(获取现在的所有新提交origin/develop), then merge(带上你当地的develop并将您的提交与刚刚获取的新提交合并)。

如果你还没有git pushed this new结果,那么远程仓库没有either您的本地提交,您已标记的提交C* and M。在这种情况下,你的状态很好! (您可以通过运行来检查git fetch再次确保您本地的存储库origin/develop与遥控器中的匹配,然后执行git log origin/develop看看里面有什么。)

记住这里有两个完全独立的 git 存储库可能会有所帮助:你的,包含你的东西;和你打电话的人origin这里。 (我们称那台机器为X.) 如果您要登录X,它有自己独立的提交历史和分支名称等等。在那里,您可以将目录更改为存储库,运行git log -1 develop,看看树枝的尖端有什么。

现在如果您注销X回到你自己的机器上,你可以运行git log -1 origin/develop。如果这和你看到的一样X, then get fetch没有什么可更新的,因为什么git fetch实际上(但更有效),登录到X看看里面有什么develop那里。任何东西X有你没有的origin/develop, fetch带来并添加到origin/develop。现在您与X. X没有你的东西,但你有他们的东西。

如果您采取额外的步骤进行merge(包括由pull),如果必须的话,git 会进行合并提交……但这一切都在your回购协议,在分支的尖端(仍然develop在这种情况下)。除非并且直到您将此合并提交推送到X(或某人在X从您那里提取您的提交,但现在让我们忽略它:-) ),X不会有它。

无论如何,只要远程(X这里)没有你的合并提交,你是黄金。自从they自己没有,别人也没有。你可以做一个rebase你的develop分支来放置你的提交(C*) 在之上origin/develop。这将摆脱合并提交(M),然后您可以将简单的快进推至origin/develop.

If X does进行合并提交——即,如果您在之后推送pulled 并得到合并 - 然后你就陷入困境(在某种程度上),因为大概其他人可以访问X现在正在使用您的合并提交。可以回滚仓库X,类似于您在自己的存储库中执行此操作的方式git reset and git rebase等等,但这通常是一个坏主意。


Now, suppose you have in fact pushed to the other repo (on machine X), but you're absolutely sure nobody else has seen your changes yet, and you're definitely going to reset them, rather than reverting them (reverting amounts to "fessing up" and leaving the screwup-record behind, which lets everyone else recover from it easily, but also lets them see your error :-) ).1

诀窍是:您首先需要获取机器 X 的存储库来说明“分支的提示”devel是提交 C7”,其中 C7 位于您之前自己的图表中,只是重新编号,以便我可以以不同的方式命名每个提交:

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

So, how can you do that? Well, one way is to log in on X,2 cd into the repo (even if it's --bare), and use git update-ref there. Let's say the SHA1 for C7 is actually 50db850 (as shown by "git log"). Then you could do this:

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

But if you can't log in to X, or even just don't want to, you can do the same with git push -f.3 (This has other advantages: in particular, your git repo will know that origin/develop has been rewound, once the push -f completes successfully.) Just make a local branch-tip pointing to the right 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 就会回到您想要的状态,您可以继续操作,就好像您从未推送过您不喜欢的合并一样。

Note that when you do the push -f, if anyone else has made new commits on top of M, those will also become invisible (technically they're still in there, along with your merge commit, but they are "lost" in the lost+found sense of git fsck --lost-found, and after a few months they'll really go away forever).5

再次和很重要:这种“共享存储库的回滚”对于该共享存储库的其他用户来说是一个很大的痛苦,因此在执行此操作之前请务必确保它没问题。


1This sort of trivial merge doesn't even need reverting. There's nothing fundamentally wrong with leaving the merge in there. If you're dealing with a more serious mistaken merge, though, there's one other disadvantage to reverting a merge, besides the record of your "oops": it makes "redoing" the changes later a bit harder, in that a later "merge on purpose" will see the earlier merge and think: OK, I don't need to re-merge those changes. You then have to "revert the revert" instead.

我认为正确的教训是:look (git log)在你推之前确保你要推动的就是你想要推动的。

2Or, easier and simpler: git ls-remote. This uses the fetch protocol code to see what the remote has. But it hides the theme I'm going for here, which is: the remote is a repo just like yours!

3The upcoming git version 2 releases have new "safety features" that will be useable with git push -f. But they're not out yet, so that doesn't help you. I'll re-edit this later when they are, to note them. Until then, be really careful here: you're racing against anyone else trying to push new stuff to the shared repository, at this point.

4You can even do this by raw SHA-1 ID. The branch name is easier to type correctly several times in a row though.

5The retaining and expiration is via git's "reflogs". The shared server may not be logging all ref updates; if not, only private repos that already had the new commits will retain them. The shortest default expiration is 30 days, i.e., about one month, for commits no longer reachable from the branch tip. But note, it's a no-fun, crazy scramble to make everyone search through their repositories for "lost" commits after force-pushes "lose work" off a shared repository.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

撤消已推送的合并 的相关文章

  • 在heroku上部署git子目录

    我必须从非主分支部署 git 子目录 我看过这个答案 https stackoverflow com questions 7539382 how can i deploy from a git subdirectory and to Her
  • 如何在Windows平台上编写Git Server Hooks?

    我找不到任何适用于 Windows 的 Git 挂钩的明确示例 我在 Windows Server 上使用 Bonobo Git Server 我需要预提交和提交后挂钩作为 cmd 或 bat 预提交应检查空注释 提交后应发送有关提交的电子
  • 在轮询 SCM 时将 ssh-agent 与 jenkins 结合使用

    我使用 Jenkins ssh agent 插件来为我的构建提供 ssh 凭证 该凭证运行良好 但是我将其设置为轮询 scm 在本例中为 bitbucket git 以检查更改 当然 要访问存储库以轮询更改 它还需要这些 ssh 凭据 我似
  • Composer - 添加 git 存储库而不使用composer.json

    我尝试从 github designmodo Flat UI 添加存储库 使用配置并收到错误No valid composer json was found in any branch or Your requirements could
  • 为什么在将应用程序部署到 Heroku 时会出现此错误?

    使用 git hub 将应用程序部署到 heroku 时遇到某种错误 问题是 我不理解 heroku 日志和随之而来的错误 这是 Heroku 日志 Marcuss MacBook Pro Weather App marcushurney
  • 合并 Pandas Dataframe:如何添加列和替换值

    我有一个数据帧 df1 并想要合并其他 许多 数据帧 df2 以便 合并发生在匹配的 多 索引上 如果缺失 将创建新列 如果列已存在 则替换值 正确的 pandas 操作是什么以及使用什么参数 我查看了 concat join merge
  • gitosis 要求输入密码

    我已经按照以下说明设置了 gitosis 服务器here http scie nti st 2007 11 14 hosting git repositories the easy and secure way 它对于初始用户来说效果很好
  • Git checkout 分支从其他分支留下目录树

    我有一个branch2 其源是branch1 并重命名了源自branch1 的目录 当签出branch1时 重命名的目录仍然存在 但没有标记为未暂存的修改 重命名的目录当然不会作为branch1 上的提交出现 为什么会出现这种情况 上述目录
  • 客户端和服务器的 Git 分支结构

    对于我的一门计算机科学课程 我和一个小组正在使用客户端 服务器架构编写一个应用程序 我很好奇在 Git 存储库中组织项目的最佳实践是什么 我的意思是 我们是否应该像这样构建目录 ProjectDir Clients Client1 file
  • Git - 如何压缩对被忽略文件的更改而不丢失这些更改?

    我想使用 git 保存应用程序随时间使用的实际依赖项的历史记录 其保真度比我从包管理器获得的保真度更高 我正在使用这些分支 master 仅源代码 依赖于 gitignore 构建 源代码和依赖项 build TIMESTAMP 用于强制提
  • jenkins构建完成后如何将更改推送到github?

    我有一个 jenkins 作业 它从 github 克隆存储库 然后运行 powershell 脚本来增加文件中的版本号 我现在正在尝试将该更新文件发布回 github 上的原始存储库 因此当开发人员提取更改时 他会获得最新的版本号 我尝试
  • 没有工作树就无法使用 Git-Windows-git-pull

    我在 Windows 上遇到与 Git 相关的问题 无法从 git 上的存储库中提取更改 我能够添加 提交和推送我的更改 但不能拉取 它给了我一个错误 致命 C Git libexec git core git pull 不能在没有 工作树
  • 如何在 github 中拉取请求时忽略或排除文件

    我们有 4 个分支 1 dev 2 qa 3 staging 4 master 我们要更新并添加1 dev中的CODEOWNERS文件中的一些人 2 qa到4 master的CODEOWNER文件将被保留 因为 1 dev 有 4 个审稿人
  • 2 个 Python 字典如何变成 1 个? [复制]

    这个问题在这里已经有答案了 可能的重复 Python 扩展 字典 https stackoverflow com questions 577234 python extend for a dictionary 我知道 Python 列表可以
  • Git 注释详细信息

    我读了this http git scm com 2010 08 25 notes html and this https github com blog 707 git notes display但仍然认为它们晦涩难懂 目前为止了解到 创
  • 是否可以在一台机器上使用 GitHub 和 GitLab?

    我的账户位于GitHub and GitLab 我生成了 RSA 密钥并将其添加到我的帐户中GitLab 但现在我需要与GitHub在第二个项目上 我知道GitLab和GitHub都使用git 请告诉我是否可以在一台机器上使用 GitHub
  • git rebase 开发分支

    抱歉 只是另一个 变基 问题 但我对此感到困惑 我有时会将开发分支上的提交推送到远程 原始 现在 关于 rebase 总是提到的一件事是 如果您推送了更改 则永远不要 rebase 这意味着 我永远无法重新调整我的开发分支 只能合并它 在功
  • 如何将 git 存储库转换为 Mercurial?

    我一直在使用 git 作为源代码存储库开发 java 应用程序 我想与其他 java 开发人员分享该项目 hg 似乎是他们最常用的 我的问题是如何将 git 存储库转换为 hg 如果我尝试谷歌搜索 将 git 转换为 hg 并且每次搜索命中
  • Jenkins Git 参数插件无法获取标签

    詹金斯版本 1 593 Git 参数插件 0 4 0 GIT 客户端插件 1 16 1 我使用私有 git 存储库 可以通过 ssh 访问 我的构建是参数化的 git参数是TAG TO BUILD 要构建的分支是refs tags TAG
  • 错误“致命:无法快进,正在中止”

    为什么 Git 不再允许我快进合并 如果我尝试使用强制它 ff only 我收到消息 fatal 无法快进 中止 我意识到有巨大的优势merge no ff 但我只是困惑为什么我不能 ff only now 免责声明 这些命令会将远程分支的

随机推荐