2010-02-12 8 views
16

에서 버전없는 파일을 유지하는 문제 것이 가능하다 : 나는 내가 유지 모든 위치/컴퓨터에서 참조 저장소로 사용하는 내 호스팅 파트너 장소에서 노출 된 자식 저장소를 생성 는 자식 저장소 여기

에서 내 프로젝트.

것은 내 프로젝트가 정기적으로 성장을 계속하는 sqlite db 파일을 사용한다는 것입니다 (현재 약 150MB). 시간이 지남에 따라 .git 폴더가 점점 더 커지고 있습니다 (최근에는 1GB 정도). 그리고 내 호스팅 공간이 제한됩니다.

이 DB 파일의 HEAD 버전을 포함하려면 맨 저장소가 필요하지만 실제로 버전 기록을 보관할 필요는 없습니다.

때때로 공간을 확보하기 위해 내역에서 db 파일을 제거하고 저장소를 정리하고 맨손 버전을 다시 만듭니다. 이것은 효과가 있지만 상당히 고통 스럽습니다.

마지막 버전의 파일 만 보관하고 기록을 삭제하도록 git에 지시하는 방법이 있습니까?

+1

관련 질문 : http://stackoverflow.com/questions/540535/managing-large-binary-files-with-git – jfs

+0

이것은 직접적인 해결책은 아니지만 데이터베이스 파일을 추적하지 않고 스크립트를 만드는 것이 좋습니다. 파일을 주 저장소의 파일과 동기화합니까? –

+0

스키마 또는 데이터의 복사본을 보관하려면 왜이 db 파일이 필요합니까? 아니면 둘다? –

답변

5

짧은 대답 : 아니오.

더 유용한 대답 : 힘내 파일을 개별적으로 추적하지 않으므로 단일 파일의 기록을 버리도록 요청하면 모든 커밋마다 모든 기록을 완전히 다시 써야한다는 것을 의미합니다. 종류의 추악한 문제.

파일을 주석 태그에 저장할 수는 있지만 그다지 편리하지는 않습니다. 그것은 기본적으로 다음과 같이 진행됩니다

ID=`git hash-object -w yourfile.sqlite` 
git tag -a -m "Tag database file" mytag $ID 

당신이 ... 당신이를 에뮬레이션 훅 스크립트를 사용해야 할 것 동안 그 편리하게 작업 트리에서 데이터베이스 파일을 갱신 (또는 생성) 않습니다 어떤 식으로.

전체 공개 : 정상적인 기록에 포함되지 않은 태그가있는 얼룩을 실제로 푸시 할 수 있는지 확실하지 않습니다. 나는 그렇지 않다고 생각하는데,이 조리법은 유용하지 않을 것이다.

3

언제든지 .gitignore 설정 파일을 사용할 수 있습니다.

그리고 ...

는 (에서 this thread! 비욘 Steinbrink에 대한 칭찬) 필터 지점

사용은 먼저, 을 유지하고 오래된 cruft에 드롭 할 커밋의 부모에게 을 드롭합니다.

예를 들어, $drop은 삭제하려는 최신 커밋 의 해시입니다. 을 평범하고 단순하게 유지하려면 계속 하시겠습니까? 예. $drop의 자식은 병합하지 않습니다. 커밋

git filter-branch --parent-filter "sed -e 's/-p $drop//'" \ 
    --tag-name-filter cat -- \ 
    --all ^$drop 

을 위는 $drop "후"온 모든 커밋의 부모를 재 작성 : 그럼 당신은 사용할 수 있습니다.

결과를 gitk로 확인하십시오.

그런 다음 모든 오래된 크래프트를 제거합니다.

첫째, 필터 지점에서 백업 참조 :

git for-each-ref --format='%(refname)'refs/original | \ 
    while read ref 
    do 
      git update-ref -d "$ref" 
    done 

그런 다음 세척 할 reflogs :

