如何有选择地合并或选择Git中另一个分支的更改?


1449

我在一个新项目上使用git,该项目有两个并行的但目前仍处于试验阶段的开发分支:

  • master:导入现有的代码库以及一些我通常确定的mod
  • exp1:实验部门1
  • exp2:实验部门2

exp1exp2代表两种截然不同的架构方法。直到我步入正轨,我才知道哪一个(如果有的话)会工作。当我在一个分支中取得进展时,有时我会进行一些编辑,而这些编辑在另一分支中将非常有用,并且希望将这些合并。

将选择的更改从一个开发分支合并到另一个开发分支,同时又保留其他所有分支的最佳方法是什么?

我考虑过的方法:

  1. git merge --no-commit 然后手动撤消我不想在分支之间共享的大量编辑的暂存。

  2. 手动将公用文件复制到temp目录中,然后git checkout移动到另一个分支,然后从temp目录中进行更多手动复制到工作树中。

  3. 上面的变化。exp现在放弃分支,并使用另外两个本地存储库进行实验。这使得手动复制文件更加简单。

所有这三种方法似乎都是乏味且容易出错。我希望有更好的方法;类似过滤器路径参数的参数,可以使git-merge选择更具选择性。


5
如果实验分支中的更改在单独的提交中井井有条,则最好考虑合并选择性提交而不是选择性文件。下面的大多数答案都假设是这种情况。
akaihola 2010年

2
难道不可以先结合git merge -s ours --no-commit一些之后git read-tree再解决这个问题?参见stackoverflow.com/questions/1214906/…–
VonC

34
最近的问题有一个单行的,写得很好的答案:stackoverflow.com/questions/10784523/…–
brahn

结帐这个博客合并特定文件仅jasonrudolph.com/blog/2009/02/25/...
Ashutosh说Chamoli

Answers:


475

您可以使用cherry-pick命令从一个分支中获取单个提交。

如果您想要的更改不在单个提交中,请使用此处显示的方法将提交拆分为单个提交。粗略地说,您可以使用git rebase -i原始提交进行编辑,然后git reset HEAD^选择性地还原更改,然后git commit将该位作为历史记录中的新提交提交。

在Red Hat Magazine中,还有另一种不错的方法,如果您想将不同的更改拆分到单个文件中(在该页面中搜索“ split”),它们可以使用git add --patch或可能git add --interactive只添加部分块。

拆分更改后,您现在可以选择所需的内容。


14
根据我的理解,这比投票率更高的答案更令人费解。
亚历山大·伯德

54
从技术上讲,这是正确的答案,正确的答案确实显示为“令人费解”。---投票数较高的答案只是一个快速而又肮脏的“做把戏”答案,对于大多数人来说,这就是他们所想的(:
Jacob

3
@akaihola:HEAD ^是正确的。请参见man git-rev-parse:版本参数的后缀^表示该提交对象的第一个父对象。前缀^符号用于从提交中排除可到达的提交。
泰勒里克(Tyler Rick)

13
我只想分享另一种似乎最干净,最不费力的方法jasonrudolph.com/blog/2009/02/25/…完全简单又很棒
superuseroi

14
对于哪种方法是“正确的”的辩论感到困惑?考虑文件和提交之间的区别(请参阅底部的备注)。OP希望合并文件,并且不提及COMMITS。投票率较高的答案是特定于文件的;可接受的答案使用特定于提交的cherry-pick。Cherry-pick可能是选择性合并提交的关键,但是将文件从一个分支移动到另一个分支可能会非常痛苦。尽管提交是git力量的核心,但不要忘记文件仍然起作用!
凯五世

970

我遇到了与您上面提到的完全相同的问题。但是我在解释答案时发现了这一点

摘要:

  • 从您要合并的分支中签出路径,

    $ git checkout source_branch -- <paths>...
    

    提示:它也可以--在链接文章中不显示的情况下工作。

  • 或有选择地合并大块

    $ git checkout -p source_branch -- <paths>...
    

    或者,使用reset,然后添加选项-p

    $ git reset <paths>...
    $ git add -p <paths>...
    
  • 最后提交

    $ git commit -m "'Merge' these changes"
    

9
Bart J的链接文章是最好的方法。清晰,简单的一个命令。这是我要使用的那个。:)
Pistos

256
这不是真正的合并。您将按文件而不是按提交来选择更改,并且将丢失所有现有的提交信息(作者,消息)。当然,如果您要合并某些文件中的所有更改,并且必须重新执行所有提交就可以了,这很好。但是,如果文件同时包含要合并的更改和要放弃的更改,则其他答案中提供的方法之一将为您提供更好的服务。
akaihola 2010年

