Comment sauvegarder un dépôt Git local?
j'utilise git sur un projet relativement petit et je trouve que zipping the .git contenu du répertoire pourrait être un bon moyen de sauvegarder le projet. Mais c'est un peu bizarre parce que, quand je restaure, la première chose que je dois faire est git reset --hard
.
y a-t-il des problèmes à sauvegarder un git repo de cette façon? De plus, y a-t-il une meilleure façon de le faire (p. ex. un format git portable ou quelque chose de semblable)?)?
7 réponses
j'ai commencé à pirater un peu le script de Yar et le résultat est sur github, y compris les pages de manuel et le script d'installation:
https://github.com/najamelan/git-backup
Installation :
git clone "https://github.com/najamelan/git-backup.git"
cd git-backup
sudo ./install.sh
accueillant toutes les suggestions et la demande de pull sur 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__ == "151910920"
l'autre voie officielle serait d'utiliser git bundle
Qui va créer un fichier git fetch
et git pull
afin de mettre à jour votre deuxième repo.
Utile pour la sauvegarde incrémentale et la restauration.
mais si vous avez besoin de sauvegarde tout (parce que vous n'avez pas un deuxième repo avec du contenu plus ancien déjà en place), la sauvegarde est un peu plus élaboré pour le faire, comme mentionné dans mon autre réponse, après Kent Fredric commentaire:
$ 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
(c'est une opération atomique , par opposition à faire une archive à partir du dossier .git
, comme commenté par fantabolous )
Attention: Je ne recommande pas Pat Notz 's solution , qui clone le repo.
La sauvegarde de nombreux fichiers est toujours plus délicate que la sauvegarde ou la mise à jour... juste une.
si vous regardez le historique des modifications du OP Yar réponse , vous verriez que Yar a d'abord utilisé un clone --mirror
,... avec le edit:
à l'Aide de ce avec Dropbox est un gâchis total .
Vous aurez des erreurs de synchronisation, et vous ne pouvez pas retourner un répertoire dans DROPBOX.
Utilisezgit bundle
si vous voulez sauvegarder jusqu'à votre dropbox.
Yar solution utilise git bundle
.
c'est terminé.
la façon dont je fais cela est de créer un référentiel distant (nu) (sur un lecteur séparé, une clé USB, un serveur de sauvegarde ou même github) et d'utiliser push --mirror
pour faire en sorte que ce référentiel distant ressemble exactement à mon référentiel local (sauf que la télécommande est un référentiel nu ).
cela poussera tous les ref (branches et étiquettes) y compris les mises à jour non-fast-forward. - Je l'utiliser pour créer des sauvegardes de mon dépôt local.
le page de manuel décrit comme ceci:
au lieu de nommer chaque ref à push, spécifie que tous les ref sous
$GIT_DIR/refs/
(qui inclut, mais n'est pas limité àrefs/heads/
,refs/remotes/
, etrefs/tags/
) être miroir au dépôt à distance. Les refs locaux nouvellement créés seront poussés à l'extrémité distante, les refs mis à jour localement seront mis à jour de force à l'extrémité distante, et les refs supprimés seront retirés de l'extrémité distante. C'est la valeur par défaut si le l'option de configurationremote.<remote>.mirror
est définie.
j'ai fait un alias pour faire la poussée:
git config --add alias.bak "push --mirror github"
ensuite, je lance git bak
quand je veux faire une sauvegarde.
[je laisse ça ici pour ma propre référence.]
mon script Pack appelé git-backup
ressemble à ceci
#!/usr/bin/env ruby
if __FILE__ == "151900920"
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
parfois j'utilise git backup
et parfois j'utilise git backup different-name
ce qui me donne la plupart des possibilités dont j'ai besoin.
les deux réponses à ces questions sont correctes, mais il me manquait encore une solution complète et courte pour sauvegarder un dépôt Github dans un fichier local. Le gist est disponible ici, n'hésitez pas à fourcher ou adapter à vos besoins.
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
restore.sh:
#!/bin/bash
# Restore the repository indicated in the command line
# Example:
# bin/restore filename.bak
set -e
FOLDER_NAME=$(echo | sed 's/.bak//')
git clone --bare $FOLDER_NAME.git
vous pouvez sauvegarder le git repo avec git-copy . git "copie de 151970920" sauvé nouveau projet comme un nu repo, il signifie un minimum de coût de stockage.
git copy /path/to/project /backup/project.backup
alors vous pouvez restaurer votre projet avec git clone
git clone /backup/project.backup project
est venu à cette question via google.
voici ce que j'ai fait de la manière la plus simple.
git checkout branch_to_clone
puis créer une nouvelle branche git à partir de cette branche
git checkout -b new_cloned_branch
Switched to branch 'new_cloned_branch'
revenez à la branche d'origine et continuez:
git checkout branch_to_clone
en supposant que vous avez foiré et besoin de restaurer quelque chose de la branche de sauvegarde:
git checkout new_cloned_branch -- <filepath> #notice the space before and after "--"
meilleure partie si quelque chose est foiré, vous pouvez juste supprimer la branche source et revenir à la branche de sauvegarde!!