如何在另一个存储库中使用git存储库?

我有一个Git媒体存储库,其中保存了我将在各种项目中使用的所有JavaScript和CSS主文件和脚本。

如果我在自己的Git存储库中创建了一个新项目,如何在新项目中使用媒体存储库中的JavaScript文件,使我在进行更改时不必更新脚本的两个副本?

146515 次浏览

键是git子

开始阅读Git社区手册用户手册的Submodules章节

假设您有存储库PROJECT1、PROJECT2和MEDIA……

cd /path/to/PROJECT1
git submodule add ssh://path.to.repo/MEDIA
git commit -m "Added Media submodule"

重复另一个回购…

现在,最酷的事情是,任何时候你提交更改到MEDIA,你可以这样做:

cd /path/to/PROJECT2/MEDIA
git pull
cd ..
git add MEDIA
git commit -m "Upgraded media to version XYZ"

这只是记录了PROJECT2内的MEDIA子模块现在处于版本XYZ的事实。

它可以让您100%控制每个项目使用的MEDIA版本。git子是伟大的,但你需要实验和学习他们。

力量越大,屁股被咬的几率越大。

如果我很了解你的问题,你想要以下东西:

  1. 您的媒体文件是否存储在一个git存储库中,许多项目都使用这个存储库
  2. 如果你在本地机器的任何一个项目中修改了一个媒体文件,它应该立即出现在每个其他项目中(所以你不希望一直都是提交+推+拉)

不幸的是,你想要的东西没有最终的解决方案,但有些事情可以让你的生活更轻松。

首先,您应该确定一件重要的事情:您是否希望在项目存储库中为每个版本存储对媒体文件版本的引用?例如,如果你有一个名为example.com的项目,你是否需要知道它2周前使用的是哪种样式。css,还是最新的总是(或大部分)最好的?

如果你不需要知道这些,解决方法很简单:

  1. 为媒体文件和每个项目创建一个存储库
  2. 在项目中创建一个指向本地克隆媒体存储库的符号链接。您可以创建一个相对的符号链接(例如../media),并假设每个人都将签出项目,以便媒体目录在相同的位置,或者将符号链接的名称写入.gitignore,每个人都可以决定他/她将媒体文件放在哪里。

然而,在大多数情况下,您都想知道这个版本信息。在这种情况下,你有两个选择:

  1. 将每个项目存储在一个大的存储库中。这种解决方案的优点是您将只有一个媒体存储库的副本。最大的缺点是很难在项目版本之间切换(如果你签入到不同的版本,你将总是修改所有的项目)

  2. 使用子模块(如答案1所解释的)。这样你将把媒体文件存储在一个存储库中,项目将只包含对特定媒体回收版本的引用。但是通过这种方式,您通常会有许多媒体存储库的本地副本,并且您不能轻松地在所有项目中修改媒体文件。

如果我是你,我可能会选择第一种或第三种解决方案(符号链接或子模块)。如果你选择使用子模块,你仍然可以做很多事情来让你的生活更简单:

  1. 在提交之前,您可以重命名子模块目录,并将符号链接放到公共媒体目录。当您准备提交时,您可以删除符号链接并将子模块移回,然后提交。

  2. 可以将媒体存储库的一个副本作为远程存储库添加到所有项目中。

您可以通过以下方式添加本地目录作为远程目录:

cd /my/project2/media
git remote add project1 /my/project1/media

如果你修改了/my/project1/media中的一个文件,你可以提交它并从/my/project2/media中提取它,而不需要将它推送到远程服务器:

cd /my/project1/media
git commit -a -m "message"
cd /my/project2/media
git pull project1 master

你可以稍后删除这些提交(git重置),因为你还没有与其他用户共享它们。

考虑使用子树而不是子模块,它将使你的回购用户的生活更容易。你可以在Pro Git书籍中找到更详细的指南。

我在子树和子模块上遇到了其他答案所暗示的问题……主要是因为我使用SourceTree,它似乎相当有bug。

相反,我最终使用SymLinks,这似乎工作得很好,所以我在这里发布它作为一个可能的替代方案。

这里有一个完整的指南:http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/

但是基本上你只需要在一个提升的命令提示符中mklink这两个路径。确保使用/J硬链接前缀。mklink /J C:\projects\MainProject\plugins C:\projects\SomePlugin

您还可以使用相对文件夹路径,并将其放在一个bat中,以便每个人在第一次检查您的项目时执行。

< p >的例子: mklink /J .\Assets\TaqtileTools ..\TaqtileHoloTools

. mklink /J .\Assets\TaqtileTools .

一旦文件夹被链接,您可能需要忽略主存储库中引用它的文件夹。否则就可以开始了。

请注意我已经从另一个帖子中删除了我的重复答案,因为那个帖子被标记为一个重复的问题。

相当多的项目,本质上是模块化的(因为git更喜欢不那么大的存储库),不需要成熟的配置阶段:您只需在给定的相对位置集中布局大量的存储库,就完成了。

在这种情况下,应该很容易使用this、this和this repo,这是git子模块、子树等尝试完成的。他们可以胜任这项任务,但我不认为他们很容易,也不容易出错。

“Git reppos in Git reppos”;并不需要很难:请参阅我的simplest-git-subrepos示例。