문제

내 소스 코드(웹 애플리케이션)가 의존하는 대용량 바이너리 파일을 처리하는 방법에 대한 의견을 찾고 있습니다.우리는 현재 몇 가지 대안을 논의하고 있습니다:

  1. 바이너리 파일을 직접 복사하세요.
    • 찬성:확실하지 않다.
    • 대조:나는 이에 강력하게 반대합니다. 새 사이트를 설정하거나 기존 사이트를 마이그레이션할 때 오류가 발생할 가능성이 높아지기 때문입니다.또 다른 장애물을 만듭니다.
  2. 모두 관리하세요 힘내.
    • 찬성:중요한 파일을 복사하는 것을 '깜빡'할 가능성을 제거합니다.
    • 대조:저장소를 비대하게 만들고 코드 베이스와 체크아웃, 복제 등을 관리하는 유연성을 감소시킵니다.꽤 시간이 걸릴 겁니다.
  3. 별도의 저장소.
    • 찬성:소스 코드 체크아웃/복제 작업은 그 어느 때보다 빠르며, 이미지는 자체 저장소에 적절하게 보관됩니다.
    • 대조:가지고 있는 단순함을 제거합니다. 유일 프로젝트의 Git 저장소.그것은 확실히 내가 생각하지 못한 다른 것들을 소개합니다.

이에 대한 귀하의 경험/생각은 무엇입니까?

또한:여러 Git 저장소를 사용하고 하나의 프로젝트에서 관리해 본 경험이 있는 사람이 있나요?

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

도움이 되었습니까?

해결책

파일이 없으면 프로그램이 작동하지 않는다면 파일을 별도의 저장소로 분할하는 것은 좋지 않은 생각인 것 같습니다.우리는 별도의 저장소로 나누는 대규모 테스트 모음을 가지고 있지만 이는 실제로 "보조" 파일입니다.

그러나 별도의 저장소에서 파일을 관리한 다음 사용할 수 있습니다. git-submodule 올바른 방식으로 프로젝트에 끌어들이세요.따라서 모든 소스의 전체 기록은 여전히 ​​유지되지만 내가 이해하는 바에 따르면 이미지 하위 모듈의 관련 개정판은 하나만 갖게 됩니다.그만큼 git-submodule 이 기능은 올바른 이미지 버전에 맞춰 올바른 코드 버전을 유지하는 데 도움이 됩니다.

여기에 좋은 것이 있습니다 서브모듈 소개 Git Book에서.

다른 팁

나는 발견했다 git-annex 최근에 나는 굉장하다. 대형 파일을 효율적으로 관리하도록 설계되었습니다. 사진/음악 (등) 컬렉션에 사용합니다. git-annex의 개발은 매우 활발합니다. 파일의 내용은 git 저장소에서 제거 될 수 있으며, 트리 계층 만 GIT (Symlinks를 통해)에 의해 추적됩니다. 그러나 파일의 내용을 얻으려면 당기기/푸시 후 두 번째 단계가 필요합니다.

$ 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

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

2015 년 4 월 이후의 또 다른 해결책은입니다 git 대형 파일 스토리지 (LFS) (Github에 의해).

사용합니다 git-lfs (보다 git-lfs.github.com) 및이를 지원하는 서버로 테스트 : LFS 테스트 서버:
메타 데이터는 git repo에만 저장할 수 있으며 다른 곳에서는 큰 파일을 저장할 수 있습니다.

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

살펴보십시오 git bup 이것은 큰 바이너리를 git 저장소에 현명하게 저장하기위한 git 확장입니다.

당신은 그것을 하위 모듈로 갖고 싶지만 저장소가 다루기가 어려워지는 것에 대해 걱정할 필요는 없습니다. 샘플 사용 사례 중 하나는 VM 이미지를 GIT에 저장하는 것입니다.

나는 실제로 더 나은 압축 속도를 보지 못했지만 저장소에는 실제로 큰 바이너리가 없습니다.

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

당신은 또한 사용할 수 있습니다 git-fat. 나는 단지 스톡 파이썬에 달려 있고 rsync. 또한 다음과 같은 자체 설명 명령과 함께 일반적인 GIT 워크 플로를 지원합니다.

git fat init
git fat push
git fat pull

또한 .gitfat 파일을 저장소에 체크인하고 .gitattributes를 수정하여 원하는 파일 확장자를 지정해야합니다. git fat 관리합니다.

정상을 사용하여 이진을 추가합니다 git add, 이는 차례로 호출합니다 git fat Gitattributes 규칙을 기반으로합니다.

