【问题标题】:Can Git handles this use cases?Git 可以处理这个用例吗?
【发布时间】:2012-07-19 23:47:59
【问题描述】:

我目前正在从 SVN 迁移到 Git。代码库是一个 10-15 个模块的大型 Maven 项目。我们曾经为每个模块都有一个 repo。

我想知道 我的 Git 存储库应该采用什么架构来处理以下用例:

  • 用户可以签出 1..N 个模块。
  • John 提交并推入模块 M。Emma 从超级文件夹中提取更改。
  • John 提交并从超级文件夹推送模块 M 的更改。 Emma 从模块文件夹中提取更改。
  • John 将文件 A 从 M1 移动(使用 git mv)到 M2,提交并推送。 Emma 在提交前编辑文件 A 更新。该文件已随着 Emma 的更改而移动。

我想到了“单一存储库”架构,但没有处理 UC#1。 'submodule'、'subtree' 和以前的 'one-module-one-repo' 无法处理 UC#4。

此外,如果大多数用例都由“子模块”架构处理,我想引入尽可能少的复杂性。子模块引入了分离头之类的概念,并且在更频繁的错误后可能会导致痛苦的修复。

我进行了广泛的搜索,但我不确定在不引入太多复杂性的情况下是否可行,但我希望你们中的一些人一定找到了解决方法。

备注:我们当前的 SVN 架构无法处理这种用例。

非常感谢,马克西姆。

【问题讨论】:

  • 您的模块是否在 SVN 存储库中以 SVN 外部形式存在?据我了解,您希望在 Git 中具有相同的功能。对吗?
  • 即使我的模块没有通过 externals 定义注册到超级模块中(基本上对应 git 中的子模块功能),它是精神。但是,我也希望 Git 处理用例 #4
  • 如果你足够努力,你可能会想出 git 处理不同于 subversion 的各种场景。如果这是你的目标,那就坚持颠覆吧。当然,相反的情况也是可能的——在某些情况下,颠覆处理也不是最佳的。如果您的目标是迁移到 git,那么您的重点应该是确定 git 的最有效使用方式,而不是如何使 git 与您的颠覆工作流程相匹配。
  • 我一定是被误解了,我很抱歉。目前,SVN 不能正确处理(所有)这些情况。我不是在寻找 Git 中的缺陷,我只是不想利用这次迁移来改进我们的工作流程,让我们的日常工作更轻松。此外,我对 Git 的功能深信不疑,这就是我来到这里的原因,目的是寻求帮助并找到更好的解决方案。
  • 如果您将所有模块放在一个存储库的子目录中,我认为 SVN 会很好地处理您的用例。所以如果这些对你很重要,为什么不保留 SVN 并改变你的结构呢? (使用svnadmin dump 和svnadmin load --parent-dir,您甚至可以保留您的历史记录。)

标签: git version-control migration git-submodules


【解决方案1】:

你的分析是正确的;没有明显的方法可以一次解决所有这些用例。我会建议以下两种方法之一:

  1. 实际上可能不需要单独签出模块的第一个要求。使用 git,您在进行初始克隆时只需支付一次结帐费用,但之后增量更新非常快。
  2. 如果您正在处理 Maven 模块,也许每个模块都有自己的发布周期,那么这些模块真的需要源级关系吗?如果不是,那么模块依赖关系可以仅在 Maven 中表示。

真的,您可能应该从单个存储库开始,然后在您认为有必要时将其拆分。但你可能不会。 :)

【讨论】:

  • 终于有答案了!不是我想听到的,而是一个答案;)我同意你的第一点。但是,我忘了解释为什么我们要迁移到 Git。简而言之,目前的合并是焦虑的,因此开发人员会尽量避免合并。我们不想改掉这些坏习惯,Git 似乎是一个很好的解决方案。但是我必须保留用例 4(移动和编辑),以使 Git 在开发人员眼中具有明显的领先优势,并驯服对合并的恐惧。这就是我想要源级别关系的原因。
  • +1,从一个 repo 开始,这是覆盖最终用例的唯一方法。
  • 第 2 点 +1。如果每个模块都有自己的发布周期,则不适合将它们作为模块。
  • 在 2018 年,我认为 VFSForGit 可能会解决这个问题。 github.com/Microsoft/VFSForGit
