Git - 如何有选择地将更改从一个分支应用到另一个分支?

时间:2014-03-13 01:58:51

标签: git github workflow git-merge kdiff3

是否可以使用Git选择性地将更改从一个分支应用到另一个分支?

更具体地说,我使用GitHub的公共dev分支和部署的私有master分支。当对一个分支进行更改时,它们将需要应用于另一个分支,但是某些代码行需要保持不同。就我而言,它有几个css类和一个feed。

我是Git的新手,但我做了我的研究:

    可以使用
  • git merge --no-commit --no-ff后跟git mergetool来选择我想要的冲突情况。问题是它只适用于Git无法自动合并的冲突,所以在我有机会使用我的mergetool之前,我想保持不同的东西会被替换。

  • git difftool --cached很有用,因为它可以让我看到差异,但我需要复制我想要保留的内容并手动将其替换为文本编辑器,因为我不能简单地选择并保存就像我可以使用mergetool一样。

  • git cherry-pick似乎将指定的提交应用于另一个,但我希望保持不同的可能会分散到不同的提交中,这些提交可能不仅包括我想保持不同的内容。除非我做出数百万次让我疯狂的提交,否则我看不到这种情况。

另外要明确的是,我不希望一个分支成为另一个分支,合并的情况似乎如此。 我想要两个独立的分支,各自有不同的分支,并将变化从一个分支应用到另一个分支。

是否有更好的工作流程可以让我通过应用更改并保持一些差异来保留开发和部署版本?如果它导致解决方案,我不介意使用单独的存储库或不同的工具。

3 个答案:

答案 0 :(得分:12)

我也发现了修补问题:

创建补丁:git diff dev > master.patch

要应用它:patch < master.patch

答案 1 :(得分:3)

我认为没有办法从同一个文件中选择部分提交。我想说你需要简单地重新计算你的代码以将这些部分移动到不同的文件中。

顺便说一句,如果你想从提交中获取一些文件,你可以使用cherry-pick和其他命令的组合来解释here

答案 2 :(得分:0)

利用创建git分支便宜且不需要对工作目录的实际内容产生影响这一事实。

  1. 签出您的源分支dev
  2. 创建一个临时分支。它将指向与dev所做的同一提交:checkout -b for_master

    大概,您知道(或可以容易地找到)在dev分支之前的哪个提交是(部分)想要的更改之前的 前的最后一个提交。在此示例中,假设该提交具有哈希1457B4('last last',得到了吗?)。

  3. 将您的for_master分支重置为该提交:git reset 1457B4。 (不要不要使用--hard开关!)

    现在,您有了一个工作目录,其中包含dev中的所有更改,但是从for_master分支的POV来看,这些更改是未暂存和未提交的(而dev分支仍然指向记录所有更改的提交,因此工作仍然是安全的。)

  4. 使用交互式暂存(git add -p和/或git add -e),创建一个包含所有内容的提交(或多个,如果您愿意的话),并且仅 ,您要应用到master分支的更改。

    记下最后一次提交的哈希(或给它一个标签)。在此示例中,我将说它的哈希为C0DA

  5. 签出master

  6. 用樱桃挑选您刚刚提交的提交:git cherry-pick 1457B4..C0DA

    (请注意,仅在git版本1.7.2之后才可以选择范围。否则,您将需要单独对步骤4中所做的所有提交进行樱桃选择。)

    请注意,当您选择一个范围时,该范围的开始是先于将被实际选择的提交。)

此过程有点像选择答案中提到的使用git checkout -p的过程。这对于在共享一些代码但又有很多差异(例如,项目的两个主要版本之间)的两个分支之间创建cherry-pick-able的提交可能很有用,而您不必花费很多时间忽略了对git checkout -p的调用中不相关的文件。

就个人而言,我发现对同一存储库使用两个不同的工作树目录(一个用于源分支,一个用于目标)并在两个命令外壳之间切换非常方便,一个使用源分支目录(工作树),另一个目的地。但是,如果您不习惯使用git worktree功能,那可能不适合您。