7

在 git 和 git-hub 中处理两个独立但非常相似的代码库的最佳方法是什么?

背景

我有一个用于小型 shell 脚本项目的 git 存储库。它只有 2 或 3 个代码文件,而且我经常在一个文件中工作。尽管我最初制作该项目是为了服务于我的特定目标,但我编写它是为了对其他人更普遍有用。我编写通用用例版本,然后根据我的特定目标对其进行修改。在特定的版本中,我可能会修改变量、输入密码、切换某些代码的顺序、取出 for 循环……等等。

我试过什么

我尝试了两种不同的方法,但都没有我认为的那样最佳:

  1. 两个单独的回购
    • 问题:代码修改为一个,不能轻易和有选择地合并到另一个
  2. 一个仓库中有两个分支
    • 问题:分支最终会重新合并在一起。我的意思并不是要将它们完全合并在一起,而是有选择地合并部分代码。
    • 问题:我发现当尝试在分支之间使用合并命令时,很容易混淆哪个分支中的哪些代码被合并。我以某种方式在它们两个之间合并了完全无意的代码,并且在我查看两个分支中文件的内容之前,没有任何迹象表明合并不正确

我还看到了如何将两个单独但相似的代码库合并到一个 SVN 代表中?那是关于SVN的。因为我不知道 SVN,所以我很难跟上。我认为这是一个不同的问题,因为他并没有试图公开该代码的一个版本。

我想解决的用例

具体来说,当以下情况出现时,问题就会暴露出来:

  • 评论同步 - 我正在准备我的专业版本,并注意到我可以在行尾添加解释性评论。我添加了它,但评论现在不在通用版本中。
  • 我不想共享的东西 - 我正在准备我的专用版本,我添加了密码或更改操作的完成顺序。我不希望这些更改进入通用版本。
  • 同一个文件 - 上述两个更改通常在同一个文件中,这使得很难将内容合并在一起。有交互式合并,但我不知道是否可以在单个文件中完成交互。
  • 通用 -> 专业 - 我或其他人可能会更新通用版本以包含对我的专业版本也有用的新内容或评论。我想将这些从通用 -> 专业中引入,而不会弄乱专业版本中的任何其他代码差异。

Git 与 Github

大多数情况下,我的问题是想知道如何在 git 的范围内执行此操作。但是,它也可能对如何与 github 交互产生影响。我的通用版本在 github 上。专用版本不应该在 github 上。我认为如果我小心的话,我上面的分支方法并没有推动两个分支......但我总是不确定。无论哪种方式,解决方案都应该允许有一个公开的版本,以及一个仅保存在本地的版本……即使它有点复杂或需要小心。

4

4 回答 4

5

这可以通过两个分支轻松完成。我不知道你为什么说“代码在一个中修改,不能轻易和有选择地合并到另一个”,因为在 Git 中合并很容易。

我建议的结构是为您的通用版本设置一个分支,为您的个人版本设置一个分支。合并应该只发生在一个方向上,从一般分支到个人分支。这意味着您对通用版本所做的任何更改都会合并到个人版本中。

换句话说,这没问题...

git checkout personal
git merge general

这是你永远不应该做的...

git checkout general
git merge personal

如果您在个人版本中进行了更改,并认为在通用版本中使用相同的代码会很漂亮,那么您应该能够轻松地处理这个问题。在个人分支中组织提交只需要一点先见之明。您将需要在个人分支中提交仅包含您想要带到通用版本的那些更改,然后简单地将其从个人分支中挑选出来并将其放到通用分支上。

两个存储库可以完成同样的事情。这将降低您不小心将个人版本上传到 Github 的风险,但使用这两个不同的版本会更加乏味。

就个人而言,我会在同一个仓库中使用两个分支。

于 2011-11-07T15:13:57.990 回答
1

为避免将您的专用版本推送到 github,请将配置设置push.defaulttracking(或upstreamgit >= 1.7.4.2)。有关血腥细节,请参阅http://longair.net/blog/2011/02/27/an-asymmetry-between-git-pull-and-git-push/

无论您使用单独的 repo 还是仅使用一个分支,合并都应该同样有效。作为一个高层次的答案,你最终将不得不真正擅长合并。其中很多将来自真正深入研究 git 如何在低级别工作,涉及分支、合并和变基。与其他一些版本控制系统不同,我发现 git 需要深入了解其内部结构才能真正正确使用它。

于 2011-11-06T19:49:10.520 回答
1

我支持使用两个分支的想法:通用版本的公共分支(推送到 GitHub)和专用代码的私有分支(未在 GitHub 上发布)。但是,我想补充的是,这git stash是一个必不可少的工具,它允许您在您概述的场景中做您想做的事情(您正在处理个人版本,并且您发现要进行更改在一般版本中)。

始终在一般分支中实施一般更改确实是一种好习惯,然后执行

git checkout personal
git merge general

现在,您还可以有用地使用 git stash; 让我们以您正在更新专用版本并考虑一般更改的情况为例:

  1. 您将当前更改保存到专用版本:

    git stash
    

    与上次提交相比,这会隐藏更改,而无需创建新提交。这对于存储正在进行的未提交工作很有用。

  2. 您转到一般分支,以便进行您正在考虑的一般更改:

    git checkout general  # or master, or whatever name your general branch has
    

    然后,您可以实现您的一般修改并像往常一样提交它。

  3. 在恢复您的专业版本的工作之前,您导入一般更改:

    git checkout personal
    git merge general
    

    git 足够聪明,可以很好地做到这一点:只应对您的代码进行最新的、通常有用的更新。

  4. 您可以通过导入正在进行的隐藏工作来恢复您在专门分支上的工作:

    git stash pop
    

就这样!关键是git stash为了在工作过程中保存更改,而无需为此创建提交,然后使用git stash pop.

于 2011-11-07T15:28:21.363 回答
0

使用 git子模块。如果要保留子模块的单独分支,请在该项目的 repo 中创建一个分支,并将所有更改本地保存到该分支,并在子模块结帐中仅使用该分支。

不同变更集之间的合并是您需要半手动完成的事情。Git 有很好的合并支持,如果你不让两个分支彼此相距太远,你应该能够通过最少的手动干预来获得。github(或任何其他托管服务提供商)确实与这些无关。如果您想保持分支私有,请不要将其推送到公共存储库。就那么简单。

于 2011-11-06T19:28:49.570 回答