【解决方案2】:

你不能拥有这一切。不在 GIT 上,也不在 SVN 上。

您已经意识到您的需求相互冲突,甚至承认您当前的设置并未涵盖所有情况,因此您应该改变处理此问题的方式。

与其要求工具提供某些功能,不如尝试解释需要解决的实际问题并让人们提出解决问题的方法,这些可能不是您已经考虑过的事情。

我现在就试着回答你在cmets上出现的问题,完全忽略你最初的要求,希望对你的实际情况有更多帮助。

我们无法承受每 (10-15) 个模块的提交消息显示在同一位置的时间线

与 SVN 不同,在 GIT 中,您有分支(真正的分支),并且每个分支都有自己的历史记录,因此只要您的开发人员使用分支并将它们合并而不是使用 rebase,您应该能够将每个分支日志与适当的命令,请参阅git log --graph 了解。

目前合并是令人焦虑的,因此开发人员会尽量避免合并

没有真正的解决方案,但有办法缓解这个问题。

一种方法是在主副本的同时拥有几个 repo 的克隆,如果您的团队大约 40 人并且您有 10-15 个模块,那么我猜您那里有专注于特定领域/模块的小团队;如果是这种情况,那么每个子团队都应该拥有自己的 repo 克隆并在本地合并,然后再合并回主副本。

这种方法有效地将合并过程(和职责)分为两个阶段,一个涉及子团队内部的更改,另一个处理与其余模块的交互。

但我必须保留用例 4(移动和编辑),以使 Git 在开发人员眼中具有明显的领先地位,并驯服对合并的恐惧

老实说,UC#4 是不可能的*。特别是在 GIT 上,mv 操作实际上是 rm 和 add 的组合。

也许如果添加发生在运动之前,一些 (d)VCS 可以解决它,但我认为 GIT 不是这种情况,即使如此我认为你采取了错误的方式来“驯服对合并的恐惧” "让我解释一下。

* @sleske 建议检查 this thread 以了解执行 UC#4 的方法

人们害怕合并的原因是因为他们不理解它,而 SVN 迫使您合并上游(即在服务器上)这增加了压力,您的方法的问题是试图帮助他们避免它您正在强化这样一种观点,即合并是应该避免的晦涩和危险的东西,不要这样做。

如果你想让他们克服恐惧,你需要对他们进行培训,让他们拥有处理这种情况的工具,换句话说,不要帮助他们避免问题,而是强迫他们解决问题,教他们所有的合并和冲突风格,告诉他们rerere,甚至教他们章鱼合并,我从来没有用过,但他也教他们什么!然后让他们练习,使其成为他们知道并且可以处理的东西。

GIT 中的合并不像 SVN 那样有压力,因为它们也是本地的,因此您可以根据需要进行多次合并,而不必担心会破坏其他人的环境,您只会在绝对完成后推动它们确定他们没事。

暂时就这些了,如果您还有其他问题,请添加评论,我会看看我是否有想法,祝您好运!

【讨论】:

  • 嗨,萨姆斯。首先,感谢您花时间回答。您关于解决提交混乱的第一点是值得怀疑的。实际上,您必须知道分支不是存储库,并且 dev 分支上每个模块的任何提交都将混合在同一历史记录中。关于合并,我没有考虑过您的解决方案,我认为它非常好。在告诉你它是否符合我们的要求之前,我需要先尝试一下。对于 UC#4,这是可能的,但只能以“单一存储库”的方式。
  • 最后,关于合并,我真的很想教他们如何使用 git :“好方法”。但是,IDE(IntelliJ)中的每个操作都应该是可能的,它具有很好的 Git 集成,IMO 不允许使用正确的 rerere。感谢一切,如果我找到“足够好”的解决方案,我会尝试更新这篇文章。
  • “UC#4 是不可能的”:我认为这是错误的。如果您在一个分支中移动文件并在另一个分支中更改它,git 将 通常会自动合并。参见例如stackoverflow.com/questions/2701790/…
  • 不错!请注意,他在抱怨我所指的合并冲突(删除/修改),但我不知道 rename-threshold 可能能够解决这个问题。我会编辑我的回复谢谢你的提示。
猜你喜欢
  • 2020-01-02
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 2012-10-24
  • 2016-04-28
相关资源
最近更新 更多