¿Cómo hacer una copy de security de un repository local de Git?

Estoy usando git en un proyecto relativamente pequeño y creo que comprimir los contenidos del directory .git podría ser una buena forma de hacer una copy de security del proyecto. Pero esto es un poco raro porque, cuando restauro, lo primero que tengo que hacer es git reset --hard .

¿Hay algún problema con la copy de security de un repository de git de esta manera? Además, ¿hay alguna forma mejor de hacerlo (por ejemplo, un formatting de git portátil o algo similar?)?

Empecé a piratear un poco el script de Yar y el resultado está en github, incluidas las páginas man y el script de installation:

https://github.com/najamelan/git-backup

Instalación :

 git clone "https://github.com/najamelan/git-backup.git" cd git-backup sudo ./install.sh 

Acogiendo con beneplácito todas las sugerencias y la request de extracción en 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 

La otra forma oficial sería usar package de git

Eso creará un file que soporta git fetch y git pull para actualizar tu segundo repository.
Útil para copy de security incremental y restauración.

Pero si necesita hacer una copy de security de todo (porque no tiene un segundo repository con contenido anterior), la copy de security es un poco más elaborada, como se menciona en mi otra respuesta, después del comentario de Kent Fnetworkingric :

 $ 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 

(Es una operación atómica , en lugar de hacer un file desde la carpeta .git , como lo comentó fantabolous )


Advertencia: No recomendaría la solución de Pat Notz , que es clonar el repository.
Copia de security de muchos files es siempre más complicado que realizar una copy de security o actualizar … solo uno.

Si miras el historial de ediciones de la respuesta de OP Yar , verás que Yar usó al principio un clone --mirror , … con la edición:

Usar esto con Dropbox es un desastre total .
Tendrá errores de synchronization y NO PUEDE VOLVER UN DIRECTORIO EN DROPBOX.
Use el git bundle si quiere realizar una copy de security en su Dropbox.

La solución actual de Yar usa git bundle .

Yo descanso mi caso.

La forma en que lo hago es crear un repository remoto (en una unidad separada, llave USB, server de respaldo o incluso github) y luego usar push --mirror para hacer que ese repository remoto se vea exactamente como el local (excepto el remote es un repository simple).

Esto impulsará todas las references (twigs y tags), incluidas las actualizaciones de avance rápido. Lo uso para crear copys de security de mi repository local.

La página man lo describe así:

En lugar de nombrar cada ref para enviar, especifica que todas las references bajo $GIT_DIR/refs/ (que incluye pero no se limita a $GIT_DIR/refs/ refs/tags/ ) se duplican en el repository remoto. Los refs locales recién creados se enviarán al extremo remoto, los refs localmente actualizados se actualizarán por la fuerza en el extremo remoto, y los refs eliminados se eliminarán del extremo remoto. Este es el valor pnetworkingeterminado si se establece la opción de configuration remote.<remote>.mirror .

Hice un alias para hacer el empuje:

 git config --add alias.bak "push --mirror github" 

Luego, solo ejecuto git bak cada vez que quiero hacer una copy de security.

[Solo dejo esto aquí para mi propia reference.]

La secuencia de commands de mi package llamada git-backup ve así

 #!/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 

Algunas veces uso git backup y algunas veces uso git backup different-name que me da la mayoría de las posibilidades que necesito.

Ambas respuestas a esta pregunta son correctas, pero todavía me faltaba una solución completa y breve para hacer una copy de security de un repository de Github en un file local. La esencia está disponible aquí, siéntase libre de tenedor o adaptarse a sus necesidades.

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 

restre.sh:

 #!/bin/bash # Restore the repository indicated in the command line # Example: # bin/restre filename.bak set -e FOLDER_NAME=$(echo $1 | sed 's/.bak//') git clone --bare $1 $FOLDER_NAME.git 

Puede hacer una copy de security del repository git con git-copy . git-copy ha guardado el nuevo proyecto como un repository simple, significa un costo mínimo de almacenamiento.

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

Entonces puedes restaurar tu proyecto con git clone

 git clone /backup/project.backup project 

Llegué a esta pregunta a través de google.

Esto es lo que hice de la manera más simple.

 git checkout branch_to_clone 

luego crea una nueva twig git desde esta twig

 git checkout -b new_cloned_branch Switched to branch 'new_cloned_branch' 

regrese a la twig original y continúe:

 git checkout branch_to_clone 

Asumiendo que te equivocaste y necesitas restaurar algo de la twig de respaldo:

 git checkout new_cloned_branch -- <filepath> #notice the space before and after "--" 

La mejor parte, si algo está mal, simplemente puede eliminar la twig fuente y volver a la twig de copy de security.