10
@mykhal等:这会自动暂存索引中的文件,因此,如果您签出了foo.cdo git reset HEAD foo.c来取消暂存该文件,则可以对其进行比较。我尝试过之后发现了这个,然后回到这里寻找答案
michiakig 2011年

12
查看您还可以使用的更改:git diff --cached
OderWat 2011年

9
根据此答案, git checkout -p <revision> -- <path>将与发出您描述的前三个命令相同:)
7hi4g0

337

要有选择地将文件从一个分支合并到另一个分支,请运行

git merge --no-ff --no-commit branchX

branchX您要合并到当前分支的分支在哪里?

--no-commit选项将暂存由Git合并的文件,而不实际提交它们。这将使您有机会修改所需的合并文件,然后自己提交。

根据您要合并文件的方式,有四种情况:

1)您想要一个真正的合并。

在这种情况下,您将接受合并文件,就像Git自动合并它们然后提交它们一样。

2)有些文件您不想合并。

例如,您要保留当前分支中的版本,而忽略要合并的分支中的版本。

要在当前分支中选择版本,请运行:

git checkout HEAD file1

这将检索file1当前分支中的版本,并覆盖file1由Git自动合并的版本。

3)如果要在branchX中使用版本(而不是真正的合并)。

跑:

git checkout branchX file1

这将检索的版本file1branchX并覆盖file1自动合并的Git的。

4)最后一种情况是,如果您只想选择中的特定合并file1

在这种情况下,您可以file1直接编辑修改的内容,将其更新为您想要的版本file1,然后提交。

如果Git无法自动合并文件,它将报告该文件为“未合并 ”并生成一个副本,您需要在其中手动解决冲突。



为了进一步举例说明,假设您要合并branchX到当前分支中:

git merge --no-ff --no-commit branchX

然后,您运行git status命令以查看已修改文件的状态。

例如:

git status

# On branch master
# Changes to be committed:
#
#       modified:   file1
#       modified:   file2
#       modified:   file3
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       both modified:      file4
#

其中file1file2file3是git文件已成功自动合并。

这意味着,这三个文件中的master和的更改branchX已组合在一起,没有任何冲突。

您可以通过运行git diff --cached; 检查合并的完成方式。

git diff --cached file1
git diff --cached file2
git diff --cached file3

如果发现合并不理想,则可以

  1. 直接编辑文件
  2. git commit

如果您不想合并,file1并且希望将版本保留在当前分支中

git checkout HEAD file1

如果您不想合并file2而只想要版本branchX

git checkout branchX file2

如果要file3自动合并,请不要执行任何操作。

Git现在已经将其合并。


file4以上是Git失败的合并。这意味着同一行上的两个分支都发生变化。这是您需要手动解决冲突的地方。您可以通过直接编辑文件或在要file4成为的分支中运行该版本的checkout命令来放弃合并。


最后,不要忘了git commit


10
但是要小心:如果git merge --no-commit branchX只是快进,则会更新指针,因此--no-commit会被静默忽略
CFI 2012

16
@cfi如何添加--no-ff以防止该行为?
爱德华多·科斯塔

5
我绝对建议使用Eduardo的“ --no-ff”选项更新此答案。我通读了整本书(这本来很棒),只是使我的合并快速进行。
Funktr0n 2014年

7
该解决方案可提供最佳结果和灵活性。
Thiago Macedo 2014年

20
与投票最多的答案不同,此解决方案保留了我的合并历史记录,这对我很重要,因为我在分支之间来回编织部分提交。我没有尝试所有其他建议的解决方案,因此也许其中一些也可以这样做。
ws_e_c421

107

我不喜欢上述方法。使用cherry-pick非常适合选择单个更改,但是如果您想引入所有更改(除了一些不好的更改),这将是一个痛苦。这是我的方法。

没有--interactive可以传递给git merge的参数。

这是替代方法:

您在分支“功能”中进行了一些更改,并且希望以一种不草率的方式将其中一些但不是全部都带入“主”(即,您不想挑剔并提交每个)

git checkout feature
git checkout -b temp
git rebase -i master

# Above will drop you in an editor and pick the changes you want ala:
pick 7266df7 First change
pick 1b3f7df Another change
pick 5bbf56f Last change

# Rebase b44c147..5bbf56f onto b44c147
#
# Commands:
# pick = use commit
# edit = use commit, but stop for amending
# squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

git checkout master
git pull . temp
git branch -d temp

因此,只需将其包装在shell脚本中,将master更改为$ to,然后将feature更改为$ from,您就可以开始了:

#!/bin/bash
# git-interactive-merge
from=$1
to=$2
git checkout $from
git checkout -b ${from}_tmp
git rebase -i $to
# Above will drop you in an editor and pick the changes you want
git checkout $to
git pull . ${from}_tmp
git branch -d ${from}_tmp

我搞掂的格式-这是一个相当不错的方法,如果你想要做一个选择的提交
1800信息

我现在正在使用这项技术,而且看起来效果很好。
dylanfm 2010年

4
如果重新设置失败,您可能需要更改git rebase -i $togit rebase -i $to || $SHELL,以便用户可以调用git --skipetc。同样值得将这些行与&&而不是新行链接在一起。
sircolinton

2
不幸的是,答案中的链接似乎已消失。
ThomasW 2012年

不仅链接断开,而且还发出WOT信誉不良警告。因此,我将其删除。
让·弗朗索瓦·科贝特

93

还有另一种方法:

git checkout -p

这是之间的混合git checkout,并git add -p与可能相当被你正在寻找什么:

   -p, --patch
       Interactively select hunks in the difference between the <tree-ish>
       (or the index, if unspecified) and the working tree. The chosen
       hunks are then applied in reverse to the working tree (and if a
       <tree-ish> was specified, the index).

       This means that you can use git checkout -p to selectively discard
       edits from your current working tree. See the “Interactive Mode”
       section of git-add(1) to learn how to operate the --patch mode.

10
到目前为止,这是最简单,最简单的方法,只要您要合并的更改数量可控即可。我希望更多的人会注意到并回答这个问题。范例:git checkout --patch exp1 file_to_merge
Tyler Rick

1
在这个问题上发布了类似的答案:stackoverflow.com/a/11593308/47185
Tyler Rick

哦,我不知道结帐有补丁!我代替了checkout / reset / add -p。
Daniel C. Sobral

2
真正最简单的方法。git checkout -p featurebranch文件名。最好的是,当命令运行时,它会给您ay / n / e /?/ ...等。决定如何合并文件的选项。我尝试使用e,甚至可以在应用之前编辑补丁。多么酷。真正的一个班轮,用于合并其他分支机构的选择性文件。
2013年

55

尽管其中一些答案相当不错,但我觉得没有一个人能够真正回答OP的原始限制:从特定分支中选择特定文件。该解决方案可以做到这一点,但是如果有很多文件,可能会很乏味。

比方说你有masterexp1exp2分支机构。您想将每个实验分支中的一个文件合并到master中。我会做这样的事情:

git checkout master
git checkout exp1 path/to/file_a
git checkout exp2 path/to/file_b

# save these files as a stash
git stash
# merge stash with master
git merge stash

这将为您提供每个文件所需的文件内差异。而已。没什么。在版本之间进行完全不同的文件更改很有用-就我而言,将应用程序从Rails 2更改为Rails 3。

编辑:这将合并文件,但会进行智能合并。我无法弄清楚如何使用此方法来获取文件中的差异信息(也许仍然会存在极大差异。除非您使用此-s recursive -X ignore-all-space选项,否则讨厌的小东西(如空格)会重新合并进来)


4
还要注意:您可以内联地从给定分支中全部处理多个文件,例如git checkout exp1 path/to/file_a path/to/file_x
EMiller 2011年

2
这很漂亮。我确实git checkout feature <path>/*得到了文件组。
isherwood 2014年

可以,但是添加了两个额外的提交对象。
没什么

@MightyPork你是对的。不幸的是,自从我很久以前写这篇文章以来,我再也不确定为什么为什么要使用“ git stash”和“ git merge stash”步骤而不是“ git commit”了。
Eric Hu

2
哦,很明显,我想。这样,它将合并一个文件,而不必覆盖目标分支上的先前更改。
MightyPork

48

1800 INFORMATION的答案是完全正确的。但是,作为一个git noob,“使用git cherry-pick”还不足以让我在互联网上不加更多挖掘的情况下解决这个问题,因此,我想我会发布更详细的指南,以防其他人陷入困境。类似的船。

我的用例是要选择性地将更改从其他人的github分支拉到我自己的分支中。如果您已经拥有进行更改的本地分支,则只需执行步骤2和5-7。

  1. 使用要引入的更改创建(如果未创建)本地分支。

    $ git branch mybranch <base branch>

  2. 切换到它。

    $ git checkout mybranch

  3. 从其他人的帐户中拉出您想要的更改。如果您还没有将其添加为遥控器,则需要。

    $ git remote add repos-w-changes <git url>

  4. 从他们的分支下拉所有。

    $ git pull repos-w-changes branch-i-want

  5. 查看提交日志以查看所需的更改:

    $ git log

  6. 切换回您想要将更改放入的分支。

    $ git checkout originalbranch

  7. Cherry用哈希值一个接一个地选择提交。

    $ git cherry-pick -x hash-of-commit

帽子提示:http : //www.sourcemage.org/Git_Guide


3
提示:首先使用git cherry命令(请先参见手册)来识别尚未合并的提交。
akaihola 2010年

这项工作.. 1.创建一个新分支2.创建了一些文件/进行了一些更改3.提交4.检出master分支5.运行git cherry-pick -x hash-of-commit并解决合并冲突,如果您很好去。
RamPrasadBismil '16

您的链接不再起作用。你能更新一下吗?
cree3007”,

42

这是如何用in 分支替换branch 中的Myclass.java文件的方法。即使不存在,它也将起作用。masterMyclass.javafeature1Myclass.javamaster

git checkout master
git checkout feature1 Myclass.java

请注意,这将覆盖-不会合并-而是忽略master分支中的本地更改。


6
这不会合并。它将仅使用来自feature1分支的更改覆盖master上的更改。
Skunkwaffle 2013年

3
完美的是,我正在寻找这种theirs覆盖,其中覆盖ours=> +1干杯;)
olibre 2013年

1
有时候,您要做的只是替换整个文件,所以这就是我想要的,但是您需要确保要丢失对此文件所做的所有更改。
MagicLAMP

1
鉴于OP特别想用另一个分支上的等效文件替换整个文件,因此是最干净的解决方案:2. Manual copying of common files into a temp directory followed by ...copying out of the temp directory into the working tree.
Brent Faust 2014年

29

简单地合并两个分支中的特定文件的简单方法,而不仅仅是用另一个分支中的文件替换特定文件。

第一步:区分分支

git diff branch_b > my_patch_file.patch

创建一个补丁文件,该文件包含当前分支和branch_b之间的差异

第二步:在与模式匹配的文件上应用补丁

git apply -p1 --include=pattern/matching/the/path/to/file/or/folder my_patch_file.patch

关于选项的有用说明

您可以*在包含模式中用作通配符。

斜线不需要逃脱。

另外,您可以改用--exclude并将其应用于除匹配模式的文件以外的所有内容,或使用-R反转补丁

-p1选项是* unix patch命令的保留项,该事实是补丁文件的内容在每个文件名前都带有a/b/(或更多,取决于补丁文件的生成方式),您需要将其剥离,以便可以找出实际文件到需要应用补丁的文件的路径。

查看手册页中的git-apply以获得更多选项。

第三步:没有第三步

显然,您想提交更改,但是谁说您在进行提交之前没有其他相关的调整。


1
这在current_branch有许多需要保留的“其他”更改的地方非常有用。得到由branch_b带来的仅更改的差异为:git diff HEAD ... branch_b(是的-三个周期可以完成魔术)。
2015年

@masukomi,在步骤2中,您是否不应该将在步骤1中创建的补丁文件添加为参数?
旋毛虫

对我来说,所有更改都被拒绝。知道为什么吗?
LinusGeffarth

最初的想法@LinusGeffarth是,也许您在制作补丁时向后分支了?将在SO之外进行后续跟踪,看看是否可以解决。
masukomi

24

通过这种方法,即使更“简单”的合并会带来很多您不希望的更改,也可以使历史记录仅跟踪来自另一个分支的几个文件,而不会造成太大的麻烦。

首先,您将采取非同寻常的步骤,即预先声明要提交的内容是合并,而git根本不对工作目录中的文件做任何事情:

git merge --no-ff --no-commit -s ours branchname1

。。。其中“分支名称”是您声称要合并的内容。如果您要立即提交,则不会进行任何更改,但仍会显示来自另一个分支的祖先。您可以添加更多分支/标签/等。如果需要,也可以使用命令行。但是,此时没有要提交的更改,因此接下来从其他修订版获取文件。

git checkout branchname1 -- file1 file2 etc

如果要从多个分支合并,请根据需要重复。

git checkout branchname2 -- file3 file4 etc

现在,来自另一个分支的文件已包含在索引中,随时可以提交,并带有历史记录。

git commit

并且您将在该提交消息中进行很多说明。

但是请注意,以防万一,这是很麻烦的事情。这并不是出于“分支”的目的,而在这里摘樱桃是一种更诚实的方式来做您想做的事情。如果您想对上次未带过的同一分支上的其他文件进行另一次“合并”,则会显示“已经更新”消息,从而阻止您。这是我们不应该分支时的一种症状,在“ from”分支中应该有多个不同的分支。


3
您的第一个命令(git merge --no-ff --no-commit -s outs branchname1)正是我想要的!谢谢!
RobM 2012年

1
具有多个分支,所需的历史记录,需要合并单个文件并且必须在推送之前更改文件的内容,这似乎是不错的选择。例如dev => master,但是您要在推送到master之前更改主机定义或类似定义。
2014年

15

我知道我来晚了一点,但这是我合并选择性文件的工作流程。

#make a new branch ( this will be temporary)
git checkout -b newbranch
# grab the changes 
git merge --no-commit  featurebranch
# unstage those changes
git reset HEAD
(you can now see the files from the merge are unstaged)
# now you can chose which files are to be merged.
git add -p
# remember to "git add" any new files you wish to keep
git commit

我对此做了些微改动。我没有选择合并,而是选择了。它完成了工作。这种方法的唯一缺点是您将丢失对原始提交哈希的引用。
马特·佛罗伦萨,

15

最简单的方法是将您的存储库设置为要合并的分支,然后运行,

git checkout [branch with file] [path to file you would like to merge]

如果你跑

git status

您将看到文件已经上演...

然后跑

git commit -m "Merge changes on '[branch]' to [file]"

简单。


3
这几乎是我找到的最佳答案。请参阅jasonrudolph.com/blog/2009/02/25/… 如此简洁明了,它确实有效!
superuseroi

1
它将完全替换源分支中的文件内容,而不是合并文件
Amare

我正要这样回答,我以为我发明了尚未得到回答的新事物!但这是最简单的方法。这应该是最重要的!
伊凡迪·吉普(Irfandy Jip),

15

我发现这篇文章包含最简单的答案。只做:

$ #git checkout <branch from which you want files> <file paths>

例:

$ #pulling .gitignore file from branchB into current branch
$ git checkout branchB .gitignore

有关更多信息,请参见帖子。


3
这实际上并没有合并,它会覆盖当前分支上的文件。
伊戈尔·拉里克

1
@igrali这是一个有用的评论,但是与“适当”方法执行此操作的难度相比,这是一个不错的解决方法。一个人必须非常小心。
owensmartin 2014年

12

奇怪的是,git仍然没有“开箱即用”的便捷工具。当通过当前版本分支的一些错误修正来更新某些旧版本分支(仍然有大量软件用户)时,我会大量使用它。在这种情况下,通常需要从主干中的文件中快速获取一些代码行,而忽略了许多其他更改(这些更改不应该在旧版本中使用)...当然还有交互式三向合并在这种情况下需要git checkout --patch <branch> <file path>使用,而不可用于此选择性合并目的。

您可以轻松做到:

只需将此行添加到[alias]全局.gitconfig或本地.git/config文件中的部分:

[alias]
    mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; /C/BCompare3/BCompare.exe $2.theirs $2 $2.base $2; rm -f $2.theirs; rm -f $2.base;' -"

这意味着您使用了超越比较。如果需要,只需更改为您选择的软件即可。或者,如果不需要交互式选择性合并,则可以将其更改为三向自动合并:

[alias]
    mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; git merge-file $2 $2.base $2.theirs; rm -f $2.theirs; rm -f $2.base;' -"

然后像这样使用:

git mergetool-file <source branch> <file path>

这将为您提供其他分支中任何文件的真正的选择性树方式合并机会。


10

它并不是您要找的东西,但对我很有用:

git checkout -p <branch> -- <paths> ...

它是一些答案的混合。


2
这确实很有用,可以添加到对我来说是最佳答案的@alvinabad答案中。这样做时:git checkout HEAD file1要保留当前版本并取消合并文件file1,可以使用-p选项选择要合并的文件的一部分。谢谢你的把戏!
Simon C.

这是我最喜欢的答案。简单,点和作品
杰西·礼萨Khorasanee


8

我遇到了与您上面提到的完全相同的问题。但是我在解释答案时发现这个git博客更加清晰。

来自以上链接的命令:

#You are in the branch you want to merge to
git checkout <branch_you_want_to_merge_from> <file_paths...>

你测试了吗?我确定文件将从<branch_you_want_to_merge_from>取代,而不是被合并
Amare

7

我喜欢上面的“ git-interactive-merge”答案,但有一个更简单。让git使用交互式和以下的rebase组合为您完成此操作:

      A---C1---o---C2---o---o feature
     /
----o---o---o---o master

因此,情况是您希望C1和C2来自“功能”分支(分支点“ A”),但目前尚无其他。

# git branch temp feature
# git checkout master
# git rebase -i --onto HEAD A temp

如上,它将带​​您进入交互式编辑器,在其中为C1和C2选择“拾取”行(如上所述)。保存并退出,然后它将继续进行重新设置,并为您提供分支“ temp”,以及在master + C1 + C2处的HEAD:

      A---C1---o---C2---o---o feature
     /
----o---o---o---o-master--C1---C2 [HEAD, temp]

然后,您可以将master更新为HEAD并删除temp分支,您可以开始以下工作:

# git branch -f master HEAD
# git branch -d temp

7

git reset --soft branch呢 我很惊讶没有人提及它。

对我来说,这是从另一分支中选择性地选择更改的最简单方法,因为此命令将所有diff更改放入我的工作树中,因此我可以轻松地选择或还原所需的内容。这样,我可以完全控制提交的文件。


6

我知道这个问题很旧,还有很多其他答案,但是我写了自己的脚本“ pmerge”来部分合并目录。这项工作仍在进行中,我仍在学习git和bash脚本。

此命令使用git merge --no-commit然后取消应用与提供的路径不匹配的更改。

用法:git pmerge branch path
示例:git merge develop src/

我还没有对其进行广泛的测试。工作目录应没有任何未提交的更改和未跟踪的文件。

#!/bin/bash

E_BADARGS=65

if [ $# -ne 2 ]
then
    echo "Usage: `basename $0` branch path"
    exit $E_BADARGS
fi

git merge $1 --no-commit
IFS=$'\n'
# list of changes due to merge | replace nulls w newlines | strip lines to just filenames | ensure lines are unique
for f in $(git status --porcelain -z -uno | tr '\000' '\n' | sed -e 's/^[[:graph:]][[:space:]]\{1,\}//' | uniq); do
    [[ $f == $2* ]] && continue
    if git reset $f >/dev/null 2>&1; then
        # reset failed... file was previously unversioned
        echo Deleting $f
        rm $f
    else
        echo Reverting $f
        git checkout -- $f >/dev/null 2>&1
    fi
done
unset IFS

4

您可以用来read-tree将给定的远程树读取或合并到当前索引中,例如:

git remote add foo git@example.com/foo.git
git fetch foo
git read-tree --prefix=my-folder/ -u foo/master:trunk/their-folder

要执行合并,请-m改用。

另请参阅:如何在git中合并子目录?


3

通过文件选择性合并/提交的简单方法:

git checkout dstBranch git merge srcBranch // make changes, including resolving conflicts to single files git add singleFile1 singleFile2 git commit -m "message specific to a few files" git reset --hard # blow away uncommitted changes


3

如果您没有太多更改的文件,这将使您没有多余的提交。

1.暂时复制分支
$ git checkout -b temp_branch

2.重置为上一次所需的提交
$ git reset --hard HEAD~n,这n是您需要返回的提交数量

3.从原始分支检出每个文件
$ git checkout origin/original_branch filename.ext

现在,如果需要,您可以提交并强制推送(覆盖远程)。


3

如果您只需要合并一个特定的目录并保留所有其他内容并保留历史记录,则可以尝试此操作... target-branchmaster在实验之前。

以下步骤假定您有两个分支target-branchsource-branch,并且dir-to-merge要合并的目录位于中source-branch。还要假设您还有其他目录,例如dir-to-retain目标中不希望更改和保留历史的目录。另外,假设中存在合并冲突dir-to-merge

git checkout target-branch
git merge --no-ff --no-commit -X theirs source-branch
# the option "-X theirs", will pick theirs when there is a conflict. 
# the options "--no--ff --no-commit" prevent a commit after a merge, and give you an opportunity to fix other directories you want to retain, before you commit this merge.

# the above, would have messed up the other directories that you want to retain.
# so you need to reset them for every directory that you want to retain.
git reset HEAD dir-to-retain
# verify everything and commit.

2

当两个分支的当前提交之间只有几个文件发生更改时,我将通过浏览不同的文件来手动合并更改。

git difftoll <branch-1>..<branch-2>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.