完全备份git repo?


136

有没有简单的方法来备份包括所有分支和标签的整个git repo?


2
我猜您在这里指的是本地git仓库。
Ztyx


3
正确的答案是这样做:git clone --mirror git@example.com/your-repo.git这将复制您的整个存储库,注释,分支,跟踪等。–
John,

我运行的一些网络搜索结果中未包含此问题:“ git clone绝对会克隆所有分支标记注释”;“ git克隆存储库中的所有内容”;“ git克隆带有所有标签注释的仓库”。
肯尼·埃维特

Answers:


64

克隆它怎么办?

git clone --mirror other/repo.git

每个存储库都是其远程服务器的备份。


7
@Daniel:如果克隆存储库,则将获取每个分支,但只会检出默认分支。尝试git branch -a。也许这样更明显:克隆存储库后,您无需获取每个分支,而是获取每个提交。分支仅引用现有的提交。
KingCrunch 2011年

1
如果他可以问这样的问题,我想他很了解克隆命令,显然这对他来说还不够(因为它是一个克隆,而不是转储)。转储是简单副本的不同之处,例如:1)对于正常工作,转储不需要是最佳的(甚至没有能力)2)但转储必须具有良好的抵抗力和可修复性,可防止数据损坏。
peterh-恢复莫妮卡

@peterh当然可以,但git clone涵盖了所有内容。(1)是可选的,不是必需的。如果结果仍然被优化,它仍然是git本身已经覆盖的备份(2)。-我想说明的一点是,如果git clone已经涵盖了相关要点,那么您需要其他工具吗?尽管我也更喜欢git bundle我,但我并不认为我的答案是错误的或无效的。您可以将两种方法都视为热备份与冷备份。
KingCrunch '16

那文件权限呢?git clone是否一定会复制过来?取决于我相信的选项
反领域

192
git bundle

我喜欢这种方法,因为它只能生成一个文件,因此更容易复制。
参见ProGit:一点点欢乐
另请参见“ 如何向某人发送git存储库的电子邮件? ”,其中的命令

git bundle create /tmp/foo-all --all

详细说明:

git bundle将仅打包git show-ref显示的引用:这包括标题,标签和远程标题。
目的地使用的依据非常重要。
可以谨慎一点,使捆绑文件包含目标中已经存在的对象,因为在目标中解包这些对象时会忽略这些对象,这是可以的。


要使用该捆绑包,您可以克隆它,并指定一个不存在的文件夹(在任何git repo之外):

git clone /tmp/foo-all newFolder

11
添加--all以进行完整备份
2011年

1
git bundle是我认为正确的答案,而不是公认的答案。如果他可以问这样的问题,我想他很了解克隆命令,这显然对他来说还不够(因为它是一个克隆,而不是转储)。转储是简单副本的不同事物,例如:1)对于正常工作,它们不需要是最佳的(甚至不是有能力的)2)但是它们必须具有良好的抵抗力和可修复性,以防止数据损坏3)它通常是有用的如果可以轻松地将它们用于增量备份,而对副本而言这不是一个目标。
peterh-恢复莫妮卡

3
请注意,无论是git bundle还是git clone获取所有内容,例如钩子脚本。
Zitrax

2
@Zitrax是的,这是设计使然。挂钩可能很危险或包含敏感信息。
VonC

我可以git bundle用于远程仓库吗?
Ryan Shillington

24

扩展其他答案,这就是我要做的:

设置仓库: git clone --mirror user@server:/url-to-repo.git

然后,当您想刷新备份时:git remote update从克隆位置。

这会备份所有分支和标记,包括稍后添加的新分支和标记,尽管值得注意的是,被删除的分支不会从克隆中删除(对于备份来说可能是一件好事)。

这是原子的,因此没有简单副本会出现的问题。

参见http://www.garron.me/en/bits/backup-git-bare-repo.html


20

扩展KingCrunchVonC的绝佳答案

我将它们结合在一起:

git clone --mirror git@some.origin/reponame reponame.git
cd reponame.git
git bundle create reponame.bundle --all

之后,您将拥有一个reponame.bundle可以轻松复制的文件。然后,您可以使用从其中创建一个新的普通git存储库git clone reponame.bundle reponame

请注意,git bundle仅副本提交会在存储库中导致某些引用(分支或标记)。因此,纠结提交不会存储到分发包中。


1
好总结。+1。
VonC

2
我想你的意思是git bundle create reponame.bundle --all

感谢@joe注意到这一点。绝对是 我将更新答案。
Kimmo Ahokas

4

一切都包含在.git目录中。就像备份任何文件一样,只需将其与项目一起备份即可。


2
这是否意味着仅备份包含Git项目的目录中的所有内容就足够了?
Ravindranath Akila

1
与Sunil达成协议-这似乎不是原子操作。
jia103 2014年

1
以及如何确保在创建备份时不对该目录中的文件进行任何更改?
Raedwald

正如Raedwald所暗示的那样,此方法可能导致备份不一致,从而导致数据丢失。因此,应该删除此答案,或者至少警告有关数据丢失的可能性。
Abhishek Anand