마지막으로, 바이너리가 실제로 저장되는 위치가 저장소에서 공유 될 수 있고 사용자를 지원할 수 있다는 이점이 있습니다. rsync 하다.

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

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

나는 몇 달 전에 매우 비슷한 문제를 겪었습니다. ~ 21GB의 MP3 파일, 분류되지 않은 (나쁜 이름, 나쁜 ID3, 내가 그 MP3 파일을 좋아하는지 알지 못하는지 모르겠다). 3 개의 컴퓨터에서 복제되었습니다.

메인 git 저장소와 함께 외부 하드 디스크 드라이브를 사용했고 각 컴퓨터로 복제했습니다. 그런 다음 습관적인 방식으로 분류하기 시작했습니다 (밀기, 당기기, 병합 ... 삭제 및 이름을 여러 번 삭제).

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

그런 다음 오래된 브랜치를 삭제하고 새 지점 만 유지하고 Ref-Logs를 삭제하고 "Git Prune"을 실행했습니다. 그 후, 내 .git 폴더는 ~ 6GB 만 ...

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

제 생각에는 큰 파일을 자주 수정하거나 많은 git clone 또는 git checkout, 그런 다음 다른 GIT 저장소 (또는 해당 파일에 액세스하는 다른 방법)를 진지하게 사용하는 것을 진지하게 고려해야합니다.

그러나 우리가하는 것처럼 작업하고 바이너리 파일이 자주 수정되지 않으면 첫 번째 클론/체크 아웃이 길지만 원하는만큼 빠르야합니다 (사용자가 첫 번째 복제 된 저장소를 계속 사용하는 것을 고려하면됩니다. 가졌다).

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

TL; DR 12-01-2017 Github의 LFS 또는 다른 타사를 사용할 수 있다면 반드시해야합니다. 할 수 없다면 계속 읽으십시오. 이 솔루션은 해킹이며 그렇게 취급해야합니다.

OTAB의 바람직한 특성

  • 이것은 순수한 git 그리고 git 만 솔루션-제 3 자 소프트웨어 (git-annex) 또는 제 3 자 인프라 (Github의 LFS)없이 작업을 수행합니다.
  • 이진 파일을 저장합니다 효율적으로, 즉, 그것은 당신의 저장소의 역사를 팽창시키지 않습니다.
  • git pull 그리고 git fetch, 포함 git fetch --all 아직도 대역폭 효율적입니다, 즉, 모든 큰 바이너리가 기본적으로 리모컨에서 가져 오는 것은 아닙니다.
  • 작동합니다 .
  • 그것은 모든 것을 a에 저장합니다 단일 git 저장소.
  • 그것은 허용합니다 삭제 구식 바이너리 (BUP와 달리).

