Git으로 큰 바이너리 파일 관리


523

내 소스 코드 (웹 응용 프로그램)가 의존하는 큰 이진 파일을 처리하는 방법에 대한 의견을 찾고 있습니다. 현재 몇 가지 대안을 논의 중입니다.

  1. 이진 파일을 직접 복사하십시오.
    • 프로 : 확실하지 않습니다.
    • 대조 : 새 사이트를 설정하거나 이전 사이트를 마이그레이션 할 때 오류가 발생할 가능성이 높아 지므로 이에 반대합니다. 또 다른 장애물을 만듭니다.
  2. Git으로 모든 것을 관리하십시오 .
    • Pro : 중요한 파일을 '잊어 버릴'가능성을 제거합니다
    • 대조 : 리포지토리를 블로 트하고 코드베이스 및 체크 아웃, 클론 등을 관리 할 수있는 유연성이 상당히 저하됩니다.
  3. 별도의 리포지토리
    • 장점 : 소스 코드를 체크 아웃 / 복제하는 것이 그 어느 때보 다 빠르며 이미지는 자체 저장소에 올바르게 보관됩니다.
    • 대조 : 프로젝트에서 유일하게 Git 저장소를 갖는 단순성을 제거합니다 . 그것은 내가 생각하지 않은 다른 것들을 소개합니다.

이것에 관한 당신의 경험 / 생각은 무엇입니까?

또한 : 여러 Git 저장소에 대한 경험이 있고 하나의 프로젝트에서 관리하는 사람이 있습니까?

파일은 해당 파일이 포함 된 PDF를 생성하는 프로그램의 이미지입니다. 파일은 몇 년처럼 자주 변경되지 않지만 프로그램과 관련이 있습니다. 파일이 없으면 프로그램이 작동하지 않습니다.


26
바이너리 파일을 제어하는 ​​버전이 필요한 경우는 어떻습니까? 나는 자산을 다루는 예술가 팀을 생각하고 있습니다.
Dan

3
필요한 경우 사용 가능한 리소스 (디스크, 대역폭, CPU 시간)와 얻는 이점의 균형을 유지해야합니다.
pi.

4
파일 잠금이 없으면 git은 여러 사람이 동일한 이진 파일을 작업해야 할 때 좋지 않습니다.
yoyo

1
자식 기반 백업 파일 bup 도 참조하십시오 .
VonC

답변:


177

파일이 없으면 프로그램이 작동하지 않으면 별도의 저장소로 나누는 것이 좋지 않습니다. 우리는 별도의 저장소로 나누는 큰 테스트 스위트를 가지고 있지만 실제로는 "보조"파일입니다.

그러나 별도의 리포지토리에서 파일을 관리 한 다음 파일을 깔끔하게 git-submodule프로젝트로 가져 오는 데 사용할 수 있습니다. 그래서, 당신은 여전히 ​​모든 소스의 전체 역사를 가지고 있지만, 이해하는 것처럼 이미지 서브 모듈의 하나의 관련 개정 만 가질 것입니다. 이 git-submodule기능을 사용하면 올바른 버전의 이미지를 올바른 버전의 코드로 유지할 수 있습니다.

다음 은 Git Book의 서브 모듈에 대한 좋은 소개 입니다.


11
"알다시피, 당신은 당신의 이미지 서브 모듈의 하나의 관련 개정만을 가질 것입니다." 나는 이것이 옳지 않다고 생각합니다.
Robin Green

22
과연. 하위 모듈은 전체 Git 리포지토리이며, 상위 리포지토리 내에 중첩됩니다. 그것은 전체 역사를 알고 있습니다. 덜 자주 커밋 할 수는 있지만 부모와 동일한 것을 저장하면 부모와 같은 문제가 발생합니다.
Cascabel

5
일정한 간격으로 변경되는 큰 이진 파일이있는 경우 이것은 매우 좋지 않은 솔루션입니다. 새로운 바이너리 파일이 모든 빌드마다 저장되기 때문에 끔찍한 저장소가 있습니다. 아래에 언급 한 것처럼 Windows를 사용하지 않는 경우 Annex를 사용하는 것이 좋습니다. 당신이 Windows에 있다면 ... 계속보고해야합니다.
AA Grapsas

