您如何组织多个git存储库,以便将它们全部一起备份?


98

使用SVN,我可以将一个大型存储库保存在服务器上,并在几台计算机上签出。这是一个非常不错的备份系统,使我可以轻松地在任何计算机上工作。我可以签出特定项目,提交并更新“主”项目,或者我可以签出整个项目。

现在,我有一堆用于各种项目的git存储库,其中一些在github上。我还提到了通过git-svn命令导入的SVN存储库。

基本上,我喜欢将我的所有代码(不仅是项目,还包括随机代码片段和脚本,诸如我的简历,我写的文章,我创建的网站等等)都放在一个大的存储库中,可以轻松地克隆到远程数据库中机器或记忆棒/硬盘驱动器作为备份。

问题是,由于它是一个私有存储库,而git不允许检出特定文件夹(我可以将pu作为单独的项目推送到github,但是更改要同时出现在master-repo和sub-回购)

可以使用git子模块系统,但是它并不能满足我的要求(子模块是指向其他存储库的指针,并且实际上不包含实际代码,因此对于备份没有用)

目前,我有一个git-repos文件夹(例如〜/ code_projects / proj1 / .git /〜/ code_projects / proj2 / .git /),在对proj1进行更改之后git push github,我将文件复制到〜/中。 Documents / code / python / projects / proj1 /并执行一次提交(而不是单个存储库中的众多提交)。然后做git push backupdrive1git push mymemorystick等等

那么,问题来了:您的个人代码和项目如何使用git存储库,并使它们保持同步和备份?

Answers:


74

强烈建议不要将无关的数据放在给定的Git存储库中。创建新存储库的开销非常低,并且该功能可以使不同的血统完全分开。

与这个想法作斗争意味着结束不必要的纠结的历史,这使得管理变得更加困难,而且更重要的是,“考古学”工具由于最终的稀释而变得不那么有用。而且,正如您提到的,Git假定“克隆单元”是存储库,并且由于其分布式性质,实际上必须这样做。

一种解决方案是保留每个项目/程序包/等。作为其自己的 存储库(即,没有工作树)在一个受祝福的层次结构下,例如:

/repos/a.git
/repos/b.git
/repos/c.git

一旦建立了一些约定,就可以将管理操作(备份,打包,Web发布)应用于完整的层次结构,这起了微不足道的作用,其作用与“整体式” SVN存储库完全不同。使用这些存储库也变得有点类似于SVN工作流,此外, 可以使用本地提交和分支:

svn checkout   --> git clone
svn update     --> git pull
svn commit     --> git push

每个工作克隆中可以有多个远程服务器,以简化多方之间的同步:

$ cd ~/dev
$ git clone /repos/foo.git       # or the one from github, ...
$ cd foo
$ git remote add github ...
$ git remote add memorystick ...

然后,您可以从每个“源”中获取/拉取,在本地进行工作和提交,然后在准备好类似的操作(注意如何将相同的提交和历史记录推入)后推(“备份”)到每个远程。每个遥控器!):

$ for remote in origin github memorystick; do git push $remote; done

将现有工作存储库~/dev/foo 转换为裸存储库的最简单方法可能是:

$ cd ~/dev
$ git clone --bare foo /repos/foo.git
$ mv foo foo.old
$ git clone /repos/foo.git

这几乎等同于svn import-,但不会丢弃现有的“本地”历史记录。

注意:子模块是一种包含共享相关 谱系的机制,因此,我确实不会将它们视为解决您要解决的问题的合适工具。


18
我一直以许多独立的存储库结尾,并编写简单的脚本来帮助管理它们,这一事实使我感到git中缺少某些内容。我只是无法确切地确定它是什么或该怎么做。
DonGar

好吧,您也管理很多单独的项目吗?在分布式环境中,项目与存储库之间的一对一关系是合理的,但是为了简化备份和管理,我仍将裸存储库放在公共目录树中。(换句话说,Git / Hg / Bzr迫使您将管理与项目任务分开,而大多数SVN工作流将两者混为一谈;现在人们经常看到将管理部分委派给GitHub或其他此类提供者。)
Damien Diederen

2
仅当您托管自己的项目和/或它们都是开源的时,这种想法才有意义。否则,您将需要在github上需要无限的私人项目,这些项目的成本可能会
很高