我认为他非常了解copycp命令,因此不适合他的需求。而且我还认为,他认为是在裸存储库上(尽管也可以复制它,但我认为它不是功能齐全的备份)。
彼得-恢复莫妮卡

4

使用git bundle或克隆

复制git目录不是一个好的解决方案,因为它不是原子的。如果您的大型存储库需要很长时间才能复制,并且有人将其推送到您的存储库,则会影响您的备份。克隆或制作捆绑包不会出现此问题。


3

您可以使用最小存储大小的git-copy备份git repo 。

git copy /path/to/project /backup/project.repo.backup

然后,您可以使用 git clone

git clone /backup/project.repo.backup project

2
github.com/cybertk/git-copy/blob/master/bin/git-copy#L8-L36:对于一个简单的git clone --bare+来说,似乎需要做很多工作git push --force
VonC 2015年

@VonC是的,但是它在重新打包期间可以具有一些附加功能,或者可以挖掘git repo的内部结构,可以将其用于一些优化(目标的重组或速度的提高等)。
peterh-恢复莫妮卡

3

IMO的正确答案是git clone --mirror。这将完全备份您的存储库。

Git克隆镜像将克隆整个存储库,注释,标题,参考等,通常用于将整个存储库复制到新的git服务器。这将拉下所有分支以及所有内容,整个存储库。

git clone --mirror git@example.com/your-repo.git
  • 通常,克隆仓库不包括所有分支,仅包括Master。

  • 复制repo文件夹将仅“复制”已拉入的分支...因此默认情况下仅是Master分支或您先前已签出的其他分支。

  • Git bundle命令也不是您想要的:“ bundle命令会将通常使用git push命令通过网络推送的所有内容打包为一个二进制文件,您可以通过电子邮件将其发送给某人或放入闪存驱动器,然后取消捆绑到另一个存储库中。” (从git clone --mirror和git clone --bare有什么区别


git clone --mirror是否创建一致的时间点备份?在备份过程中,用户推送提交的内容是什么?是拒绝,排队还是将其合并到备份中?
本杰明·古德克莱

3

该线程对于获取一些有关如何执行git repos备份的见解非常有用。我认为它仍然缺少一些提示,信息或结论来寻找适合自己的“正确方法”(tm)。因此,在这里分享我的想法可以帮助他人,并提出讨论以增强他们的见识。谢谢。

因此,从整理原始问题开始:

  • 目标是尽可能接近git存储库的“完整”备份。

然后用典型的愿望丰富它并指定一些预设:

  • 最好通过“热拷贝”进行备份,以避免服务停机。
  • git的缺点将通过其他命令来解决。
  • 脚本应执行备份,以将多个步骤组合为一个备份,并避免人为错误(打字错误等)。
  • 另外,脚本应执行还原以使转储适应目标计算机,例如,自备份以来,即使原始计算机的配置也可能已更改。
  • 环境是Linux计算机上的git服务器,其文件系统支持硬链接。

1.什么是“完整” git repo备份?

关于什么是“ 100%”备份,观点有所不同。这是两个典型的例子。

#1开发人员的观点

  • 内容
  • 参考资料

git是一个开发人员工具,并通过git clone --mirror和支持这种观点git bundle --all

#2管理员的观点

  • 内容文件
    • 特殊情况“ packfile”:git在垃圾回收期间将对象组合并压缩为packfile(请参阅参考资料git gc
  • git配置
  • 可选:操作系统配置(文件系统权限等)

git是一个开发人员工具,将其留给管理员。git配置和OS配置的备份应与内容备份分开。

2.技术

  • “冷复制”
    • 停止该服务以对其文件具有独占访问权。停机时间!
  • “热复制”
    • 服务提供了用于备份目的的固定状态。正在进行的更改不会影响该状态。

3.其他需要考虑的话题

它们中的大多数对备份都是通用的。

  • 是否有足够的空间容纳完整备份?将存储几代?
  • 是否需要增量方法?将存储几代,以及何时再次创建完整备份?
  • 如何验证备份在创建后还是在一段时间后没有损坏?
  • 文件系统是否支持硬链接?
  • 将备份放入单个存档文件还是使用目录结构?

4. git提供什么来备份内容

  • git gc --auto

    • docs:man git-gc
    • 清理并压缩存储库。
  • git bundle --all

    • docs:man git-bundle,man git-rev-list
    • 原子=“热复制”
    • 捆绑包是转储文件,可以直接与git一起使用(验证,克隆等)。
    • 支持增量提取。
    • 可通过验证git bundle verify
  • git clone --mirror

    • docs:man git-clone,man git-fsck,git clone --mirror和git clone --bare有什么区别
    • 原子=“热复制”
    • 镜像是真正的git存储库。
    • 该命令的主要目的是构建一个完整的活动镜像,该镜像会定期从原始存储库中获取更新。
    • 支持同一文件系统上的镜像的硬链接,以避免浪费空间。
    • 可通过验证git fsck
    • 镜像可用作完整文件备份脚本的基础。

5.冷复制

冷拷贝备份始终可以进行完整的文件备份:拒绝对git repos的所有访问,进行备份并再次允许访问。

  • 可能的问题
    • 拒绝所有访问,例如通过文件系统的共享访问,可能并不容易,甚至可能。
    • 即使该回购位于只有一个用户的仅客户机上,该用户在自动备份运行期间仍可能会提交某些内容:(
    • 服务器上的停机时间可能不可接受,并且备份多个巨大的存储库可能需要很长时间。
  • 缓解思路:
    • 通常,即使客户端在同一台计算机上,也要防止通过文件系统直接回购访问。
    • 对于SSH / HTTP访问,请使用git授权管理器(例如gitolite)以脚本方式动态管理访问或修改身份验证文件。
    • 备份存储库一个接一个,以减少每个存储库的停机时间。拒绝一个回购,进行备份并再次允许访问,然后继续下一个回购。
    • 制定有计划的维护时间表,以免开发人员烦恼。
    • 仅在存储库已更改时备份。可能很难实现,例如,对象列表以及考虑的打包文件,配置和钩子的校验和等。

6.热复制

由于正在进行的提交会损坏数据,因此无法使用活动仓库进行文件备份。热备份为备份目的提供了活动存储库的固定状态。正在进行的提交不会影响该副本。如上所述,git的克隆和捆绑功能支持此功能,但是对于“ 100%管理员”备份,必须通过其他命令来完成几件事。

“ 100%管理员”热拷贝备份

  • 选项1:用于git bundle --all分别创建内容的完整/增量转储文件和复制/备份配置文件。
  • 选项2:分别使用git clone --mirror,处理和复制配置,然后进行镜像的完整文件备份。
    • 笔记:
    • 镜像是一个新的存储库,在创建时会使用当前的git模板进行填充。
    • 清理配置文件和目录,然后从原始源存储库复制配置文件。
    • 备份脚本也可以在镜像上应用操作系统配置,例如文件权限。
    • 使用支持硬链接的文件系统,并在与源存储库相同的文件系统上创建镜像,以提高速度并减少备份期间的空间消耗。

7.恢复

  • 检查并采用git配置目标机器和最新的“行事方式”理念。
  • 检查并采用针对目标机器的OS配置和最新的“行事方式”理念。

0
cd /path/to/backupdir/
git clone /path/to/repo
cd /path/to/repo
git remote add backup /path/to/backupdir
git push --set-upstream backup master

这将创建一个备份并进行设置,以便您可以执行git push更新您的备份,这可能是您想做的。只要确保/ path / to / backupdir和/ path / to / repo至少是不同的硬盘驱动器,否则这样做就没有多大意义。


如果他可以问这样的问题,我想他很了解克隆命令,这显然对他来说还不够(因为它是一个克隆,而不是转储)。转储是简单副本的不同事物,例如:1)对于正常工作,它们不需要是最佳的(甚至不是有能力的)2)但是它们必须具有良好的抵抗力和可修复性,以防止数据损坏3)它通常是有用的如果可以轻松地将它们用于增量备份,而对副本而言这不是一个目标。
peterh-恢复莫妮卡

