로컬 Git 리포지토리를 백업하는 방법? 좋은 방법 일 수 있습니다. 그러나

비교적 작은 프로젝트에서 git을 사용하고 있으며 .git 디렉토리의 내용을 압축하면 프로젝트를 백업하는 좋은 방법 일 수 있습니다. 그러나 복원 할 때 가장 먼저해야 할 일은이므로 이는 이상 git reset --hard합니다.

이런 식으로 git repo를 백업하는 데 문제가 있습니까? 또한 더 좋은 방법이 있습니까 (예 : 휴대용 git 형식 또는 이와 유사한 것)?



답변

나는 Yar의 스크립트에서 약간의 해킹을 시작했으며 그 결과는 매뉴얼 페이지 및 설치 스크립트를 포함하여 github에 있습니다.

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

설치 :

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

모든 제안을 환영하고 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

답변

다른 공식적인 방법은 git bundle을 사용하는 것입니다.

그러면 두 번째 리포지토리 를 지원 git fetch하고 git pull업데이트 하는 파일이 생성됩니다 .
증분 백업 및 복원에 유용합니다.

그러나 모든 오래된 것을 이미 백업 해야하는 경우 (이전에 오래된 콘텐츠가있는 두 번째 저장소가 없기 때문에) 다른 대답에서 언급했듯이 Kent Fredric 의 의견 다음에 백업이 좀 더 정교합니다 .

$ 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

( fantabolous에 의해 언급 된 것처럼 폴더 에서 아카이브를 만드는 것과는 반대로 원자 작업입니다 . ).git


경고 : 나는 저장소를 복제하는 Pat Notz솔루션을 권장하지 않습니다 .
많은 파일을 백업하는 것은 하나의 백업 또는 업데이트보다 항상 까다 롭습니다.

OP Yar answer 의 편집 히스토리 를 보면 Yar처음에 편집 에 사용 된 것을 볼 수 있습니다.clone --mirror

이것을 Dropbox와 함께 사용하는 것은 완전히 혼란 입니다.
동기화 오류가 발생하여 DROPBOX에서 디렉토리를 롤백 할 수 없습니다. 보관 용 계정에 백업
하려면 사용하십시오 git bundle.

Yar의 현재 솔루션 은을 사용합니다 git bundle.

난 내 경우를 휴식.


답변

나는이 작업을 수행하는 방법은 원격 (베어) 저장소를 생성하는 것입니다 (별도의 드라이브를 USB 키, 백업 서버 또는 GitHub의) 한 다음 사용 push --mirror(가) 멀리 떨어진입니다 제외하고 (정확히 내 지역과 같은 해당 원격 REPO 모양을 만들기 위해 베어 저장소).

이렇게하면 빨리 감기가 아닌 업데이트를 포함한 모든 참조 (분기 및 태그)가 푸시됩니다. 로컬 리포지토리의 백업을 생성하는 데 사용합니다.

매뉴얼 페이지 이런 식으로 설명 :

대신 밀어 각 REF 네이밍, 심판 미만임을 지정 $GIT_DIR/refs/(을 포함하지만 이에 한정되지 않고 refs/heads/, refs/remotes/, 및 refs/tags/)는 원격 저장소에 미러링 될 수있다. 새로 생성 된 로컬 참조는 원격 끝으로 푸시되고 로컬로 업데이트 된 참조는 원격 끝에서 강제로 업데이트되며 삭제 된 참조는 원격 끝에서 제거됩니다. 구성 옵션 remote.<remote>.mirror이 설정된 경우 이것이 기본값 입니다.

푸시를 수행하기 위해 별칭을 만들었습니다.

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

그런 다음 git bak백업을 원할 때마다 실행 됩니다.


답변

[내 자신의 참고를 위해 여기에 남겨 두십시오.]

내 번들 스크립트는 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

때로는 사용 git backup하고 때로는 사용하기 git backup different-name때문에 필요한 기능을 최대한 활용할 수 있습니다.


답변

이 질문에 대한 대답은 모두 정확하지만 여전히 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

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

답변

git-copy를 사용하여 git repo를 백업 할 수 있습니다 . git-copy는 새 프로젝트를 베어 리포지토리로 저장했습니다. 이는 최소 스토리지 비용을 의미합니다.

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

그런 다음 프로젝트를 복원 할 수 있습니다 git clone

git clone /backup/project.backup project

답변

위의 텍스트 벽을 넘어간 후 아무도 없다고 생각하게 만드는 간단한 공식 방법을 찾았습니다.

다음을 사용하여 완전한 번들을 작성하십시오.

$ git bundle create <filename> --all

다음을 사용하여 복원하십시오.

$ git clone <filename> <folder>

이 작업은 원자 AFAIK입니다. 자세한 내용은 공식 문서 를 확인 하십시오.

“zip”과 관련하여 : git 번들은 .git 폴더 크기에 비해 압축되어 놀랍도록 작습니다.