Git -如何选择性地将变更从一个分支应用到另一个分支



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

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

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

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

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

  • git cherry-pick似乎将指定的提交应用于另一个,但是我想保持不同的东西可能分散到不同的提交,这些提交可能不仅仅包括我想保持不同的东西。我不能看到这个工作,除非我做了数百万次的提交,这会把我逼疯的。

也要清楚,我不希望一个分支成为另一个,似乎是合并的情况。我想要两个独立的分支,它们各自不同,并将更改从一个应用到另一个

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

我也发现了补丁:

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

应用:patch < master.patch

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

  1. 检查你的源分支dev
  2. 创建临时分支。它将指向与dev相同的提交:checkout -b for_master

    想必,您知道(或者可以很容易地发现)在dev分支之前提交的是之前(部分地)想要的更改。在这个例子中,我们假设提交的哈希值是1457B4 ('last before',明白吗?)

  3. 重置你的for_master分支到commit: git reset 1457B4。(Do not使用--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可提交可能是有用的,这些分支共享一些代码,但也有很多差异(例如在项目的两个主要版本之间),并且您不想在调用git checkout -p时花费大量时间忽略无关文件。

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

我不认为有一种方法可以从同一个文件中选择提交的部分。我想说的是,你需要简单地重构你的代码,将这些部分移动到不同的文件中。

顺便说一句,如果你想从一次提交中获取一些文件,你可以像这里解释的那样,结合其他命令使用cherry-pick。