我有一个分支称为演示,我需要与主分支合并。我可以通过以下命令得到想要的结果:

git pull origin demo
git checkout master
git pull origin master
git merge demo
git push origin master

我唯一关心的是,如果有任何合并问题,我想告诉git覆盖的变化在主分支没有给我合并提示。所以基本上演示分支中的变化会自动覆盖主分支中的变化。

我环顾四周,有多种选择,但我不想冒险合并。


当前回答

这种合并方法将在master之上添加一个提交,该提交粘贴了任何特性中的内容,而不会抱怨冲突或其他废话。

在你碰任何东西之前

git stash
git status # if anything shows up here, move it to your desktop

现在准备大师

git checkout master
git pull # if there is a problem in this step, it is outside the scope of this answer

把功能都打扮起来

git checkout feature
git merge --strategy=ours master

使出杀手锏

git checkout master
git merge --no-ff feature

其他回答

这些命令将帮助覆盖代码的演示分支到主

git fetch --all

在本地拉您的演示分支

git pull origin demo

现在签出到主分支。该分支将与演示分支上的代码完全更改

git checkout master

停留在主分支并运行此命令。

git reset --hard origin/demo

重置意味着您将重置当前分支

——hard是一个标志,意味着它将被重置而不会引发任何合并冲突

Origin /demo将被认为是将强制覆盖当前主分支的代码

上述命令的输出将显示您在origin/demo或demo分支上的最后一个提交消息

然后,最后,强制将主分支上的代码推到远程回购。

git push --force

这种合并方法将在master之上添加一个提交,该提交粘贴了任何特性中的内容,而不会抱怨冲突或其他废话。

在你碰任何东西之前

git stash
git status # if anything shows up here, move it to your desktop

现在准备大师

git checkout master
git pull # if there is a problem in this step, it is outside the scope of this answer

把功能都打扮起来

git checkout feature
git merge --strategy=ours master

使出杀手锏

git checkout master
git merge --no-ff feature

当我尝试使用-X their和其他相关命令开关时,我一直得到一个合并提交。我可能没有正确理解。一个容易理解的替代方法是删除分支,然后再次跟踪它。

git branch -D <branch-name>
git branch --track <branch-name> origin/<branch-name>

这并不是真正的“合并”,但这正是我遇到这个问题时所寻找的。在我的例子中,我想从一个远程分支中拉出强制推送的更改。

我有一个类似的问题,我需要有效地替换任何文件,有变化/冲突与一个不同的分支。

我发现的解决方案是使用git merge -s我们的分支。

注意,该选项是-s而不是-X。-s表示使用ours作为顶级合并策略,-X将把ours选项应用于递归合并策略,这不是我(或我们)在这种情况下想要的。

步骤,其中oldbranch是要用newbranch覆盖的分支。

Git checkout newbranch签出你想要保留的分支 Git merge -s我们的oldbranch在旧的分支中合并,但保留我们所有的文件。 Git checkout oldbranch签出你想要覆盖的分支 Get merge newbranch在新分支中合并,覆盖旧分支

与这个答案没有太大关系,但我将抛弃git pull,它只运行git fetch,然后是git merge。您正在进行三次合并,这将使您的Git运行三次获取操作,而您只需要一次获取。因此:

git fetch origin   # update all our origin/* remote-tracking branches

git checkout demo         # if needed -- your example assumes you're on it
git merge origin/demo     # if needed -- see below

git checkout master
git merge origin/master

git merge -X theirs demo   # but see below

git push origin master     # again, see below

控制最棘手的合并

这里最有趣的部分是git merge -X their。正如root545指出的,-X选项被传递给合并策略,默认递归策略和替代解析策略都接受-X我们的或-X他们的(其中一个,但不是两个)。但是,要理解它们的作用,您需要了解Git如何查找和处理合并冲突。

A merge conflict can occur within some file1 when the base version differs from both the current (also called local, HEAD, or --ours) version and the other (also called remote or --theirs) version of that same file. That is, the merge has identified three revisions (three commits): base, ours, and theirs. The "base" version is from the merge base between our commit and their commit, as found in the commit graph (for much more on this, see other StackOverflow postings). Git has then found two sets of changes: "what we did" and "what they did". These changes are (in general) found on a line-by-line, purely textual basis. Git has no real understanding of file contents; it is merely comparing each line of text.

