【问题标题】:Git: how to merge modified files onlyGit:如何仅合并修改的文件
【发布时间】:2011-03-07 20:10:31
【问题描述】:

我有以下问题: 我们有一个大型产品在 master 分支中。此外,我们还有其他只有很少文件的分支,这些文件仅特定于该分支。这些分支中的每一个都代表主产品的一个插件。因此,例如,当您获得主要产品时,您会收到大量文件,安装它们等,然后当您决定获得插件时,您会收到一个仅包含几个文件的包,并通过上传这些文件(并替换原始文件) ) 你安装了插件。

让我在 master 分支(以及许多其他文件)中有 payment.php。我有一个paypal 分支,它只有一个文件,即payment.php。现在我修复了 master 的 payment.php 中的一个错误,并希望将此修复合并到 paypal 分支中。但是,当我运行合并时,绝对所有文件都会添加到该分支。所以最后 paypal 分支拥有来自 master 分支的所有文件。您是否偶然知道如何解决此问题?我希望 GIT 仅合并此分支中存在的文件,因此在上面的示例中,paypal 分支应该仍然只有一个文件(payment.php),其中合并了错误修复。

【问题讨论】:

  • 正如其他人所说,您可能不希望有一个缺少所有文件的分支。如果您真的想单独跟踪插件,它应该是一个单独的存储库,可能作为子模块包含在主项目中。如果你不希望它分开,那么当然,它可以有自己的开发分支,但作为项目存储库的一个分支,该分支应该包含整个项目,而不仅仅是一个插件。

标签: git merge branch


【解决方案1】:

这就是为什么管理好你的分支很重要,尤其是使用主题分支并向上合并。

你应该在一个主题分支上进行修复,从需要修复的所有分支的共同祖先派生,然后将其合并到 master 和 paypal:

x - x - x - x ------------- X (master)
|\                          |
| x - x - x ---- X (paypal) |
 \              /           /
  x (bugfix) ---------------

如果您已经进行了错误修复,并且您错误地在 master 上而不是从适当的合并基础上进行了修复,并且 master 上的历史尚未发布,您应该挑选或重新设置它到正确的位置:

# If the bugfix commit is not at the tip of master, you can rebase to get it there:
git rebase -i <commit before the bugfix> master
# rearrange the list of commits to put the bugfix at the tip, save and quit

# Now either cherry-pick or rebase the commit to the right place
# (rebase is easier if the bugfix is actually several commits)

# Cherry-pick
# make a branch and cherry-pick
git checkout -b bugfix <SHA1 of merge base>
git cherry-pick <SHA1 of bugfix>
# remove the commit from master, assuming it's still on the tip
git checkout master
git reset --hard master^

# or rebase
# make the bugfix branch (assuming it's still on the tip)
git branch bugfix master
# and remove the commit from master (assuming it's still on the tip)
git checkout master
git reset --hard master^    # or if the bugfix is composed of n commits, master~n
# rebase the bugfix branch to the right place
git rebase --onto <SHA1 of merge base> master bugfix

如果历史已经发布了,你所能做的就是在paypal分支上挑选bugfix,下次记得做对:

git checkout paypal
git cherry-pick <SHA1 of bugfix>

【讨论】:

  • 您好,我正在考虑拥有 paypal 分支并不时将 master 合并到其中。因此,当我需要实现新功能或修复错误时,我将在主文件中执行此操作,然后在发布之前我将合并贝宝分支中的更改(以便贝宝可以拥有新的修复和功能)。我对这些东西很陌生,所以如果我没有看到一些隐藏的问题,请纠正我。早些时候我一直在手动完成这项工作。所以我在 master 中实现了新功能,然后手动将代码复制到 paypal 分支。
  • 在上面的示例中,两个分支似乎非常不同(分支点之后的所有提交),而我的分支通常只有一个区别(例如贝宝功能)。其余的都是一样的,主要的工作是保持新的代码修改总是进入两个分支。当然,有时我有一个只针对 paypal 分支的修复程序,但这相当罕见,因为此时该代码已经过良好测试。
  • @Eugene:我真的不确定你想在这些 cmets 中问什么。无论如何,您始终可以从正确的分支点进行修改,然后将它们合并到所有需要它们的分支中。只要你的补丁仍然适用,这些分支有多么不同并不重要......
【解决方案2】:

为什么您的其他分支不包含属于 master 分支的所有文件?通过删除所有其他文件的麻烦,您只是让自己变得更难。特别是如果您以后最终需要更改已删除的其他文件。

【讨论】:

  • 实际操作中;修补程序需要进入特定的发布分支,而不是主要的。在这种情况下,您将有一个与 main 不是最新的发布分支,也就是文件不同,因此您需要这个樱桃采摘选项。
【解决方案3】:

你做错了。您应该拥有分支中的所有文件。

Git 的工作是跟踪分支之间哪些文件不同,而不是你的。 这就是使用 VCS 的要点之一。

如果您只想分发分支之间不同的文件,可以通过脚本轻松提取这些文件。

【讨论】:

  • 您好,感谢您的回复。我目前正在测试这个解决方案,并且很可能会使用它。
【解决方案4】:

你可以做类似这样的事情:http://nvie.com/git-model

(我希望这有效)

master 将继续是您的主要分支。您从 master 创建了第二个分支,名为 bugfix。您创建了名为 plugin-foo 的错误修复的第三个分支。

在 plugin-foo 中删除所有不需要的文件。现在,每当您对不在插件分支中的文件进行更改时,您都会在主分支上进行更改。所有错误修正都进入错误修正分支。您定期将错误修复分支合并到主分支和插件分支中。这会导致错误修复进入这两个分支。

【讨论】:

    【解决方案5】:

    将您的插件隔离在它们自己的 git 存储库中允许您在父项目上独立地对它们进行进化。

    但是,如果您需要将它们直接包含在您的项目中,则最近的 Git 版本(git1.7.11,2012 年 6 月)包括 git subtree script(以前 developed on GitHubapenwarr,现在合并到主线 git)

    这样,您可以将一个存储库(及其历史记录)合并到另一个存储库中,保留稍后提取其历史记录的选项(与子树合并相反)。
    这可以看作是 git 子模块的替代方案。

    另一种选择是git slave,以保持父 repo 和子模块紧密同步。

    【讨论】:

      猜你喜欢
      • 2018-01-15
      • 2010-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多