git - 如何使用git-merge选择性合并文件 ?

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

  • master :导入现有代码库以及一些我通常确定的插件
  • exp1 :实验分支#1
  • exp2 :实验分支#2

exp1和exp2表示两种不同的架构,

将文件从一个开发分支合并到另一个开发分支,而不留下其他内容的最佳方法是什么?

时间:

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

如果需要更改不是单独提交,则使用下面所示的方法将提交拆分为单个提交 ,使用git rebase -i来编辑原始提交,然后git reset HEAD^有选择地还原更改,然后将git commit提交到历史记录中。

Red Hat Magazine中还有另一个不错的方法,它们使用git add --patch或可能的git add --interactive,如果你想拆分不同的文件(在该网页中搜索"分割")。

我在寻找答案的时候发现了这个 。

摘要:

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

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

  • 如果需要选择性地合并更改,请使用重置,然后添加,

    $ git reset <paths>...
    $ git add -p <paths>...

  • 最后提交

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

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


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

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

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

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

1)你想要真正的合并,在这种情况下,你接受合并文件的方式,Git合并它们,然后提交它们。

2)有些文件你不想合并,例如,要保留当前分支中的版本,并忽略要合并的分支中的版本。

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


git checkout HEAD file1

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

3)如果你想要branchX中的版本(而不是真正的合并),请运行:


git checkout branchX file1

这将在branchX中检索file1的版本,并覆盖Git自动合并的文件。

4)最后一种情况是,如果你只想在file1中选择特定的合并,在这种情况下,您可以直接编辑修改后的file1,将其更新为您想要的file1版本,然后提交。

如果Git无法自动合并文件,它将报告为"unmerged"文件并生成一个副本,你需要手动解决冲突。

用一个例子进一步说明,假设你要将branchX合并到当前分支中:


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

然后运行git状态命令来查看已修改文件的状态。

例如:


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
#

其中file1,file2和file3是git已成功自动合并的文件。

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

通过运行git diff cached文件来检查合并的完成方式,例如:


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

如果发现某些合并不受欢迎,可以直接编辑文件,保存,然后提交。

如果不希望合并file1并希望保留当前分支中的版本,请运行:


git checkout HEAD file1

如果你不想合并file2而只想要branchX中的版本,请运行,


git checkout branchX file2

如果你希望file3自动合并,请不要执行操作,Git已经在这个时候合并了它。

上面的file4是Git失败的合并,这意味着在两个分支都有变化,这是你需要手动解决冲突的地方,通过直接编辑文件或在要使file4成为分支的版本中运行该版本的checkout命令来丢弃合并的文件。

最后,不要忘记提交。

 
git commit

 

还有另一种方法:

 
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.

假设你有masterexp1exp2分支,你想将一个实验分支中的一个文件合并到主文件中,我可以这样做:


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

这为你提供你想要的每个文件的文件差异,

-s recursive -X ignore-all-space

可以将Myclass.java文件从feature1分支合并到master分支,即使Myclass.javamaster上不存在,它也会工作。


git checkout master
git checkout feature1 Myclass.java

...