dme*_*meu 13 git merge revert reset
好的,我搞得一团糟.显然,在家里的机器上,开发分支没有更新.我做了一个提交并推了推.结果是实际的origin/develop分支已合并到我的本地开发分支 - 由于某种原因被认为是不同的分支!
首先,我真的不明白这是怎么发生的,其次,我可以撤消这个吗?
为了说明它,网络现在看起来像这样:
local-develop ---------------------------------- C*--- M -
origin/develop --- C --- C --- C --- C --- C --------- /
Run Code Online (Sandbox Code Playgroud)
我真正想要的是C*将致力于原点/开发而不是合并分支.
正如我所说,这已经被推了.有没有办法删除更改并以我想要的方式提交它?
例如我做:
git reset --hard HEAD~1
Run Code Online (Sandbox Code Playgroud)
我不确定这是否解除了合并,我有两个不同的开发,然后合并删除等...?
tor*_*rek 26
合并不会在推送时发生,它们会发生git merge(好吧,pull但这实际上只是fetch + merge,因此合并时会发生合并).
你似乎更有可能做到这样的事情:
<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
Run Code Online (Sandbox Code Playgroud)
这是创建合并提交的最后一步(M上面),因为pull意味着fetch(获取所有现在进行的新提交origin/develop),然后merge(获取本地develop并将提交与刚刚获取的新提交合并).
如果你还没有git push编这个新的结果,那么远程回购没有任何本地提交的,你标记的那些C*和M.在这种情况下,你的状态很好!(您可以git fetch再次运行检查以确保您的本地仓库origin/develop与远程仓库中的仓库匹配,然后git log origin/develop查看其中的内容.)
可能有助于记住,这里有两个完全独立的git repos:你的,你的东西; 和你在origin这里打电话的人.(让我们调用那台机器X.)如果你要登录X,它有自己独立的提交历史和分支名称等等.在那里,你可以将目录更改为repo,运行git log -1 develop,并查看该分支的顶端是什么.
现在,如果您注销X并重新使用自己的计算机,则可以运行git log -1 origin/develop.如果这与你所看到的相同X,则get fetch无需更新,因为git fetch实际上(但更有效)X是什么,登录并查看其中的内容develop.任何X你没有的东西origin/develop,fetch带来并增加origin/develop.现在你与之同步X. X没有你的东西,但你有他们的东西.
如果你再采取额外的步骤merge(包括暗示的那个pull),git将,如果必须,进行合并提交......但所有这些都在你的仓库中,在分支的顶端(仍然develop在这个案例).除非你推动这个合并提交X(或某人X从你那里提取你的提交但是现在忽略它:-)),X否则不会.
无论如何,只要远程(X这里)没有你的合并提交,你就是金.由于他们没有它,其他人也没有.你可以做rebase你的develop分支,把你的commit(C*)放在上面origin/develop.这将摆脱合并commit(M),然后你可以推送一个简单的快进origin/develop.
如果X 确实有你的合并提交 - 即,如果你在pulled 之后推送并获得了合并 - 那么你就会陷入困境(在某种程度上),因为可能是其他人有权访问X并且现在正在使用你的合并提交.这是可能的回滚回购X类似,您可以在自己的回购与这样做的方法git reset和git rebase等,但它通常是一个坏主意.
X),但你绝对肯定没有其他人看到你的更改,你肯定会重置它们,而不是恢复它们(恢复金额为" "放弃",让其他人从中轻松恢复,但也让他们看到你的错误:-)).1
这里的诀窍是:首先需要让机器X的repo说"分支提示devel是C7",其中C7在你自己的图表中,只是重新编号,以便我可以用不同的名字命名每个提交:
--------------------------- C*--- M
--- C4 --- C5 --- C6 --- C7 ---- /
Run Code Online (Sandbox Code Playgroud)
那么,你怎么能这样做?好吧,一种方法是登录X,2 cd进入回购(即使它是--bare),然后git update-ref在那里使用.假设C7的SHA1实际上是50db850(如"git log"所示).然后你可以这样做:
localhost$ ssh X
X$ cd /path/to/repo.git
X$ git update-ref refs/heads/develop 50db850
Run Code Online (Sandbox Code Playgroud)
但是如果你无法登录X,甚至只是不想,你也可以这样做git push -f.3 (这还有其他优点:特别origin/develop是,一旦push -f成功完成,你的git repo将知道已经重绕了.)只需创建一个指向正确提交的本地分支: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
Run Code Online (Sandbox Code Playgroud)
完成此操作后,机器X将恢复到您想要的状态,您可以继续操作,就好像您从未推动过您不喜欢的合并一样.
请注意,当你这样做时push -f,如果其他人在其上进行了新的提交M,那些也将变得不可见(技术上它们仍然在那里,伴随着你的合并提交,但它们在lost+found某种意义上是"丢失" 的git fsck --lost-found,并且几个月后他们真的会永远消失.五
同样非常重要的是:这种"共享回购的回滚"对于共享回购的其他用户来说是一个巨大的痛苦,所以在你做之前要确定它是可以的.
1这种微不足道的合并甚至不需要恢复.将合并留在那里没有任何根本性的错误.但是,如果你正在处理一个更严重的错误合并,那么除了你的"oops"的记录之外还有一个还原合并的另一个缺点:它使得稍后更难"重做"这些更改,因为后来的"合并"故意"将看到早期合并并思考:好的,我不需要重新合并这些变化.然后你必须"恢复还原".
我认为这里正确的外卖课程是:在你推动以确保你要推动的东西是你打算推动的之前,先看看(git log).
2或者,更简单,更简单:git ls-remote.这使用获取协议代码来查看远程具有的内容.但它隐藏了我要去的主题,即:遥控器就像你的一样!
3即将推出的git版本2版本具有可用的新"安全功能" git push -f.但它们还没有出来,所以这对你没有帮助.我会稍后重新编辑它,注意它们.在此之前,是真的小心这里:你争分夺秒其他人尝试新的东西推到共享资源库,在这一点上.
4您甚至可以通过原始SHA-1 ID执行此操作.但是,分支名称更容易连续多次正确输入.
5保留和到期是通过git的"reflogs".共享服务器可能没有记录所有ref更新; 如果没有,只有已经有新提交的私有回购将保留它们.对于从分支提示无法再访问的提交,最短的默认到期时间为30天,即大约一个月.但是请注意,这是一个无趣的,疯狂的争夺,让所有人在强制推送"失去工作"从共享存储库中搜索"丢失"提交之后搜索他们的存储库.
| 归档时间: |
|
| 查看次数: |
8379 次 |
| 最近记录: |