0

这里有两个选择:

  1. 您可以直接获取git repo目录的tar,因为它具有服务器上repo的全部裸内容。进行备份时,可能会有人在做回购。

  2. 以下命令将为您提供repo的裸露克隆(就像服务器中一样),然后您可以毫无问题地获取克隆位置的tar。

    git clone --bare {your backup local repo} {new location where you want to clone}
    

如果他可以问这样的问题,我想他很了解克隆或tar命令,并且显然这对他来说还不够(因为它是一个克隆,而不是转储)。转储是简单副本的不同事物,例如:1)对于正常工作,它们不需要是最佳的(甚至不是有能力的)2)但是它们必须具有良好的抵抗力和可修复性,以防止数据损坏3)它通常是有用的如果可以轻松地将它们用于增量备份,而在副本中则不是很确定。
peterh-恢复莫妮卡

3
peterh,肯定他不是在要求tar或clone命令。如果您仔细观察,我也不会解释这些命令。我试图解释的是通过不同方法进行的Git备份,其中可能包括各种Linux命令,但这并不意味着我在教那些Linux命令。我试图在这里提出一些想法。
vishal sahasrabuddhe'Apr 11'16

0

如果在Github上,请导航至bitbucket,然后使用“导入存储库”方法将github存储库作为私有存储库导入。

如果在bitbucket中,请反之。

这是完整备份,但保留在云中是我的理想方法。


-7

据我所知,您只需复制您的存储库所在的目录就可以了!

cp -r project project-backup

有人可以确认吗?我认为这是进行正确备份的正确方法。
Ravindranath Akila

5
我认为在复制操作期间将更改提交/推送到存储库时,您可能会得到不一致的快照。使用类似git的命令git clone --bare将为您提供一致的快照。
Eelke

1
与Sunil达成协议-这似乎不是原子的。
jia103 2014年

1
@ jia103如果它不是原子的,这并不总是一个问题-您只需要知道并且需要能够保证在处理仓库时没有其他人可以到达仓库。但是我认为OP想要一个特定的,针对git repos优化的工具来完成任务,简单的文件复制可能对他而言是众所周知的。
peterh-恢复莫妮卡
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.