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

master:导入现有的代码库,再加上一些我通常确信的修改exp1:实验分支#1exp2:实验分支#2

exp1和exp2表示两种非常不同的体系结构方法。在我进一步相处之前,我无法知道哪一个(如果有的话)会起作用。当我在一个分支中取得进展时,我有时会对另一个分支进行有用的编辑,并希望仅合并这些编辑。

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

我考虑过的方法:

gitmerge——无需提交,然后手动取消大量编辑,我不想在分支之间共享这些编辑。手动将通用文件复制到临时目录中,然后git checkout移动到另一个分支,然后更多地手动将临时目录复制到工作树中。在上述基础上的变化。暂时放弃exp分支,使用另外两个本地存储库进行实验。这使得手动复制文件更加简单。

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


当前回答

我遇到了和你上面提到的完全相同的问题。但我发现这个Git博客在解释答案时更清晰。

来自以上链接的命令:

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

其他回答

我找到了一个解决这个问题的方法,这真的很简单。所以我只是把它放在这里给自己和其他想要使用这个解决方案的人。

答案假设我在包含单个文件file1.text的branch1中现在,我想将file1.txt与branch2中的另一个文件file2.txt合并。所以命令应该是,

git checkout --patch branch2 <path_of_file2.txt_in_context_of_branch2>

这会提示控制台,您需要输入特定字符以反映当前分支分支1中的更改。有时我用a来接受所有的帅哥。

我希望这个答案有帮助。谢谢

还有另一条路要走:

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.

我喜欢前面的“git交互式合并”答案,但有一个更简单。让Git使用交互式和到以下内容的重基组合为您实现这一点:

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

因此,您需要从“feature”分支(分支点“A”)中获取C1和C2,但目前没有其他分支。

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

正如前面的回答一样,这会让您进入交互式编辑器,在其中选择C1和C2的“pick”行(如上所述)。保存并退出,然后它将继续重新创建数据库,并为您提供分支“temp”和主机+C1+C2的HEAD:

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

然后,您只需将master更新为HEAD并删除临时分支即可:

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

我遇到了和你上面提到的完全相同的问题。但我发现这个Git博客在解释答案时更清晰。

来自以上链接的命令:

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

我不喜欢上述方法。使用cherry pick可以很好地选择一个改变,但如果你想带来所有的改变,除了一些不好的改变,这是一种痛苦。这是我的方法。

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

以下是备选方案:

您在分支“特性”中进行了一些更改,您希望以一种不拖泥带水的方式将其中的一些(但不是全部)提交给“主”(即,您不希望逐一挑选和提交)

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