17

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

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

我是 Git 新手,但我进行了研究:

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

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

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

另外要明确的是,我不希望一个分支成为另一个分支,合并似乎就是这种情况。我想要两个具有各自差异的独立分支,并将更改从一个应用到另一个。

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

4

3 回答 3

19

我还发现了有关修补的信息:

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

要应用它:patch < master.patch

于 2014-03-13T20:32:40.030 回答
5

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

  1. 检查您的源分支dev
  2. 创建一个临时分支。它将指向相同的提交devcheckout -b for_master

    大概,您知道(或可以轻松找出)dev分支之前的哪个提交是您(部分)想要的更改之前的最后一个。在此示例中,假设该提交具有哈希值1457B4('last before',明白吗?)。

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

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

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

    记下最后一次提交的哈希(或给它一个标签)。在这个例子中,我会说它的哈希是C0DA.

  5. 退房master

  6. Cherry-pick 你刚刚做出的提交:git cherry-pick 1457B4..C0DA.

    (请注意,挑选范围仅在 git 版本 1.7.2 之后可用。否则,您需要单独挑选您在步骤 4 中所做的所有提交。)

    请注意,当您选择一个范围时,该范围的开始是实际选择的第一个提交之前的提交。)

此过程git checkout -p与所选答案中提到的使用相反。在共享一些代码但也有很多差异(例如,在项目的两个主要版本之间)的两个分支之间创建可提交可能很有用cherry-pick,并且您不希望花费大量时间忽略不相关的调用中的文件git checkout -p

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

于 2018-11-01T19:22:40.697 回答
4

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

顺便说一句,如果您想从提交中获取一些文件,您可以将cherry-pick 与其他命令组合使用,如此所述。

于 2014-03-13T10:34:30.583 回答