我在一个相对较小的项目上使用git,我发现压缩.git目录的内容可能是备份项目的好方法.但这有点奇怪,因为当我恢复时,我需要做的第一件事就是git reset --hard.
以这种方式备份git repo有什么问题吗?还有,有没有更好的方法(例如,便携式git格式或类似的?)?
Von*_*onC 142
另一种官方方式是使用git bundle
这将创建一个文件,支持git fetch并git pull更新您的第二个回购.
对增量备份和还原很有用.
但是如果你需要备份所有内容(因为你没有第二个包含已经存在的旧内容的回购),那么在我的其他答案中提到肯特弗雷德里克的评论后,备份就更复杂了:
$ git bundle create /tmp/foo master
$ git bundle create /tmp/foo-all --all
$ git bundle list-heads /tmp/foo
$ git bundle list-heads /tmp/foo-all
Run Code Online (Sandbox Code Playgroud)
(这是一个原子操作,而不是从制造存档.git文件夹中,作为评价由fantabolous)
警告:我不推荐Pat Notz的解决方案,它正在克隆回购.
备份许多文件总是比备份或更新更棘手...只有一个.
如果你看一下编辑的历史的的OP亚尔 的答案,你会看到亚尔使用起初clone --mirror,......与编辑:
与Dropbox一起使用这是一个混乱.
您将有同步错误,并且您无法在DROPBOX中返回目录.
使用git bundle,如果你想备份到您的Dropbox.
Yar 目前的解决方案使用git bundle.
我休息一下.
Pat*_*otz 62
我这样做的方法是创建一个远程(裸)存储库(在一个单独的驱动器,USB密钥,备份服务器甚至github上)然后push --mirror用来使远程仓库看起来像我的本地(除了远程是裸机)库).
这将推送所有引用(分支和标记),包括非快进更新.我用它来创建本地存储库的备份.
该手册页描述它是这样的:
代替命名每个裁判推的,指定了下的所有参考文献
$GIT_DIR/refs/(包括但不限于refs/heads/,refs/remotes/和refs/tags/)被镜像到远程存储库.新创建的本地引用将被推送到远程端,本地更新的引用将在远程端强制更新,并且已删除的引用将从远程端删除.如果remote.<remote>.mirror设置了配置选项,则这是默认设置.
我做了一个别名来做推:
git config --add alias.bak "push --mirror github"
Run Code Online (Sandbox Code Playgroud)
然后,git bak只要我想做备份,我就会运行.
Dan*_*ark 35
[离开这里供我自己参考.]
我调用的bundle脚本git-backup看起来像这样
#!/usr/bin/env ruby
if __FILE__ == $0
bundle_name = ARGV[0] if (ARGV[0])
bundle_name = `pwd`.split('/').last.chomp if bundle_name.nil?
bundle_name += ".git.bundle"
puts "Backing up to bundle #{bundle_name}"
`git bundle create /data/Dropbox/backup/git-repos/#{bundle_name} --all`
end
Run Code Online (Sandbox Code Playgroud)
有时我会使用git backup,有时候我会使用git backup different-name它,这给了我所需要的大部分可能性.
小智 24
我开始在Yar的脚本上进行一些攻击,结果是在github上,包括手册页和安装脚本:
https://github.com/najamelan/git-backup
安装:
git clone "https://github.com/najamelan/git-backup.git"
cd git-backup
sudo ./install.sh
Run Code Online (Sandbox Code Playgroud)
欢迎所有建议并在github上提取请求.
#!/usr/bin/env ruby
#
# For documentation please sea man git-backup(1)
#
# TODO:
# - make it a class rather than a function
# - check the standard format of git warnings to be conform
# - do better checking for git repo than calling git status
# - if multiple entries found in config file, specify which file
# - make it work with submodules
# - propose to make backup directory if it does not exists
# - depth feature in git config (eg. only keep 3 backups for a repo - like rotate...)
# - TESTING
# allow calling from other scripts
def git_backup
# constants:
git_dir_name = '.git' # just to avoid magic "strings"
filename_suffix = ".git.bundle" # will be added to the filename of the created backup
# Test if we are inside a git repo
`git status 2>&1`
if $?.exitstatus != 0
puts 'fatal: Not a git repository: .git or at least cannot get zero exit status from "git status"'
exit 2
else # git status success
until File::directory?( Dir.pwd + '/' + git_dir_name ) \
or File::directory?( Dir.pwd ) == '/'
Dir.chdir( '..' )
end
unless File::directory?( Dir.pwd + '/.git' )
raise( 'fatal: Directory still not a git repo: ' + Dir.pwd )
end
end
# git-config --get of version 1.7.10 does:
#
# if the key does not exist git config exits with 1
# if the key exists twice in the same file with 2
# if the key exists exactly once with 0
#
# if the key does not exist , an empty string is send to stdin
# if the key exists multiple times, the last value is send to stdin
# if exaclty one key is found once, it's value is send to stdin
#
# get the setting for the backup directory
# ----------------------------------------
directory = `git config --get backup.directory`
# git config adds a newline, so remove it
directory.chomp!
# check exit status of git config
case $?.exitstatus
when 1 : directory = Dir.pwd[ /(.+)\/[^\/]+/, 1]
puts 'Warning: Could not find backup.directory in your git config file. Please set it. See "man git config" for more details on git configuration files. Defaulting to the same directroy your git repo is in: ' + directory
when 2 : puts 'Warning: Multiple entries of backup.directory found in your git config file. Will use the last one: ' + directory
else unless $?.exitstatus == 0 then raise( 'fatal: unknown exit status from git-config: ' + $?.exitstatus ) end
end
# verify directory exists
unless File::directory?( directory )
raise( 'fatal: backup directory does not exists: ' + directory )
end
# The date and time prefix
# ------------------------
prefix = ''
prefix_date = Time.now.strftime( '%F' ) + ' - ' # %F = YYYY-MM-DD
prefix_time = Time.now.strftime( '%H:%M:%S' ) + ' - '
add_date_default = true
add_time_default = false
prefix += prefix_date if git_config_bool( 'backup.prefix-date', add_date_default )
prefix += prefix_time if git_config_bool( 'backup.prefix-time', add_time_default )
# default bundle name is the name of the repo
bundle_name = Dir.pwd.split('/').last
# set the name of the file to the first command line argument if given
bundle_name = ARGV[0] if( ARGV[0] )
bundle_name = File::join( directory, prefix + bundle_name + filename_suffix )
puts "Backing up to bundle #{bundle_name.inspect}"
# git bundle will print it's own error messages if it fails
`git bundle create #{bundle_name.inspect} --all --remotes`
end # def git_backup
# helper function to call git config to retrieve a boolean setting
def git_config_bool( option, default_value )
# get the setting for the prefix-time from git config
config_value = `git config --get #{option.inspect}`
# check exit status of git config
case $?.exitstatus
# when not set take default
when 1 : return default_value
when 0 : return true unless config_value =~ /(false|no|0)/i
when 2 : puts 'Warning: Multiple entries of #{option.inspect} found in your git config file. Will use the last one: ' + config_value
return true unless config_value =~ /(false|no|0)/i
else raise( 'fatal: unknown exit status from git-config: ' + $?.exitstatus )
end
end
# function needs to be called if we are not included in another script
git_backup if __FILE__ == $0
Run Code Online (Sandbox Code Playgroud)
这两个问题的答案都是正确的,但我仍然缺少一个将Github存储库备份到本地文件的完整,简短的解决方案.这里有要点,随意分叉或适应您的需求.
backup.sh:
#!/bin/bash
# Backup the repositories indicated in the command line
# Example:
# bin/backup user1/repo1 user1/repo2
set -e
for i in $@; do
FILENAME=$(echo $i | sed 's/\//-/g')
echo "== Backing up $i to $FILENAME.bak"
git clone git@github.com:$i $FILENAME.git --mirror
cd "$FILENAME.git"
git bundle create ../$FILENAME.bak --all
cd ..
rm -rf $i.git
echo "== Repository saved as $FILENAME.bak"
done
Run Code Online (Sandbox Code Playgroud)
restore.sh:
#!/bin/bash
# Restore the repository indicated in the command line
# Example:
# bin/restore filename.bak
set -e
FOLDER_NAME=$(echo $1 | sed 's/.bak//')
git clone --bare $1 $FOLDER_NAME.git
Run Code Online (Sandbox Code Playgroud)
在穿过上面的文字墙后发现了简单的官方方式,这会让你认为没有。
使用以下内容创建完整的捆绑包:
$ git bundle create <filename> --all
Run Code Online (Sandbox Code Playgroud)
恢复它:
$ git clone <filename> <folder>
Run Code Online (Sandbox Code Playgroud)
AFAIK 这个操作是原子操作。检查官方文档以获取详细信息。
关于“zip”:git 捆绑包经过压缩,与 .git 文件夹大小相比非常小。
您可以使用git-copy备份 git repo 。git-copy将新项目保存为裸仓库,这意味着最低存储成本。
git copy /path/to/project /backup/project.backup
Run Code Online (Sandbox Code Playgroud)
然后你可以恢复你的项目 git clone
git clone /backup/project.backup project
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
119297 次 |
| 最近记录: |