使用Git跟踪第三方代码

使用Git跟踪第三方代码,git,Git,我似乎无法探索我发现和研究的不同解决方案 用于跟踪外部代码。更不用说了解如何将它们应用于 我的用例 你们能帮我解释一下吗 我的特定用例?对于这个问题,什么是最好的解决方案 下面,具体问题是什么?(我不会试图概括我的观点 问题是,因为我可能会对事物做出错误的假设,尤其是 因为我对这一切都很陌生……) 我正在用Django(Python的web框架)构建一个网站。现在, 有很多第三方插件可用于Django (Django称之为“应用程序”),您可以将其放入项目中。一些 这些应用程序可能需要一些修改才

我似乎无法探索我发现和研究的不同解决方案 用于跟踪外部代码。更不用说了解如何将它们应用于 我的用例

你们能帮我解释一下吗 我的特定用例?对于这个问题,什么是最好的解决方案 下面,具体问题是什么?(我不会试图概括我的观点 问题是,因为我可能会对事物做出错误的假设,尤其是 因为我对这一切都很陌生……)

我正在用Django(Python的web框架)构建一个网站。现在, 有很多第三方插件可用于Django (Django称之为“应用程序”),您可以将其放入项目中。一些 这些应用程序可能需要一些修改才能像我一样工作 我想要他们。但是如果你开始修改第三方代码 介绍在出现较新版本时更新代码的问题 同时保留您的本地修改

因此,我在Subversion中实现这一点的方法是使用供应商分支。 我的存储库布局如下所示:

/trunk
  ...
  /apps
    /blog-app
  ...
/tags
  ...
/branches
  ...
/vendor
  /django-apps
    /blog-app
      /1.2
      /1.3
      /current
    /other-app
      /3.2
      /current
在这种情况下,/trunk/apps/blog app将是其中一个的svn副本 /vendor/django apps/blog app中的标记。说它是v1.2。及 我现在想把我的trunk版本升级到v1.3。尽你所能 看,我已经更新了/vendor/django apps/blog app/current (使用svn_加载_目录)和“标记”(svn副本)将其作为 /供应商/django应用程序/博客应用程序/1.3。 现在我可以通过svn合并更改来更新/trunk/apps/blog app 在/vendor/django apps/blog app/1.2和 /供应商/django应用程序/blog应用程序/1.3 on/trunk/apps/blog应用程序。这将 保留我的本地更改。 (对于不了解此过程的人员,请参见 颠覆手册: )

现在我想用Git完成整个过程。我该怎么做

让我重复一下需求:

  • 我必须能够将外部代码放置在树中的任意位置
  • 我必须能够修改外部代码并保存(提交)这些代码 修改我的Git回购协议
  • 我必须能够轻松地更新外部代码,如果一个新的 版本将被发布,同时保留我的更改
额外(奖励积分;-):

  • 我最好不要像svn_load_dirs这样的东西。我 我认为应该可以跟踪应用程序及其更新 直接从其存储库(大多数第三方Django应用程序保存在 颠覆)。使我能够查看更多的好处 发布之间的单个提交消息。和修复合并 冲突更容易,因为我可以处理很多小的提交 而不是svn_load_dirs创建的一个人工提交。 我想有人会用svn做这件事:Subversion中的externals,但我有 以前从未用过这个
两种方法结合使用的解决方案如下: 更可取的是,因为可能会有应用程序开发人员不这样做 使用源代码管理或不公开其回购协议。 (这意味着svn_load_dirs-like行为和直接从 Subversion reposity(或其他Git))

我想我要么使用子树、子模块、重基、分支。。。或者是这些的组合,但如果我知道是哪一个或是怎么做的话,就揍我一顿

我急切地等待你的答复!请尽量详细 回答的时候,因为我已经很难理解对方了 在网上可以找到例子


提前感谢

我在Django项目中使用git子模块跟踪可重用的应用程序,但从长远来看这有点混乱

这对于部署来说是混乱的,因为使用git archive无法获得整个树(带有子模块)的干净归档。有一些技巧,但没有完美的。 此外,子模块更新机制不太适合处理子模块分支

您可能需要看看virtualenv和pip,因为它们最近有一些改进,以便与外部存储库一起工作

pip:
使用pip/virtualenv时:

这里有两个独立的问题:

  • 如何维护远程项目的本地分支,以及
  • 如何在自己的树中保存远程项目的副本
  • 问题1本身就很简单。只需做如下操作:

    git clone git://example.com/foo.git
    cd foo
    git remote add upstream git://example.com/foo.git
    git remote rm origin
    git remote add origin ssh://.../my-forked-foo.git
    git push origin
    
    然后,您可以正常使用分叉存储库。如果要合并上游更改,请运行:

    git pull upstream master
    
    至于问题2,一种选择是使用子模块。为此,请将cd插入主项目,然后运行:

    git submodule add ssh://.../my-forked-foo.git local/path/for/foo
    
    如果我使用git子模块,我需要知道什么?

    您可能会发现git子模块有时有点棘手。以下是一些需要记住的事情:

  • 始终在提交父模块之前提交子模块
  • 始终在推送父模块之前推送子模块
  • 在提交之前,确保子模块的头指向分支。(如果您是bash用户,我建议使用将当前分支名称放在提示符中。)
  • 切换分支或拉取更改后,始终运行“git子模块更新”
  • 通过使用我的一位同事创建的别名,您可以在一定程度上解决(4):

    git config --global alias.pull-recursive '!git pull && git submodule update --init'
    
    …然后运行:

    git pull-recursive
    
    如果git子模块如此棘手,有什么好处?

  • 您可以签出主项目而不签出子模块。当子模块很大,并且在某些平台上不需要它们时,这非常有用
  • 如果您有经验的git用户,则可以拥有子模块的多个分支,并将它们与主项目的不同分支相链接
  • 有朝一日,可能有人真的会修复git子模块,使其更优雅地工作。子模块实现的最深部分实际上相当好;只是上层的工具坏了
  • git子模块不适合我。下一步是什么?

    如果您不想使用git子模块,您可能需要查看
    git svn clone -s https://example.com/foo
    cd foo
    git remote add origin ssh://.../my-forked-foo.git
    git push origin
    
    git push origin master:local-fork
    git checkout -b local-fork origin/local-fork
    
    git svn fetch
    git merge trunk
    
    git svn init -s https://example.com/foo
    git svn fetch