2
代替“对于远程源github记忆棒;执行git push $ remote;完成”,还可以配置一个特殊的远程对象,以单个命令将其推送到许多远程对象:stackoverflow.com/questions/36862/…。(在某些情况下可能会更方便。)
imz-伊万·扎哈拉里舍夫(Ivan Zakharyaschev

2
我认为缺少的东西是git可以按子树将其对象保持分开的方式,以便单个“存储库”可以由单独的同步但可分离的单元(单独下载而没有其余单元)组成,从而人们可以在特定的对象上工作。子集而不知道其余部分。
彼得2011年

28

我想在他建议地方添加达米恩的答案

$ for remote in origin github memorystick; do git push $remote; done

您可以设置一个特殊的遥控器,以使用1条命令将其推入所有单独的真实遥控器。我在http://marc.info/?l=git&m=116231242118202&w=2找到了它:

因此,对于“ git push”(多次推送同一分支是有意义的),您实际上可以执行我的操作:

  • .git / config包含:

    [remote "all"]
    url = master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
    url = login.osdl.org:linux-2.6.git
    
  • 现在git push all master会将“ master”分支推送到这两个
    远程存储库中。

您还可以使用以下结构来节省两次输入URL的麻烦:

[url "<actual url base>"]
    insteadOf = <other url base>

3

我也对处理此问题的建议方法感到好奇,并将描述我使用的当前设置(与SVN一起使用)。我基本上已经创建了一个存储库,其中包含一个小型文件系统层次结构,包括其自己的bin和lib dirs。这棵树的根目录中有脚本,该脚本将设置您的环境,以将这些bin,lib等...其他目录添加到适当的环境变量中。因此,根目录实质上如下所示:

./bin/            # prepended to $PATH
./lib/            # prepended to $LD_LIBRARY_PATH
./lib/python/     # prepended to $PYTHONPATH
./setup_env.bash  # sets up the environment

现在,在/ bin和/ lib内部有多个项目及其相应的库。我知道这不是一个标准项目,但是对于我团队中的其他人来说,很容易签出仓库,运行“ setup_env.bash”脚本,并在其本地拥有所有最新版本的项目。退房。他们不必担心安装/更新/ usr / bin或/ usr / lib的麻烦,这使得拥有多个签出项和每次签出具有非常本地化的环境变得很简单。有人也可以仅管理整个存储库,而不必担心卸载任何程序。

这对我们来说很好,我不确定是否要更改它。问题是在这个大的存储库中有很多项目。是否有git / Hg / bzr标准方法来创建这样的环境并将项目分解为自己的存储库?


3

,我还没有尝试过嵌套git存储库,因为我还没有遇到过需要的情况。正如我在#git通道上阅读的那样,git似乎由于嵌套存储库而感到困惑,即您正在尝试在git存储库中进行git-init。管理嵌套git结构的唯一方法是使用git-submodule或Android的repo实用程序。

至于您要描述的备份责任,我要说是委派 ……对我来说,我通常将每个项目的“原始”存储库放在工作的网络驱动器上,并由IT技术人员根据其备份策略定期进行备份。选择。这很简单,我不必担心。;)


2

怎么样用先生在一次管理您的多个Git的回购协议:

mr(1)命令可以检出,更新或对一组存储库执行其他操作,就好像它们是一个组合存储库一样。它支持Subversion,git,cvs,mercurial,bzr,darcs,cvs,vcsh,化石和真实性存储库的任意组合,并且可以轻松添加对其他版本控制系统的支持。[...]

它可以通过简单的shell脚本进行极其配置。它可以做的事情包括:

[...]

  • 更新git储存库时,请从两个不同的上游拉出并将两者合并在一起。
  • 并行运行多个存储库更新,从而极大地加快了更新过程。
  • 记住由于笔记本电脑脱机而失败的操作,因此可以在笔记本计算机恢复在线时重试。

1

还有另一种嵌套git repos的方法,但是它不能解决您所追求的问题。不过,对于正在寻找解决方案的其他人,我仍然是:

在顶层git repo中,只需将包含嵌套git repo的文件夹隐藏在.gitignore中即可。这使得拥有两个单独的(但嵌套的)git仓库很容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.