4
리포지토리에 큰 이진 파일을 갖는 또 다른 문제는 성능입니다. Git은 큰 이진 파일을 처리하도록 설계되지 않았으며 일단 repo 크기가 3G +로 올라가면 성능이 빠르게 떨어집니다. 즉, 리포지토리에 큰 바이너리가 있으면 호스팅 옵션이 제한됩니다.
zoul

하위 모듈을 창의적으로 잘못 사용하면 하위 모듈에서 결제 데이터 전송 요구 사항을 줄일 수 있습니다. 하위 모듈 내용을 업데이트하려는 경우 부모없이 새 커밋을 만든 다음 부모없이 슈퍼 프로젝트 (주 git 저장소)를 새로 만든 커밋으로 지정하십시오. 논리적으로 이것은 서브 모듈에 대한 연결이 끊긴 히스토리를 작성하지만 그 결과로 해당 버전에는 히스토리가 없으므로 서브 버전의 모든 버전을 전송하기가 더 쉽습니다.
Mikko Rantalainen

310

나는 최근에 git-annex를 발견했습니다 . 대용량 파일을 효율적으로 관리하도록 설계되었습니다. 내 사진 / 음악 등의 컬렉션에 사용합니다. git-annex의 개발은 매우 활발합니다. 파일의 내용은 Git 리포지토리에서 제거 할 수 있으며 트리 계층 만 Git에 의해 추적됩니다 (심볼릭 링크를 통해). 그러나 파일의 내용을 얻으려면 다음과 같이 당기거나 누른 후 두 번째 단계가 필요합니다.

$ git annex add mybigfile
$ git commit -m'add mybigfile'
$ git push myremote
$ git annex copy --to myremote mybigfile ## This command copies the actual content to myremote
$ git annex drop mybigfile ## Remove content from local repo
...
$ git annex get mybigfile ## Retrieve the content
## or to specify the remote from which to get:
$ git annex copy --from myremote mybigfile

사용 가능한 많은 명령이 있으며 웹 사이트에 훌륭한 문서가 있습니다. 패키지는 데비안에서 사용할 수 있습니다 .


11
우와! 경이로움에 찬성! 이것은 내가 최근에했던 아이디어를 구현합니다. 그것은 하스켈로 작성되었습니다. git-media는 좋은 대안입니다.
cdunn2001

33
그러나 Annex는 Windows를 지원하지 않습니다. 게임 개발자에게는 문제가됩니다.
AA Grapsas

7
Steam이 Windows에 대한 지원을 중단하고 Linux에 대한 지원을 추가한다고 들었습니다. 평범한 게임 개발자가 할 수있을 것 같아요.
Sam Watkins

4
@EstebanBrenes 실제 문제는 일반적인 구성에서 Windows 심볼릭 링크를 만들려면 높은 권한이 필요하다는 것입니다.
Laurens Holst

4
방금 이 페이지를 찾았습니다 . 이제 Windows 에서도 git annex사용할 수 있습니다. 누구든지 Windows에서 테스트 한 적이 있다면 그의 경험에 대해 듣고 싶습니다!
Kouichi C. Nakamura

49

2015 년 4 월 이후 다른 솔루션은 Git Large File Storage (LFS) (GitHub)입니다.

git-lfs를 사용합니다 (참조 git-lfs.github.com를 )하고이를 지원하는 서버와 테스트 : LFS-테스트 서버 :
당신은 오직 자식의 repo에서 메타 데이터를 저장할 수 있으며, 다른 곳에서 큰 파일.

https://cloud.githubusercontent.com/assets/1319791/7051226/c4570828-ddf4-11e4-87eb-8fc165e5ece4.gif


3
lfs-test-server프로덕션 용이 아닌 것으로 선언되었습니다. 실제로 프로덕션 LFS 서버 ( github.com/artemkin/git-lfs-server ) 에서 작업하고 있습니다. 현재 진행 중이지만 이미 서비스가 가능하며 사내에서 테스트하고 있습니다.
Stas

git lfs를 사용하여 이전 버전의 바이너리 파일을 체크 아웃 할 수 있습니까?
mucaho

