Git:由于看起来随机的合并,变化会不断迷路 [英] Git: Changes keep getting lost due to seemingly random merges

查看:160
本文介绍了Git:由于看起来随机的合并,变化会不断迷路的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一种感觉,这将是一个明显的答案,但我似乎无法解决这个问题。



看来发生的事情是,我提交/推送



另一位开发人员然后从同一分支的服务器上拉出来(据说看到我的变化,就我而言, m知道),做了一些修改,将它们提交到自己的本地副本,然后最终将其推回到服务器。



在这样做的过程中,我的更改会丢失因为它们的推送(326c8fd0 ...)会导致合并大量删除/添加行,从而将存储库重置为旧版本。这种情况发生了几次,即使是新的版本库也是如此。



下面突出显示的行(8def6e9 ..)是我做的一个提交,下面的提交应该有假设其他开发人员撤消了更改,他一直在这个分支上。合并发生在326c8fd0,这会导致错误地重置存储库,从而导致以前的更改丢失。





我是否错过了一些非常明显的原因:为什么会发生这种情况?我们都使用TortoiseGit。



很抱歉,可能含糊不清的解释。

解决方案

在你的例子中,有人正在合并f36908d(合并时的第一个父元素,它们的HEAD)和8def6e9(第二个父元素;可能是合并时原始分支的尖端)以生成326c8fd0 。如果合并提交(326c8fd0)缺少关于其父母(f36908d和8def6e9;)的重要内容片段;您说它缺少后者的片段),那么创建合并提交的人可能以不恰当的方式执行合并。



这个人可能正在使用我们的 - 我们的 / - 策略=我们),我们的选项添加到默认的递归合并策略中(合并或拉取 -X我们 / - 策略选择=我们),或者他们可能只是在做出糟糕的决定时手动解决合并冲突。



我们的策略完全忽略了历史记录中所有父母的内容更改,第一。你通常可以识别这种类型的合并,因为合并提交及其第一个父代(即它们的更改)将具有相同的树(即 git diff f36908d 326c8fd0 不会显示差异)。
$ b

我们的合并策略选项也会忽略第二个父代的历​​史记录(即您的更改)的更改,但只有那些与第一个父母的历史变化(即他们的变化)相冲突的人。在这种情况下,来自第二个父母的一些变化可能会使其成为结果,但其他人可能会完全放弃。

另一种可能的替代方法是他们只是变得糟糕同时解决在默认合并期间产生的冲突。



无论哪种方式,有人可能不得不与进行合并的用户进行交谈,以确切了解他们做了什么,以及为什么他们这样做,以便可以制定一项政策,以防止将来出现问题。






要恢复,您可能会重新合并你自己,他们将结果合并到历史的当前提示中:

$ g $ g $ g $ check $ b $ g $ g $ b git merge 8def6e9
#解决冲突并提交
git checkout开发
git合并remerge
#可能解决更多冲突

#最终:git分支 - d remerge

或者,如果您可以重写历史记录:

  git checkout -b remerge f36908d 
git merge 8def6e9
#解决冲突并提交
git rebase --onto remerge 326c8fd0 develop
#也许更多冲突来解决在每个重新提交的提交


I have a feeling this will be an obvious answer, but I can't seem to work it out.

What appears to happen is that I commit/push some changes to the server and everything appears fine on my copy.

Another developer then pulls from the server from the same branch (allegedly seeing my changes, as far as I'm aware), makes some modifications, commits them to their own local copy then finally pushes it back to the server.

Somewhere in the middle of doing this my changes get lost as their push (326c8fd0...) causes a merge with lots of delete/add lines resetting the repository back to a much older revision. This has happened a few times now even with fresh copies of the repository.

The highlighted line below (8def6e9..) was a commit I made, the following commits should have been on this same branch assuming the other developer pulled the changes. A merge happens at 326c8fd0 which ends up resetting the repository incorrectly, losing previous changes.

Am I missing something very obvious as to why this is happening? We're both using TortoiseGit.

Sorry for the probably vague explanation.

解决方案

In your example, someone is merging f36908d (the first parent; their HEAD at the time of the merge) and 8def6e9 (the second parent; probably the tip of the origin branch at the time of the merge) to produce 326c8fd0.

If the merge commit (326c8fd0) is missing significant pieces of content with respect to either of its parents (f36908d and 8def6e9; you say it is missing pieces of the latter), then whoever create the merge commit is probably executing the merge in an inappropriate fashion.

This person may be using the ours merge strategy (merge or pull with -s ours/--strategy=ours), the ours option to the default recursive merge strategy (merge or pull with -X ours/--strategy-option=ours), or they may just be making bad decisions when manually resolving the merge conflicts.

The ours strategy completely ignores any content changes made in the history all parents but the first. You can usually identify this type of merge because the merge commit and its first parent (i.e. their changes) will have identical trees (i.e. git diff f36908d 326c8fd0 would show no differences).

The ours merge strategy option will also ignore changes from the history of the second parent (i.e. your changes), but only those that conflict with changes made in the history of the first parent (i.e. their changes). In this case, some changes from the second parent may make it into the result, but others may be dropped entirely.

The other likely alternative is that they are just making bad decisions while resolving conflicts generated during a default merge.

Either way, someone will probably have to talk to the user that did the merge to find out exactly what they did, and why they did it so that a policy can be devised to prevent the problem in the future.


To recover, you might redo the merge yourself and them merge the result into the current tip of the history:

git checkout -b remerge f36908d
git merge 8def6e9
# resolve conflicts and commit
git checkout develop
git merge remerge
# maybe resolve more conflicts

# eventually: git branch -d remerge

Or, if you are okay with rewriting history:

git checkout -b remerge f36908d
git merge 8def6e9
# resolve conflicts and commit
git rebase --onto remerge 326c8fd0 develop
# maybe more conflicts to resolve at each rebased commit

这篇关于Git:由于看起来随机的合并,变化会不断迷路的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