这些变化就是你在git diff输出中看到的,和往常一样,它们也有上下文。有可能我们所更改的内容与他们所更改的内容在不同的行上,这样更改看起来不会发生冲突,但上下文也发生了变化(例如,由于我们的更改接近文件的顶部或底部,因此在我们的版本中文件运行完,但在他们的版本中,他们也在顶部或底部添加了更多文本)。

如果更改发生在不同的行上——例如,我们在第17行将颜色更改为颜色,而他们在第71行将fred更改为barney——那么就不存在冲突:Git只是接受这两个更改。如果更改发生在相同的行上,但是是相同的更改,Git将获取该更改的一个副本。只有当更改在同一行上,但是是不同的更改,或者干扰上下文的特殊情况时,才会出现修改/修改冲突。

-X ours和-X their选项告诉Git如何解决这个冲突,只需选择两个更改之一:我们的或他们的。因为你说你正在将demo(他们的)合并到master(我们的)中,并希望从demo中进行更改,你需要-X他们的。

然而,盲目地应用-X是危险的。仅仅因为我们的更改在逐行基础上没有冲突并不意味着我们的更改实际上没有冲突!一个经典的例子出现在带有变量声明的语言中。基本版本可能声明一个未使用的变量:

int i;

在我们的版本中,我们删除了未使用的变量以消除编译器的警告,而在他们的版本中,他们在几行之后添加了一个循环,使用i作为循环计数器。如果我们将这两个更改结合在一起,生成的代码将不能再编译。-X选项在这里没有帮助,因为更改在不同的行上。

如果您有一个自动化测试套件,最重要的事情就是在合并后运行测试。你可以在提交后执行此操作,并在需要时进行修复;或者你可以在提交之前,通过在git merge命令中添加——no-commit来完成。我们将把所有这些细节留给其他帖子。


你也可以在“文件范围的”操作中得到冲突,例如,也许我们修复了文件中一个单词的拼写(这样我们就有了一个更改),而他们删除了整个文件(这样他们就有了一个delete)。不管-X参数如何,Git都不会自行解决这些冲突。


做更少的合并和/或更聪明的合并和/或使用rebase

在我们的两个命令序列中有三个合并。第一种方法是将origin/demo引入本地演示(你使用的是git pull,如果你的git非常旧,它将无法更新origin/demo,但会产生相同的最终结果)。第二是将原点/主带入主。

It's not clear to me who is updating demo and/or master. If you write your own code on your own demo branch, and others are writing code and pushing it to the demo branch on origin, then this first-step merge can have conflicts, or produce a real merge. More often than not, it's better to use rebase, rather than merge, to combine work (admittedly, this is a matter of taste and opinion). If so, you might want to use git rebase instead. On the other hand, if you never do any of your own commits on demo, you don't even need a demo branch. Alternatively, if you want to automate a lot of this, but be able to check carefully when there are commits that both you and others, made, you might want to use git merge --ff-only origin/demo: this will fast-forward your demo to match the updated origin/demo if possible, and simply outright fail if not (at which point you can inspect the two sets of changes, and choose a real merge or a rebase as appropriate).

同样的逻辑也适用于master,尽管你是在master上进行合并,所以你肯定需要一个master。然而,更可能的情况是,如果不能快速进行非合并,则合并失败,所以这可能也应该是git merge——ff-only origin/master。

假设你从来没有在demo中做过自己的提交。在这种情况下,我们可以完全放弃名称演示:

git fetch origin   # update origin/*

git checkout master
git merge --ff-only origin/master || die "cannot fast-forward our master"

git merge -X theirs origin/demo || die "complex merge conflict"

git push origin master

如果你正在做自己的演示分支提交,这是没有帮助的;您也可以保留现有的合并(但可能添加-ff-only取决于您想要的行为),或将其转换为rebase。注意,这三种方法都可能失败:merge可能会因冲突而失败,merge with——ff-only可能无法快进,rebase可能会因冲突而失败(rebase本质上是通过选择提交工作的,它使用合并机制,因此可能会产生合并冲突)。