1
@mucaho 당신은해야합니다 : git checkout의 구문은 변경되지 않고 lfs smudge 스크립트는 여전히 호출되어야합니다.
VonC

31

Git 저장소에 큰 바이너리를 스마트하게 저장하는 Git 확장 인 git bup 을 살펴보십시오 .

서브 모듈로 사용하고 싶지만 저장소를 처리하기가 어려울 염려가 없습니다. 샘플 사용 사례 중 하나는 VM 이미지를 Git에 저장하는 것입니다.

실제로 더 나은 압축률을 보지는 못했지만 리포지토리에는 실제로 큰 바이너리가 없습니다.

귀하의 마일리지가 다를 수 있습니다.


3
bup은 스토리지 (내부적으로 중복성을 위해 패리티 아카이브를 사용하고 압축, 중복 제거 및 히스토리를 위해 git를 사용함)를 제공하지만 git을 확장하지는 않습니다. git-annex는 bup 스토리지 백엔드 를 제공 하는 git 확장입니다 .
Tobu

나는이를 게시 할 때 @Tobu는 자식 부록은 아직 (주류 릴리스에서) 존재하지 않았다
sehe

2
bup은 큰 파일을 관리하는 데 확실히 흥미 롭습니다. UI의 차이점을 지적하고 싶었습니다. 저장소 컨텍스트 외부에서 bup 명령을 사용하고 git은 구현 세부 사항입니다.
Tobu

27

git-fat을 사용할 수도 있습니다 . 나는 그것이 파이썬과 주식에만 의존한다는 것을 좋아합니다 rsync. 또한 다음과 같은 자체 설명 명령을 사용하여 일반적인 Git 워크 플로를 지원합니다.

git fat init
git fat push
git fat pull

또한 .gitfat 파일을 리포지토리에 체크인하고 .gitattributes를 수정하여 git fat관리 하려는 파일 확장명을 지정해야합니다 .

normal을 사용하여 바이너리를 추가하면 gitattributes 규칙에 따라 git add호출 git fat됩니다.

마지막으로 바이너리가 실제로 저장된 위치를 리포지토리와 사용자간에 공유 할 수 있고 모든 것을 지원할 수 있다는 이점이 있습니다. rsync .

업데이트 : Git-SVN 브리지를 사용하는 경우 git-fat을 사용하지 마십시오. Subversion 저장소에서 바이너리 파일이 제거됩니다. 그러나 순수한 Git 저장소를 사용하는 경우 아름답게 작동합니다.


26

서브 모듈 (Pat Notz) 또는 두 개의 별개의 저장소를 사용합니다. 바이너리 파일을 너무 자주 수정하면 히스토리를 정리하는 거대한 저장소의 영향을 최소화하려고합니다.

나는 몇 달 전에 매우 비슷한 문제를 겪었습니다 : ~ 21GB의 MP3 파일, 분류되지 않은 (나쁜 이름, 나쁜 id3, 그 MP3 파일을 좋아하는지 여부를 모르겠습니다 ...), 세 대의 컴퓨터에서 복제했습니다.

주 Git 리포지토리와 함께 외장 하드 디스크 드라이브를 사용하여 각 컴퓨터에 복제했습니다. 그런 다음 습관적으로 분류하기 시작했습니다 (푸시, 당기기, 병합 ... 삭제 및 이름 바꾸기 여러 번).

결국 .git 디렉토리에 ~ 6GB의 MP3 파일과 ~ 83GB 만있었습니다. 나는 커밋 조상없이 새로운 커밋을 사용 git-write-tree하고 git-commit-tree만들었고 그 커밋을 가리키는 새로운 브랜치를 시작했습니다. 해당 브랜치의 "git log"에는 단 하나의 커밋 만 표시되었습니다.

그런 다음 이전 분기를 삭제하고 새 분기 만 유지하고 ref-log를 삭제 한 후 "git prune"을 실행합니다. 그 후 .git 폴더의 가중치는 ~ 6GB에 불과합니다.

같은 방법으로 때때로 거대한 저장소를 "퍼지"할 수 있습니다. "git clone"이 더 빠릅니다.


