如何从合并中排除文件?

时间:2016-06-26 23:38:58

标签: git merge

刚刚开始围绕git,目前正在考虑合并。假设我有一个主分支,我创建了一个名为child的分支。我处理childbranch并更改一些文件。现在我想将这个childbranch合并到master分支中:

git merge child

然而,子分支中有一些文件(也在masterbranch中)我不想合并。如何将我的更改从子项合并到主服务器中,但从子项中排除特定文件?

2 个答案:

答案 0 :(得分:2)

简短的回答很简单:不。

长答案要复杂得多,但也等于“不”。基本上,您可以在某些情况下,让Git相信如果合并的双方发生更改,则更改始终冲突。请参阅this answer一个相关的问题(尽管我真正说的是你可以将文件标记为二进制文件,或者设置特殊的合并驱动程序,但是你需要了解很多背景知识才能达到这一点)。

如果您想避开某些文件,可以执行的操作是使用git merge运行--no-commit

$ git status
On branch master
nothing to commit, working directory clean
$ git checkout -b sidebranch
... lots of coding, git committing, etc
$ git checkout master
... more coding and committing, etc.,
    or various merges of other branches,
    so that master and sidebranch are
    actually divergent (if they are
    not, note that merge would
    normally do a "fast forward" here)
$ git merge --no-commit sidebranch

此时,Git将使用我在链接答案中描述的过程进行合并(通过做两个差异,然后组合两个差异)。但它不会自动提交生成的合并,即使成功

这意味着您现在可以执行此操作:

$ git rm path/to/ickyfile
    # we don't want this file, it's icky!

和/或这:

$ git checkout --ours -- path/to/foo; git add path/to/foo
    # we want the current (master) version of this file,
    # ignoring all the changes made in the side branch

甚至像这样的东西(但不要:结果有时被称为“邪恶合并”):

$ vim path/to/bar
<make changes that come from neither master nor sidebranch>
$ git add path/to/bar

一旦你完成所有事情,让坏事发生在良好的合并上:-)然后你可以运行git commit来完成合并。

一般情况下,如果您发现需要这样做,则可能使用了错误的工具。特别是,人们经常使用配置文件执行上述操作,当“正确”的事情是首先不要将这些文件放在Git(或任何版本控制系统)中。

(而是将示例配置文件放在VCS中。而不是prog.conf,添加并提交prog.conf.example。将prog.conf放入.gitignore对于新用户设置,您的安装/初始化代码可以根据需要将示例配置复制到位。)

答案 1 :(得分:0)

如果你犹豫要合并的原因是你会遇到合并冲突,我认为你不应该。 合并冲突解决虽然是一项难以学习的任务,但您可以从中获益匪浅。

但是,如果您现在不想这样做,或者您的问题是其他问题,我可以考虑从childbranch中排除文件的几种方法:

方法1。如果对文件的更改是在他们自己的提交中,那么您可以从这些提交中创建补丁,并通过交互式rebase从您的分支中“删除”这些提交,但是我怀疑是这种情况。但是,如果是,请执行以下操作:

git format-patch -1 commit_in_which_you_modified_the_file

假设您的分支有2个提交,请执行:

git rebase -i HEAD~3

这将带您进入一个类似

的菜单
pick commit_hash_of_1st_commit ...
pick commit_hash_of_2st_commit ...

假设您不想添加的文件是第一次提交的一部分,您将通过删除该行或将其注释掉来“删除”第一次提交:

# pick commit_hash_of_1st_commit ...
pick commit_hash_of_2st_commit ...

逃离编辑器,你应该拥有分支机构所需的东西。另外,请记住,您有一个补丁,稍后可以apply

Pros:
    - logically simple
    - idiomatically Git


Cons:
    - interactive rebase can be an overwhelming task the first time.

方法2。从您的分支中挑选出修改您不想提交的文件的特定提交。通过交互式rebase,edit这些提交。

假设您的分支有2个提交,请执行

    git rebase -i HEAD~3

这将带您进入一个类似

的菜单
    pick commit_hash_of_1st_commit ...
    pick commit_hash_of_2st_commit ...

假设您不想添加的文件是第一次提交的一部分,您将edit第一次提交:

edit commit_hash_of_1st_commit ...
pick commit_hash_of_2st_commit ...

此时,逃离编辑器。当你这样做时,Git将应用第一个提交,但事后你会edit

执行:

git reset HEAD~1

这将取消提交并取消暂停第一次提交的更改。这为您提供了一个干净的平板,可以在一次提交的上下文中重新开始

然后:

  • git add仅限您想要的更改
  • git commit
  • git add其余更改:
    • git diff > mypatch.patch

优点:

  • 这是正确的方法。

缺点:

  • 互动式篮板可以是第一次压倒性的运动 时间。

方法3。为您的分支添加最终提交,您可以在其中撤消对文件所做的所有更改。您可以参考此最终提交的更改集,以重新构建您希望稍后排除的文件所做的更改。

Pros:

    - easy to do (assuming there aren't too many changes)

Cons:

    - corrupts VC history
    - is not idiomatic usage of Git

方法4。如果您的分支有一个提交git reset HEAD~1,并且只重新提交您想要的内容。

Pros:
    - it is straightforward, basically a modification of one of the previous methods

方法5。创建一个新分支并重新开始。我不认为应该这样做,尽管鉴于你的分支的性质,它可能并不困难,并且可能是实用的方法。