OTAB의 바람직하지 않은 특성

  • 그것은 만든다 git clone 잠재적으로 비효율적입니다 (그러나 반드시 사용량에 따라는 아닙니다). 이 솔루션을 배포하면 동료에게 사용하도록 조언해야 할 수도 있습니다. git clone -b master --single-branch <url> 대신에 git clone. 기본적으로 git 클론이 문자 그대로 클론하기 때문입니다 전체 평소와 같이 대역폭을 낭비하고 싶지 않은 것들을 포함하여 저장소. 가져 왔습니다 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. vertybigbinary.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. 내가 (또는 내 동료)는 어떻게 BERCYBIGBINAR.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. 가져 왔습니다 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 "$@". 또한 다른 모든 참조되지 않은 커밋을 삭제합니다. 가져 왔습니다 그래서 1904860
  4. 가능하면 리모컨에서 Git GC 트릭을 반복하십시오. 저장소를 자체 주최하고 Github와 같은 일부 GIT 제공 업체에서는 불가능할 수 있습니다. 리모컨에 대한 SSH 액세스를 제공하지 않는 공급자와 함께 호스팅하는 경우 그냥 놔두십시오. 귀하의 공급자의 인프라가 자신의 달콤한 시간에 귀하의 참조되지 않은 커밋을 청소할 수 있습니다. 기업 환경에 있다면 주당 한 번 정도 리모컨을 수집하는 Cron 작업장을 운영하도록 조언 할 수 있습니다. 동료에게 항상 조언하는 한, 대역폭 및 스토리지 측면에서 팀에 영향을 미치지 않는지 여부 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는 마스터 또는 기타 소스 코드/개발 지점을 만지지 않습니다. 커밋 해시, 모든 역사 및 작은 크기 의이 가지는 영향을받지 않습니다. 이진 파일로 소스 코드 기록을 이미 부풀린 경우 별도의 작업으로 정리해야합니다. 이 스크립트 유용 할 수 있습니다.

  • gitbash와 함께 Windows에서 작동하는 것으로 확인되었습니다.

  • a를 적용하는 것이 좋습니다 표준 트릭 세트 이진 파일의 저장을보다 효율적으로 만들기 위해. 빈번한 달리기 git gc (추가 인수없이) GIT는 이진 델타를 사용하여 파일의 기본 저장을 최적화합니다. 그러나 파일이 Commit To Commit에서 비슷한 상태를 유지하지 않을 경우 Binary Deltas를 모두 끄십시오. 또한 .zip, .jpg 또는 .crypt와 같이 이미 압축되거나 암호화 된 파일을 압축하는 것은 의미가 없기 때문에 Git을 사용하면 기본 스토리지의 압축을 끄는 것이 가능합니다. 불행히도 소스 코드에도 영향을 미치는 모든 설정입니다.

  • 더 빠른 사용을 허용하기 위해 OTAB의 일부를 스크립팅 할 수 있습니다. 특히, 스크립팅 단계 2-3 이진 파일을 완전히 삭제합니다update Git Hook는 Git Fetch에 매력적이지만 위험한 의미를 제공 할 수 있습니다 ( "오래된 모든 것을 가져 와서 삭제하십시오").

  • 4 단계를 건너 뛰고 싶을 수도 있습니다 이진 파일을 완전히 삭제합니다 중앙 저장소 팽창 비용으로 리모컨의 모든 이진 변경의 전체 이력을 유지합니다. 현지 리포지토리는 시간이 지남에 따라 유지됩니다.

  • Java World에서는이 솔루션을 다음과 결합 할 수 있습니다. maven --offline 버전 제어에 전적으로 저장된 재현 가능한 오프라인 빌드를 만들려면 (Gradle보다 Maven을 사용하는 경우). Golang World에서는이 솔루션을 구축하여 대신 Gopath를 관리하는 것이 가능합니다. go get. Python World에서는 이것을 VirtualEnV와 결합하여 모든 빌드마다 처음부터 PYPI 서버에 의존하지 않고 자체 포함 된 개발 환경을 생성 할 수 있습니다.

  • 바이너리 파일이 빌드 아티팩트와 같이 자주 변경되면 가장 최근 버전의 아티팩트를 Orphan 태그에 저장하는 솔루션을 스크립팅하는 것이 좋습니다. 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> 당신을 위해 그것을해야합니다.

SVN은 바이너리 델타를 git보다 더 효율적으로 처리하는 것으로 보입니다.

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

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

따라서 내 선택은 소스 코드의 GIT 및 Documentation과 같은 이진 파일의 경우 SVN입니다.

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

이 새로운 옵션은 GIT와 Github가 Devs를 사용하고 사용자에게 충분히 친숙하게 만드는 경우 이진 파일 문제에 대한 최종 솔루션이 될 수 있습니다. 하위 모듈에 대해서는 여전히 달성하지 못했습니다 예를 들어).

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

이를 통해 먼저 얕은 클론을 수행 한 다음 각 유형의 빌드에 대한 빌드 시스템으로 가져 오는 블로브를 자동화 할 수 있습니다.

이미 A가 있습니다 --filter=blob:limit<size> 이를 통해 최대 블로브 크기를 제한 할 수 있습니다.

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

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

나는 개인적으로 달려 갔다 git과 동기화 실패 내 웹 애플리케이션 바이너리 데이터가 노칭 한 후 일부 클라우드 호스트로 3GB 이상. 나는 고려했다 BFT 리포 클리너 당시에는 해킹처럼 느껴졌습니다. 그 이후로 나는 git purview 외부에 파일을 보관하기 시작했습니다. 목적으로 지어진 도구 파일 관리, 버전 관리 및 백업을위한 Amazon S3와 같은.

여러 Git 리포지토리에 대한 경험이 있고 하나의 프로젝트에서 관리하는 사람이 있습니까?

예. 휴고 테마 주로 이런 식으로 관리됩니다. 조금 어리석지 만 작업이 끝납니다.


내 제안은 작업에 적합한 도구를 선택하십시오. 회사를위한 것이고 Github에서 코드 라인을 관리하는 경우 돈을 지불하고 GIT-LFS를 사용합니다. 그렇지 않으면 분산, 암호화와 같은보다 창의적인 옵션을 탐색 할 수 있습니다. 블록 체인을 사용한 파일 스토리지.

고려해야 할 추가 옵션은 포함됩니다 미니오 그리고 S3CMD.

살펴보십시오 Camlistore. 그것은 실제로 git 기반이 아니지만, 당신이해야 할 일에 더 적합하다고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top