한 번의 저장소를 실수로 병합 한 두 개의 저장소로 분리 해야하는 비슷한 작업을 한 번 수행했습니다. 흥미로운 사용 패턴. :)
pi.

1
이것은 다음과 같을까요? rm -f .git; 자식 초기화; git add. ; git commit -m "히스토리를 버리십시오."
Pat Notz

1
예, mp3의 경우에만 동일합니다. 그러나 때로는 브랜치와 태그를 건드리고 싶지 않지만 (공개 리포지토리의 공간 축소 없음) 브랜치의 "git clone / fetch / pull"속도를 높이고 싶습니다 (전용 전용 공간 부족). 지사 리포지토리).
Daniel Fanjul

13

내가 제안하고 싶은 솔루션은 고아 브랜치와 약간의 태그 메커니즘 남용을 기반으로하기 때문에 * Orphan Tags Binary Storage (OTABS)라고합니다.

TL; DR 12-01-2017 github의 LFS 또는 다른 타사를 사용할 수 있다면 반드시해야합니다. 할 수 없다면 계속 읽으십시오. 이 솔루션은 해킹이므로주의해야합니다.

OTABS의 바람직한 특성

  • 그것은 순수한 자식자식입니다 솔루션 - 그것은 나 (GitHub의의 LFS 등) 제 3 자 인프라 (자식-부록 등) 모든 제 3 자 소프트웨어없이 일을 가져옵니다.
  • 바이너리 파일을 효율적으로 저장합니다 . 즉, 리포지토리의 기록을 팽창시키지 않습니다.
  • git pullgit fetch포함하여 git fetch --all여전히 대역폭 효율적입니다 즉, 모든 큰 바이너리는 기본적으로 원격에서 가져온되는 것은 아닙니다.
  • 그것은 Windows에서 작동 .
  • 단일 git 저장소에 모든 것을 저장 합니다. .
  • bup과 달리 오래된 바이너리 를 삭제할 수 있습니다 .

OTABS의 바람직하지 않은 속성

  • 그것은 수 git clone(사용량에 따라, 반드시 그런 것은 아니지만) 잠재적으로 비효율적. 이 솔루션을 배포하는 경우 동료 git clone -b master --single-branch <url>대신 사용하도록 조언해야 할 수도 있습니다 git clone. git clone은 기본적 으로 참조되지 않은 커밋과 같이 일반적으로 대역폭을 낭비하고 싶지 않은 것을 포함하여 전체 저장소를 문자 그대로 복제하기 때문 입니다. 에서 가져온SO 4811434 .
  • 그것은 만든다 git fetch <remote> --tags 비효율적 인 대역폭, 그러나 반드시 저장 비효율적. 동료에게 사용하지 말라고 항상 조언 할 수 있습니다.
  • 주기적으로 git gc더 이상 원하지 않는 파일에서 리포지토리를 정리 트릭 .
  • bup 또는 git-bigfiles 만큼 효율적이지 않습니다 . 그러나 그것은 당신이하려는 일과 더 많은 기성품에 각각 더 적합합니다. 수십만 개의 작은 파일이나 기가 바이트 범위의 파일에 문제가 생길 수 있지만 해결 방법은 계속 읽으십시오.

이진 파일 추가

시작하기 전에 모든 변경 사항을 커밋했는지 확인하고 작업 트리가 최신 상태이며 인덱스에 커밋되지 않은 변경 사항이 포함되어 있지 않습니다. 재난이 발생할 경우를 대비하여 모든 로컬 브랜치를 원격 (github 등)으로 푸시하는 것이 좋습니다.

  1. 새 고아 지점을 만듭니다. git checkout --orphan binaryStuff트릭을 할 것입니다. 이것은 다른 브랜치와 완전히 분리 된 브랜치를 생성하며,이 브랜치에서 첫 번째 커밋은 부모가 없으므로 루트 커밋이됩니다.
  2. 을 사용하여 색인을 정리하십시오 git rm --cached * .gitignore.
  3. 심호흡을하고을 사용하여 전체 작업 트리를 삭제하십시오 rm -fr * .gitignore. 와일드 카드가 일치하지 .git않기 때문에 내부 디렉토리는 그대로 유지 *됩니다.
  4. VeryBigBinary.exe 또는 VeryHeavyDirectory /에 복사하십시오.
  5. 추가 및 커밋
  6. 이제 까다로워집니다. 원격으로 분기로 밀어 넣으면 다음에 모든 개발자가 git fetch연결을 막을 때 호출하여 다운로드합니다 . 브랜치 대신 태그를 밀어서이를 피할 수 있습니다. 동료가 입력 습관이있는 경우에도 동료의 대역폭 및 파일 시스템 스토리지에 영향을 줄 수 git fetch <remote> --tags있지만 해결 방법을 읽어보십시오. 가서git tag 1.0.0bin
  7. 고아 태그를 누릅니다 git push <remote> 1.0.0bin.
  8. 이진 브랜치를 실수로 밀어 넣지 않도록 삭제할 수 git branch -D binaryStuff있습니다. 커밋은 가비지 수집으로 표시되지 않습니다. 고아 태그를 가리키면 1.0.0bin살아남기에 충분합니다.

