简体   繁体   English

Git合并可以清除更改,如何处理

[英]Git merge can wipe out changes, how to deal with it

During a merge commit creation. 在合并提交创建期间。 if any change is not staged and left outside the merge commit.(this do happen, and happens a lot when someone doesn't quite known what he's doing, just blindly type those mystery commands. or due to misclick on a GUI git tool.[they are non-technician, we tried to teach them, but failed. We let them use git so that they can update their files easily and keep up to date.]) Then the change is gone. 如果没有进行任何更改并将其保留在合并提交之外。(这种情况确实会发生,并且在某人不太了解他在做什么的情况下会发生很多事情,只需盲目键入这些神秘命令即可。或者是由于在GUI git工具上单击不当。 [他们是非技术人员,我们试图教他们,但失败了。我们让他们使用git,以便他们可以轻松地更新文件并保持最新。])然后,更改就消失了。 the merge commit won't have a this change is undoed msg. 合并提交将没有this change is undoed msg。 it just doesn't appear in merge commit. 它只是没有出现在合并提交中。 the commit which made the change has the info about the change. 进行更改的提交具有有关更改的信息。 but after merge the change is actually undoed without trace. 但是合并后,更改实际上被撤消,没有任何痕迹。

this is horrifying, we can't rely on merge commit info to tell what has been changed/undoed. 这太可怕了,我们不能依靠合并提交信息来告知已更改/撤消的内容。 In fact there's no easy way to tell. 实际上,没有简单的方法可说。

One approach to solve this is to limit the ability to merge onto master to trustworthy maintainers.But as a fast developing mini group, this would add burden to the maintainer and slow us down. 解决此问题的一种方法是将合并到master的能力限制为值得信赖的维护者。但是,作为快速发展的小型团队,这会给维护者增加负担,并使我们放慢速度。

I'm wondering is there anyone enforce merge commit to include info about changes that is actually reverted but not recorded? 我想知道是否有人强制执行合并提交以包含有关实际上已还原但未记录的更改的信息?

Or can I ban the merge operation completely, only allow rebase to make sure all changes are recorded explicitly? 还是可以完全禁止合并操作,仅允许重新设置以确保所有更改都被明确记录?

No automated source tool can be totally foolproof, as fools are too clever. 傻瓜太聪明了, 没有任何自动化的源工具可以完全做到万无一失。 :-) :-)

I think that it is true that most people should rebase more often than merging (ie, I think git pull 's default action, which is to run git merge after running git fetch , is wrong). 我认为大多数人确实应该比合并更经常地调整基础(即,我认为git pull的默认操作(在运行git fetch之后运行git fetch git merge是错误的))。 But this is no solution to the "people do merges incorrectly" problem, because rebasing is merging! 但是,这并不是解决“人员合并错误”问题的解决方案,因为基础调整正在合并! Specifically, to "rebase" a commit, you copy the commit, as if with git cherry-pick . 具体来说,要使提交“变基”,您可以复制提交,就像使用git cherry-pick Usually this is small and simple and does not require any fancy merge work, but sometimes it goes wrong and you wind up with a full blown merge. 通常,这是小型且简单的操作,不需要任何花哨的合并工作,但有时会出错,并且最终会出现完整的合并。 So if people are going to get merges wrong, they may get their own rebases wrong too—and when you rebase multiple commits, each commit gets copied, so each one is a potential merge. 因此,如果人们要错误地合并,他们也可能会错误地更改自己的基准-当您对多个提交进行基准重新设置时, 每个提交都会被复制,因此每个提交都是潜在的合并。

This means the only solution to this problem is to learn how to merge . 这意味着解决此问题的唯一方法是学习如何合并 I will have to leave that sort of instruction to others, but I will note that you can see what changes a merge brought in, with respect to the commit that was the tip of the branch before merging. 我将不得不把这种指示留给其他人,但是我会注意到,相对于合并之前分支的尖端的提交,您可以看到合并带来的变化。

Suppose that you have two branches, eg, this series of commits: 假设您有两个分支,例如,以下一系列提交:

...--o--*--A-----B---C   <-- master
         \
          D--E--F--G--H   <-- feature/X

When you use git merge feature/X to create a new merge commit M on master , you get a new commit with two parents: 当您使用git merge feature/Xmaster上创建一个新的合并提交M时,您将获得一个有两个父级的新提交:

...--o--*--A-----B---C--M   <-- master
         \             /
          D--E--F--G--H   <-- feature/X

This new commit has its own independent source tree, just like any commit. 就像任何提交一样,此新提交具有自己的独立源代码树。

In your question, you say: 在您的问题中,您说:

this is horrifying, we can't rely on merge commit info to tell what has been changed/undoed. 这太可怕了,我们不能依靠合并提交信息来告知已更改/撤消的内容。 In fact there's no easy way to tell. 实际上,没有简单的方法可说。

But there is! 但是有 Commit M (whatever its actual hash ID is) has two parents. 提交M (无论其实际的哈希ID是什么)都有两个父级。 One of those two parents is "what was on the branch before", ie, is commit C . 这两个父母之一是“之前在分支上的东西”,即,提交C If you want to see what has been changed in going from commit C to commit M , just ask Git to show you that : 如果您想查看从提交C到提交M更改,只需让Git告诉您

git diff <hash-id-of-C> <hash-id-of-M>

The output from this git diff is the same as the output from any git diff : it's a set of instructions that show you how to take what was committed as C , and modify it to make what was committed as M . git diff的输出与任何 git diff的输出相同:这是一组指令,向您展示如何获取提交为C ,以及如何对其进行修改以使其提交为M

You can, if you want, also have Git produce for you a set of instructions to show you how to take what was committed as H , and modify it to make what was committed as M : 如果需要,您还可以让Git为您提供一组指令,以向您展示如何采用提交为H ,以及如何对其进行修改以使提交为M

git diff <hash-id-of-H> <hash-id-of-M>

As with any git diff , the output is a set of instructions: "how to take what is in the first commit and change it to make what is in the second commit." 与任何git diff ,输出是一组指令:“如何获取第一次提交中的内容并进行更改以使其成为第二次提交中的内容。”

There is an easy way to see both of these 有一个简单的方法可以看到两个

It's true that git log -p , which normally shows you a diff from "parent commit" to "child commit"—eg, a diff of A vs B , or B vs C —shows nothing when applied to a merge commit. 的确, git log -p通常会显示“父提交”与“子提交”之间的差异(例如, ABBC差异)在应用于合并提交时不显示任何内容。 However: 然而:

git show -m <hash-id-of-M>

runs two git diff commands, one for each parent, and shows you both . 运行两个 git diff命令,每个父命令一个,并向您显示两个命令 Think of -m as "show a merge" or even "split a merge (into two diffs)". -m视为“显示合并”或什至“拆分合并(分为两个差异)”。 This -m flag is available in git log as well: -m标志可用的git log ,以及:

git log -m -p

shows each commit, one at a time, as either a simple diff (if it's not a merge) or a pair of simple diffs (if it is a merge, with two parents). 将每个提交一次显示为一个简单的差异(如果不是合并)或一简单的差异(如果是一个合并,有两个父母)。

(There are, of course, ways to get just one of these two as well, but this answer is long enough already.) (当然,也有几种方法只能获得这两种方法之一 ,但是这个答案已经足够长了。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM