我在具有两个并行的但仍处于试验阶段的开发分支的新项目上使用Git:


确定

master:实验分支#1

exp1:实验分支#2

exp2exp1代表两种截然不同的体系结构方法。直到我步入正轨,我才知道哪一个(如果有的话)会工作。当我在一个分支中取得进展时,有时我会进行一些编辑,而这些编辑将在另一个分支中有用,并且希望将这些合并。其他?
我已经考虑过的方法:


exp2,然后手动取消暂存我不想在分支之间共享的大量编辑。


手动将公用文件复制到一个临时目录,然后将git merge --no-commit移到另一个分支,然后从该临时目录中手动复制到工作树。 >
以上所述。现在放弃git checkout分支,并使用另外两个本地存储库进行实验。这使手动复制文件变得更加简单。


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

评论

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

混合git merge -s我们的--no-commit后再加上一些git read-tree会不是一个好的解决方案?参见stackoverflow.com/questions/1214906/…

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

检出此博客以仅合并特定文件jasonrudolph.com/blog/2009/02/25/…

#1 楼

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

如果所需的更改不在单个提交中,请使用此处显示的方法将提交拆分为单个提交。 。粗略地说,您可以使用git rebase -i来进行原始提交的编辑,然后使用git reset HEAD^来有选择地还原更改,然后使用git commit将该位作为新的提交提交到历史记录中。
如果要对单个文件拆分不同的更改(在该页面中搜索“拆分”),则在Red Hat Magazine上使用git add --patch或可能的git add --interactive,它允许您仅添加块的一部分。

拆分更改后,现在就可以随意挑选所需的内容了。

评论


根据我的理解,这比投票率更高的答案更令人费解。

–亚历山大·伯德(Alexander Bird)
2012年2月3日在2:24

从技术上讲,这是正确的答案,正确的答案确实显示为“令人费解”。 ---投票率较高的答案只是一个快速而又肮脏的“按需付费”答案,对于大多数人来说,这就是他们所要解决的所有问题:

–杰伊
2012年9月9日在7:46



@akaihola:HEAD ^是正确的。请参见man git-rev-parse:修订参数的后缀^表示该提交对象的第一个父对象。前缀^符号用于从提交中排除可到达的提交。

–泰勒·里克(Tyler Rick)
13年2月13日在19:49

我只想分享另一种方法,这些方法似乎在所有方法中都是最干净且不那么复杂的:jasonrudolph.com/blog/2009/02/25/…完全简单而又令人敬畏

–superuseroi
14 Sep 15'0:03



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

–凯V
16年8月26日在5:16

#2 楼

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


从要合并的分支中找出路径,
 $ git checkout source_branch -- <paths>...

Hint: It also works without `--` like seen in the linked post.



或选择性地合并大块
 $ git checkout -p source_branch -- <paths>...



或者,使用reset,然后添加选项-p
    $ git reset <paths>...
    $ git add -p <paths>...



最后提交
 $ git commit -m "'Merge' these changes"




评论


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

–手枪
09年10月7日在2:07

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

– akaihola
2010-2-13在12:00

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

–michiakig
2011-2-15在4:09

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

– OderWat
2011年6月21日在6:16



根据这个答案git checkout -p -将与发出您描述的前三个命令相同:)

– 7hi4g0
15年1月22日在22:32



#3 楼

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

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


其中branchX是要合并到当前分支的分支。

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

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

1)您想要真正的合并。

在这种情况下,您会采用Git自动合并它们然后提交的方式接受合并的文件。

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

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

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

git checkout HEAD file1


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

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

运行:

git checkout branchX file1


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

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已成功自动合并的文件。

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

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

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


如果发现某些合并不合需要,则可以


直接编辑文件
保存
git commit

如果不想合并file1并想保留当前分支中的版本

运行

git checkout HEAD file1


如果不想合并file2,而只希望branchX中的版本


运行

git checkout branchX file2


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

此时,Git已将其合并。



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

评论


不过要小心:如果git merge --no-commit branchX只是一个快进,指针将被更新,因此--no-commit会被静默忽略

–cfi
2012年3月12日下午16:14

@cfi如何添加--no-ff以防止该行为?

–爱德华多·科斯塔(Eduardo Costa)
13年8月16日13:31

该解决方案可提供最佳结果和灵活性。

– Thiago Macedo
2014年7月24日在5:13

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

–ws_e_c421
2014年10月19日,12:54

大警告。该合并沿一个方向进行,但是如果您决定将上游母版合并回源分支,则未包含在合并中的文件将被视为DELETED。我使用类似git-flow的流程,该流程使用master分支(生产主线),staging分支(staging服务器主线)和基于staging分支的主题分支。使用这种策略导致我的“反向合并”从母版重新回到登台,从而导致竞争失败,因为我认为从登台到母版的所有未合并内容都被删除了。这包括整个文件和块。您被警告

– danielricecodes
18年2月7日在22:06

#4 楼

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

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

这里是替代方法:

您有一些更改在“功能”分支中,您希望以一种不草率的方式将其中的一些但不是全部都带到“主”中(即,您不想选择并提交每个人)

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

 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
 


评论


我固定了格式-如果您要选择提交,这是一种非常不错的方法

–1800信息
09年9月4日在10:57

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

– dylanfm
2010-2-10在11:24

您可能需要将git rebase -i $ to更改为git rebase -i $ to ||。 $ SHELL,以便用户可以在重新设置失败时根据需要调用git --skip等。还值得将这些行与&&(而不是换行符)链接在一起。

–西罗林顿
2011-2-24在18:10

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

– ThomasW
2012年4月6日在2:08

不仅链接已死,而且还有WOT信誉不良警告。因此,我将其删除。

–让·弗朗索瓦·科贝特(Jean-FrançoisCorbett)
2013年1月10日7:49



#5 楼

还有另一种方法:
git checkout -p

它是git checkoutgit 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.


评论


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

–泰勒·里克(Tyler Rick)
13年2月13日在19:56

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

–泰勒·里克(Tyler Rick)
13年2月13日在20:00

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

–丹尼尔·C·索布拉尔
13年2月26日在14:04

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

–infoclogged
16-3-2在15:33



#6 楼

尽管其中一些答案相当不错,但我觉得没有一个人能够真正回答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

这将为您提供每个文件所需的文件内差异。而已。没什么。在版本之间进行根本不同的文件更改很有用-就我而言,将应用程序从Ruby on Rails 2更改为Ruby on Rails3。
这将合并文件,但会进行智能合并。我无法弄清楚如何使用此方法来获取文件中的差异信息(也许仍然会存在巨大差异。除非您使用-s recursive -X ignore-all-space选项,否则讨厌的小东西(如空格)将被重新合并)

评论


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

–EMiller
2011年10月4日在22:37

这很漂亮。我做了git checkout功能 / *以获取文件组。

–艾舍伍德
2014年1月30日18:43



可以,但是添加了两个额外的提交对象。没什么大不了,但有点混乱

–MightyPork
2015年9月20日下午13:42

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

–胡锦涛
2015年9月22日在20:47

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

–MightyPork
15年9月22日在22:23

#7 楼

1800 INFORMATION的答案是完全正确的。但是,作为Git的新手,“使用git cherry-pick”还不足以让我不花更多时间在Internet上进行深入了解,所以我想我会发布更详细的指南,以防其他人
我的用例是希望有选择地将更改从其他人的GitHub分支拉到我自己的分支中。如果您已经具有更改的本地分支,则只需执行步骤2和5-7。


创建(如果未创建)具有要更改的本地分支引入。
$ git branch mybranch <base branch>


切换到其中。
$ git checkout mybranch


从其他项中提取您想要的更改人的帐户。如果还没有,请将其添加为远程计算机。
$ git remote add repos-w-changes <git url>


从其分支中删除所有内容。
$ git pull repos-w-changes branch-i-want


查看提交日志以查看所需的更改:
$ git log


切换回要添加更改的分支。
$ git checkout originalbranch


樱桃用哈希值一个接一个地选择提交。
$ git cherry-pick -x hash-of-commit



评论


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

– akaihola
2010-2-13在12:09

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

–RamPrasadBismil
16年5月12日在18:50

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

–creep3007
18年4月16日在7:00

链接被(有效)破坏:“需要身份验证... https://www.sourcemage.org正在请求您的用户名和密码。该站点显示:'Restricted Zone'。 (它也重定向到HTTPS。)

– Peter Mortensen
7月28日12:23



谢谢,我只是删除了它,因为我不确定目前在哪里可以找到原始文件

– Cory
7月29日12:09

#8 楼

这是用Myclass.java分支中的master替换Myclass.java分支中的feature1文件的方法。即使Myclass.java上不存在master也可以使用。

git checkout master
git checkout feature1 Myclass.java


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

评论


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

–Skunkwaffle
2013年9月6日20:59

完美的是,我一直在寻找这种合并,他们的合并会覆盖我们的合并=> +1欢呼;)

– oHo
2013年9月25日9:19



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

– MagicLAMP
2014年9月10日于1:30

鉴于OP特别想用另一个分支上的等效文件替换整个文件,因此是最干净的解决方案:2.手动将常见文件复制到temp目录中,然后从temp目录中复制到工作树中。

–布伦特·浮士德
2014-09-25 22:21



#9 楼

一种简单的方法,实际上是合并两个分支中的特定文件,而不仅仅是用另一个分支中的特定文件替换。
第一步:对分支进行区分
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有关更多选项的信息。
第三步:没有第三步
显然,您想提交更改,但是谁又说您在进行更改之前没有其他相关的调整呢?提交。

评论


这在current_branch有很多需要保留的“其他”更改的地方非常有用。得到由branch_b带来的仅更改的差异为:git diff HEAD ... branch_b(是的-三个周期进行了魔术)。

– Saad Malik
15年8月16日在20:08

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

–螺旋藻
16 Jan 20'在0:23



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

– LinusGeffarth
1月31日23:49

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

– Masukomi
2月5日17:12



#10 楼

即使更“简单”的合并会带来很多您不想要的更改,您也可以通过以下方法获得历史记录,以最小的麻烦跟踪另一个分支中的几个文件。
首先,您将采取非同寻常的步骤,即预先声明要提交的内容是合并,而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”分支应该是一个以上的不同分支。

评论


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

–RobM
2012年11月23日18:39

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

–timss
2014年5月11日12:33

这非常完美,我所做的唯一更改是执行了git merge --continue而不是最终的git commit。谢谢!

–约翰
9月14日下午16:36

#11 楼

我发现这篇文章包含最简单的答案。只需执行以下操作:
git checkout <branch from which you want files> <file paths>

示例
将.gitignore文件从branchB中拉到当前分支中:

评论


这实际上并没有合并,它会覆盖当前分支上的文件。

–伊戈尔·拉里奇(Igor Ralic)
2014年2月12日在17:13

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

–owensmartin
2014年8月15日在23:10

#12 楼

这是我用于合并选择性文件的工作流程。
# 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


评论


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

–马特佛罗伦萨
11年6月24日在2:49

#13 楼

最简单的方法是将存储库设置为要与之合并的分支,然后运行
如果运行
git checkout [branch with file] [path to file you would like to merge]

,您将看到文件已暂存。 。
然后运行
git status

简单。

评论


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

–superuseroi
14 Sep 15'0:02



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

– Amare
18年9月13日在0:04

我正要这样回答,我以为我发明了尚未得到回答的新事物!但这是最简单的方法。这应该是最重要的!

–艾凡迪·吉普(Irfandy Jip)
19/12/11在10:10

#14 楼

奇怪的是,Git仍然没有“开箱即用”这样方便的工具。
在更新一些旧版本分支(仍然有很多软件用户)时,我大量使用它,而当前版本仅提供了一些错误修复版本分支。在这种情况下,经常需要从主干中的文件中快速获取几行代码,而忽略了许多其他更改(这些更改本不应该包含在旧版本中)...
当然在这种情况下,需要交互式三路合并。 git checkout --patch <branch> <file path>不能用于此选择性合并。
您可以轻松做到:
只需将此行添加到全局[alias]或本地.gitconfig文件中的.git/config部分:
[alias]
    mergetool-file = "!sh -c 'git show : > .theirs; git show $(git merge-base  $(git rev-parse HEAD)): > .base; /C/BCompare3/BCompare.exe .theirs  .base ; rm -f .theirs; rm -f .base;' -"

它表示您使用超越比较。如果需要,只需更改为您选择的软件即可。或者,如果不需要交互式选择性合并,则可以将其更改为三向自动合并:
[alias]
    mergetool-file = "!sh -c 'git show : > .theirs; git show $(git merge-base  $(git rev-parse HEAD)): > .base; git merge-file  .base .theirs; rm -f .theirs; rm -f .base;' -"

然后像这样使用它:
git mergetool-file <source branch> <file path>

您将拥有另一个分支中任何文件的真正的选择性树方式合并机会。

#15 楼

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

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


它是一些答案的结合。

评论


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

–西蒙C.
18-2-14在14:15



#16 楼

我遇到了与您上面提到的完全相同的问题。但是我在解释答案时发现这个Git博客更加清晰。
以上链接的命令:
# You are in the branch you want to merge to
git checkout <branch_you_want_to_merge_from> <file_paths...>


评论


你测试了吗?我确定文件将从替换,而不是被合并

– Amare
18年9月13日在0:02

#17 楼

我会做一个

git diff commit1..commit2 filepattern | git-apply --index && git commit

这样,您可以限制分支中文件模式的提交范围。从一个分支到另一个分支?

评论


在某些情况下,这可能非常方便。但是,如果更改位于不同的分支中,则可以从该分支的尖端进行检出,如上述Bart J的回答。

– cdunn2001
2011年6月22日在8:26

谁是Bart Js?

–黑色
18年12月13日14:00

这与下面的git checkout branch相同...-删除分支中不存在的本地更改(!)。它们在补丁文件中被标记为“已删除”,因为纯差异不检查提交历史记录。

– Jan Stefanides
8月7日13:21

#18 楼

对我来说,git reset --soft branch是有选择地从另一个分支中选择更改的最简单方法,因为此命令将所有diff更改放入我的工作树中,因此我可以轻松地选择或还原所需的内容。

这样,我可以完全控制已提交的文件。

#19 楼

我喜欢以前的“ git-interactive-merge”答案,但有一个更简单。让Git使用交互式和以下代码的重新组合来为您完成此操作:
      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]


评论


您能否直接链接到您所指的其他答案(用户名不够稳定,因为它们可以随时更改)? (按“最旧的”排序,以限制可能的答案的数量(在您之前)。

– Peter Mortensen
7月28日12:42



@PeterMortensen好点,我敢肯定,我现在有合适的人选。

–韦德
8月2日,3:10

#20 楼

我写了自己的脚本“ 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 q4312078q` branch path"
    exit $E_BADARGS
fi

git merge  --no-commit
IFS=$'\n'

# List of changes due to merge | replace nulls with newlines | strip lines to just filenames | ensure lines are unique
for f in $(git status --porcelain -z -uno | tr 'q4312078q0' '\n' | sed -e 's/^[[:graph:]][[:space:]]\{1,\}//' | uniq); do
    [[ $f == * ]] && 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


#21 楼

您可以使用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中的子目录?

#22 楼

通过文件选择性合并/提交的简单方法:
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


评论


git reset --hard不会摆脱已提交的更改吗?

–普罗米修斯
9月4日23:19

@Prometheus,根据文档:“重置索引和工作树。自以来,工作树中跟踪文件的任何更改都将被丢弃。”因此,提交本身是安全的。

– pepoluan
12月21日7:35

#23 楼

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

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

2。重置为最后一个想要的提交$ git reset --hard HEAD~n,其中n是您需要返回的提交次数

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

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

#24 楼

如果您只需要合并一个特定的目录并保留所有其他内容并保留历史记录,则可以尝试一下...在尝试之前,从target-branch创建一个新的master

以下步骤假设您有两个分支target-branchsource-branch,并且要合并的目录dir-to-mergesource-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.


#25 楼

当两个分支的当前提交之间只有几个文件发生更改时,我将通过浏览不同的文件来手动合并更改。
git difftool <branch-1>..<branch-2>
另请参见
https://sites.google .com / site / icusite / setup / git-difftool