이진 파일 확인

  1. 현재 작업 트리에 VeryBigBinary.exe를 체크 아웃하려면 어떻게해야합니까? 현재 작업 지점이 마스터와 같은 경우 간단히git checkout 1.0.0bin -- VeryBigBinary.exe .
  2. 고아 태그를 1.0.0bin다운로드 하지 않으면 미리 실패해야 git fetch <remote> 1.0.0bin합니다.
  3. VeryBigBinary.exe마스터에 추가하면 .gitignore팀의 아무도 아무도 실수로 이진 파일로 프로젝트의 주요 기록을 오염시키지 않습니다.

이진 파일을 완전히 삭제

로컬 저장소, 원격 저장소 및 동료의 저장소에서 VeryBigBinary.exe를 완전히 제거하기로 결정한 경우 다음을 수행 할 수 있습니다.

  1. 리모컨에서 고아 태그를 삭제하십시오. git push <remote> :refs/tags/1.0.0bin
  2. 고아 태그를 로컬로 삭제하십시오 (참조되지 않은 다른 모든 태그를 삭제) git tag -l | xargs git tag -d && git fetch --tags. SO 1841341 에서 가져온약간 수정 .
  3. git gc 트릭을 사용하여 참조되지 않은 커밋을 로컬에서 삭제하십시오. git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@". 또한 참조되지 않은 다른 모든 커밋도 삭제합니다. SO 1904860 에서 찍은
  4. 가능하면 리모컨에서 git gc 트릭을 반복하십시오. 리포지토리를 자체 호스팅하는 경우 가능하며 github와 같은 일부 git 공급자 또는 일부 회사 환경에서는 불가능할 수 있습니다. 리모컨에 ssh 액세스 권한을 부여하지 않는 공급자와 호스팅하는 경우 그대로 두십시오. 공급자의 인프라가 참조되지 않은 커밋을 달콤한 시간에 정리할 수 있습니다. 회사 환경에있는 경우 IT 담당자에게 일주일에 한 번 정도 리모컨을 수집하는 크론 작업 가비지를 실행하도록 조언 할 수 있습니다. 동료에게 항상을 git clone -b master --single-branch <url>대신 하여 조언하는 한, 대역폭과 스토리지 측면에서 팀에 영향을 미치지 않을지 여부는 상관 없습니다 git clone.
  5. 오래된 고아 태그를 제거하려는 모든 동료는 2-3 단계 만 적용하면됩니다.
  6. 그런 다음 이진 파일 추가의 1-8 단계를 반복하여 새 고아 태그를 만들 수 있습니다 2.0.0bin. 동료가 타이핑하는 git fetch <remote> --tags것이 걱정된다면 실제로 이름을 다시 지정할 수 있습니다 1.0.0bin. 이렇게하면 다음에 모든 태그를 가져올 때 이전 태그를 1.0.0bin참조하지 않고 후속 가비지 수집을 위해 표시합니다 (3 단계 사용). 리모컨에서 태그를 덮어 쓰려고 할 때 다음 -f과 같이 사용해야 합니다.git push -f <remote> <tagname>

  • OTABS는 마스터 나 다른 소스 코드 / 개발 브랜치를 건드리지 않습니다. 커밋 해시, 모든 히스토리 및 이러한 분기의 작은 크기에는 영향을 미치지 않습니다. 바이너리 코드로 소스 코드 기록을 이미 확장 한 경우 별도의 작업으로 정리해야합니다. 이 스크립트 는 유용 할 수 있습니다.

  • git-bash를 사용하여 Windows에서 작동하도록 확인했습니다.

  • 이진 파일을보다 효율적으로 저장하려면 표준 tric 세트 를 적용하는 것이 좋습니다 . git gc추가 인수없이 자주 실행 하면 이진 델타를 사용하여 git이 파일의 기본 저장소를 최적화합니다. 그러나 파일이 커밋에서 커밋과 비슷하게 유지되지 않을 경우 이진 델타를 완전히 끌 수 있습니다. 또한 .zip, .jpg 또는 .crypt와 같이 이미 압축 또는 암호화 된 파일을 압축하는 것은 의미가 없으므로 git를 사용하면 기본 저장소의 압축을 해제 할 수 있습니다. 불행히도 그것은 소스 코드에도 영향을 미치는 전부 또는 아무것도 아닌 설정입니다.

  • 보다 빠른 사용을 위해 OTABS의 일부를 스크립팅 할 수 있습니다. 특히, 바이너리 파일updategit hook 으로 완전히 삭제하는 2-3 단계 스크립팅 은 git fetch ( "오래된 모든 것을 가져오고 삭제")에 강력하지만 위험한 의미를 부여 할 수 있습니다.

  • 이진 파일 완전 삭제의 4 단계를 건너 뛰어 중앙 저장소 팽창 비용으로 원격의 모든 이진 변경 내역을 모두 유지할 수 있습니다. 로컬 리포지토리는 시간이 지남에 따라 마른 상태로 유지됩니다.

  • Java 세계에서는이 솔루션을 결합 maven --offline하여 버전 제어에 완전히 저장된 재현 가능한 오프라인 빌드를 만들 수 있습니다 (그라들보다 maven을 사용하는 것이 더 쉽습니다). Golang 세계에서는이 솔루션을 기반으로 대신 GOPATH를 관리 할 수 ​​있습니다 go get. 파이썬 세계에서 이것을 virtualenv와 결합하여 처음부터 모든 빌드에 대해 PyPi 서버에 의존하지 않고 자체 개발 환경을 만들 수 있습니다.

  • 바이너리 파일이 빌드 유물처럼, 매우 자주 변경하는 경우, 그것은 솔루션 고아 태그에 저장 유물의 5 최신 버전을 스크립트에 좋은 생각이 될 수도 monday_bin, tuesday_bin..., friday_bin각 릴리스에 대한, 또한 고아 태그 1.7.8bin 2.0.0bin등을 weekday_bin매일 회전하고 오래된 바이너리를 삭제할 수 있습니다 . 이렇게하면 두 가지 이점을 모두 얻을 수 있습니다. 소스 코드 의 전체 기록은 유지 하지만 바이너리 종속성 의 관련 기록 만 유지합니다 . 모든 히스토리를 가진 전체 소스 코드를 얻지 않고도 주어진 태그에 대한 이진 파일을 얻는 것이 매우 쉽습니다 git init && git remote add <name> <url> && git fetch <name> <tag>.


"정기적으로 사용해야합니다 git gc"— 바로 거기에서 읽기를 중단했습니다. 누군가 왜 해킹을 위해 마지막 안전 벨트를 포기했을까요?
user1643723

@ user1643723 git gc은 (는) 실행하기에 안전하지 않습니다. 모든 매달린 커밋은 기본적으로 최소 30 일 동안 하드 드라이브에 안전하게 보관됩니다. git-scm.com/docs/git-gc
Adam Kurkiewicz

자세한 내용을 작성해 주셔서 감사합니다. 누군가가 저장소를 복제 할 때 기본적으로 다운로드되지 않지만 수동으로 다운로드하여 로컬 저장소를 업데이트 할 수있는 방식으로 GitHub 저장소에 일부 바이너리 종속성을 저장하는 방법으로 이것을 시도하고 싶었습니다. 그러나이 단계에서 오류가 발생했습니다 : git push <remote> 1.0.0bin- remote: error: GH001: Large files detected. You may want to try Git Large File Storage. 아마도 GitHub가 더 이상 이것을 지원하지 않는 것 같습니다. 해당 바이너리의 크기는 100MB입니다.
user5359531

1
솔직히 말해서, 작업에 github을 사용할 수 있다면 LFS를 사용하지 못하게하는 것은 무엇입니까? github의 직원들은이 제품을 만들기 위해 열심히 노력했으며 심지어 제품을 호스팅하고 있으며 인프라를 사용하여 최적화되었습니다. 이 해킹은 실제로 LFS 또는 다른 타사를 사용할 수없고 순수한 git 솔루션을 사용하는 상황을위한 것입니다.
Adam Kurkiewicz

또한이 솔루션이 실제로 얼마나 해키 지에 대해 더 명확하게 답변을 업데이트했습니다.
Adam Kurkiewicz

13

제 생각에는, 당신은 종종 그 큰 파일을 수정할 가능성이있어, 또는 당신은 많은을하려는 경우 경우 git clone또는 git checkout, 당신은 심각하게 (해당 파일 액세스 아니면 다른 방법) 다른 Git 저장소를 사용하는 것이 좋습니다.

그러나 우리처럼 작업하고 바이너리 파일을 자주 수정하지 않으면 첫 번째 복제 / 체크 아웃이 오래 걸리지 만 그 후에는 원하는만큼 빨라야합니다 (사용자가 첫 번째 복제 된 저장소를 계속 사용한다는 것을 고려하면 했다).


13
또한 두 repos를 모두 체크 아웃해야하기 때문에 별도의 repos가 체크 아웃 시간을 단축시키지 않습니다!
Emil Sit

@EmilSit 별도의 저장소는 "이진 저장소"의 기록을 꾸준히 정리하면 체크 아웃이 훨씬 짧아 질 수 있습니다. 또한 개발자는 매번 두 저장소를 모두 체크 아웃하지 않아도 됩니다 .
FabienAndre

메인 모듈의 빌드 스크립트가 두 번째 저장소에서 이진 파일을 가져 와서 하나씩 추출합니다 (예 : stackoverflow.com/questions/1125476/… ).
akauppi

1
이진 파일이 자주 변경되지 않더라도 공동 작업을 위해 분기를 리포지토리로 자주 밀어 넣으면 큰 파일로 인해 워크 플로가 중단 될 수 있습니다.
Timo Reimann

9

SVN은 Git보다 이진 델타를보다 효율적으로 처리하는 것으로 보입니다.

문서화를위한 버전 관리 시스템 (JPEG 파일, PDF 파일 및 .odt 파일)을 결정해야했습니다. 방금 JPEG 파일을 추가하고 90도 4 번 회전하여 이진 델타의 효과를 확인했습니다. Git의 저장소는 400 % 성장했습니다. SVN의 저장소는 11 % 만 증가했습니다.

따라서 SVN이 이진 파일에서 훨씬 더 효율적인 것처럼 보입니다.

소스 코드는 Git이고 문서와 같은 이진 파일은 SVN입니다.


33
이 4 개의 파일을 추가 한 후 "git gc"(재 포장 및 가비지 수집)를 실행해야했습니다. Git은 추가 된 모든 컨텐츠를 즉시 압축하지 않으므로, 파일 그룹 압축 (크기 측면에서 더 효율적)이 있으며 추가 된 모든 단일 오브젝트를 개별적으로 압축하는 속도가 저하되지 않습니다. 그러나 "git gc"가 없어도 git은 결국 압축되어 압축되지 않은 개체가 충분히 축적되었음을 알게됩니다.
nightingale

24
@jpierson 빈 git 저장소를 만들고 크기가 41MB 인 완전히 흰색 bmp 이미지를 추가하고 커밋 한 결과 크기가 328KB 인 전체 자식 저장소가 생성되었습니다. 후 git gc총 자식 저장소 크기 184킬로바이트으로 감소시켰다. 그런 다음 단일 픽셀을 흰색에서 검은 색으로 변경 하고이 변경 사항을 커밋하고 총 자식 저장소 크기가 388KB로 증가했으며 총 자식 저장소 크기 git gc가 184KB로 감소했습니다. 이것은 git이 이진 파일의 델타를 압축하고 찾는 데 매우 우수하다는 것을 보여줍니다.
Tader

6
@jpierson A 참고 : 방금 이진 델타에 대해 언급했습니다. Git은 큰 (GB 크기) 파일이있는 저장소를 관리하는 경우 모든 메모리를 소비하고 스왑합니다. 이를 위해 git-annex (이미 다른 답변에서 언급)를 사용하십시오.
Tader

12
@ JanDvorak-아무도 진실을 언급하지 않았기 때문에 아무도 언급하지 않았습니다. Subversion 사본은 페이지 중간에 대해 저렴합니다 ( svnbook.red-bean.com/en/1.7/svn.branchmerge.using.html) .
Joris Timmermans

12
@ 테이 더 : 당신의 테스트는 나쁘다. 바이너리 파일이라고 부르는 것은 실제로 텍스트 파일과 비슷합니다 (비트 관점에서) – 비트 스트림은 바이트로 정렬되며 의미 있고 현지화 된 차이점이 있습니다. 결국, 하나의 픽셀을 변경하는 것은 기본적으로 텍스트 파일에서 하나의 문자를 변경하는 것과 같습니다 (그리고 오늘날 압축되지 않은 비트 맵을 사용하는 사람은 누구입니까?) 작은 비디오, 압축 이미지, 가상 머신, zip 파일 또는 다른 것을 사용하여 동일한 실험을 시도하십시오. 그 자식은 델타를 효율적으로 처리하지 못합니다. 실제로 압축 불가능한 데이터로는 기본적으로 불가능합니다.
Eamon Nerbonne

4

git clone --filter Git 2.19 + 얕은 클론에서

이 새로운 옵션은 결국, 경우 힘내 및 GitHub의 DEVS 바이너리 파일 문제에 대한 최종 솔루션이되어 만들 수도 있습니다 (그들은 틀림없이 그것은 사용자 친화적 인만큼 아직 서브 모듈 달성하지 않은 예를 들어).

실제로 서버에 원하는 파일과 디렉토리 만 가져올 수 있으며 원격 프로토콜 확장과 함께 도입되었습니다.

이를 통해 먼저 얕은 복제를 수행 한 다음 각 빌드 유형에 대해 빌드 시스템으로 가져올 Blob을 자동화 할 수 있습니다.

--filter=blob:limit<size>가져 오기 위해 최대 얼룩 크기를 제한 할 수 있는 이미 있습니다.

이 기능이 어떻게 보이는지에 대한 최소한의 자세한 예를 제공했습니다. Git 저장소의 하위 디렉토리 만 어떻게 복제합니까?


2

내 소스 코드 (웹 응용 프로그램)가 의존하는 큰 이진 파일을 처리하는 방법에 대한 의견을 찾고 있습니다. 이것에 관한 당신의 경험 / 생각은 무엇입니까?

나는 개인적으로 실행 한 힘내와 동기화 실패 내 웹 응용 프로그램 바이너리 데이터는 노치 일단 내 클라우드 호스트의 일부와 3 기가 바이트 표시 위로 . 당시 BFT Repo Cleaner 를 고려 했지만 해킹처럼 느껴졌습니다. 그 이후로 파일 관리, 버전 관리 및 백업을 위해 Amazon S3와 같은 전용 도구 를 활용하는 대신 파일을 Git 외부에 보관하기 시작했습니다 .

누구든지 여러 Git 리포지토리에 대한 경험이 있고 하나의 프로젝트에서 관리합니까?

예. 휴고 테마 는 주로이 방법으로 관리됩니다. 조금 멍청하지만 작업이 완료됩니다.


내 제안은 작업에 적합한 도구선택하는 것 입니다. 회사를 위해 있고 GitHub에서 코드 라인을 관리하는 경우 돈을 지불하고 Git-LFS를 사용하십시오. 그렇지 않으면 blockchain을 사용하여 분산되고 암호화 된 파일 저장소 와 같은보다 창의적인 옵션을 탐색 할 수 있습니다 .

고려해야 할 추가 옵션으로는 Minios3cmd가 있습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.