git reflog expire --expire=0 --all 

그리고 마지막으로, 재 포장 및 모든 오래된 도달 할 수없는 물건을 떨어 뜨리 : 자식이 을 재 포장 -ad git prune # 리팩 (repack)하는 객체에 대해 ~ 왼쪽으로 떠났을 수도있는 객체에 대해

그 시점에서, $ drop을 포함하여 까지가는 것은 이되어야합니다.

+0

저장소의 db 복사본을 보관하는 솔루션을 찾고 있습니다. –

+0

그런 다음 모든 커밋 후에 기록을 제거하는 스크립트를 만들 수 있습니다. –

4

잘못된 문제에 대한 해결책을 찾고있는 것처럼 들립니다.

대형 바이너리 파일은 리포지토리에 저장해야하는 경우가 많지만 실제로 SQLite 데이터베이스가 리포지토리의 바이너리 형식으로 저장해야한다고 생각하지 않습니다.

스키마를 버전 관리에 보관해야하며 데이터를 유지해야하는 경우 XML, JSON, YAML ...로 직렬화하고 버전도 함께 지정해야합니다. 빌드 스크립트는 데이터베이스를 생성하고 필요할 때 데이터를 직렬화 해제 할 수 있습니다.

텍스트 기반 직렬화 형식을 Git이 효율적으로 추적 할 수 있기 때문에 이전 버전을 유지하는 데 필요한 공간 오버 헤드에 대해 걱정할 필요가 없습니다.

+0

이렇게하면 git은 일반적인 압축과 diffing 기술을 적용하여 고통스럽지 않게 만들 수 있습니다. 처리해야 할 유일한 것은 diff의 크기를 최소화하는 적절하게 정렬 된 직렬화 형식을 만드는 것입니다. –

+0

동의하지 않습니다. 슬레이트 형식을 보면 이진 형식이 아닙니다. 힘내는 그것을 사용할 수있는 diff 파일을 완벽하게 생성 할 수 있습니다. 유일한 이점은 충돌이 발생할 경우 diff 파일을 읽기 쉽다는 것입니다. 당신이 나에게 묻는다면 텍스트 직렬화 계층을 다루는 것은 너무 많은 작업입니다 –

+0

이것은 멋진 아이디어입니다 ... 텍스트 기반의 직렬화에 대해 가지고있는 스크립트가 있습니까? – AlexMA

0

질문을 이해하는 한 간단한 해결책이 있다고 생각합니다.

  1. 먼저 백업 파일 어딘가에,
  2. 이 당신의 작업 디렉토리/트리에서 삭제. git rm, 그냥 rm.
  3. 커밋하십시오.
  4. 파일이 .gitignore에 추가되었는지 확인하십시오.

이후의 커밋에서 GIT는 더 이상 해당 파일을 추가하지 않습니다. 이전 커밋에 여전히 파일이 저장됩니다. 앞으로 커밋 할 때마다 추가하지 않을 것입니다. 이전 커밋에서 삭제하려면 내가 가지고있는 것보다 GIT 경험이 많은 사람에게 조언이 필요합니다.

0

.gitignore에 sqlite.db를 추가하십시오.

체크인 현재 지점으로 추진 (전위)에 대한 현재의 DB :

branch="$(sed 's,.*refs/heads/,,' "$(git rev-parse --git-dir)"/HEAD)" 
objectname=$(git hash_object -w "$(git rev-parse --show-toplevel)/sqlite.db") 
git tag -f db_heads/$branch $objectname 

분기 밀어 때

git fetch origin $branch tags/db_heads/$branch:tags/db_heads/$branch 
: 분기를 가져 오는

git push origin $branch +db_heads/$branch 

을 지점을 체크 아웃 할 때

:

git checkout $branch 
git cat-file -p db_heads/$branch >"$(git rev-parse --show_toplevel)/sqlite.db" 

그리고 그렇게해야한다고 생각합니다.