어떻게 Git 저장소의 성능을 유지할까?

최준혁·2023년 3월 13일
0
post-thumbnail

최근에 Dockerizing 을 진행하면서 깃헙에 있는 레포지터리를 서비스별로 전부 분리시켰다. 하지만 기존에 컷밋한 깃로그들은 그대로 가져가야 했는데 레포의 사이즈가 매우 크다는 사실을 알게 되었다.
깃로딩의 속도를 개선하기 위해서 여러 블로그들을 살펴보았고 여기에 정리하고자 한다.

우선 Git은 DVCS(Distributed Version Control System) 으로, clone을 하면 사용자는 전체 history 를 로컬 저장소로 가지고 온다. 한편, Git 의 외부 저장소는 commit 이 발생함에 따라 object / pack / 등이 증가하고, 이를 gc 를 통해서 관리한다.
Git 저장소가 매우 빈번하게 업데이트 되는 경우, remote git 에 명령을 수행할 시 object를 찾고 서버에서의 명령 수행이 매우 느려진다. 따라서 remote git 저장소를 최적의 상태로 유지하거나, 이에 준하는 수준으로 관리해야 한다.

아래 링크를 통해 gc, gc — aggressive, repack 에 대한 이력과 특징을 이해할 수 있다.

https://stackoverflow.com/questions/28720151/git-gc-aggressive-vs-git-repack/

그리고 다음링크를 통해 repack 시 object, window, depth 에 대해서 알아볼 수 있다.

https://stackoverflow.com/questions/14842127/how-to-use-git-repack-a-d-depth-250-window-250

Remote Git에서 일어나는 일들

Git 서버를 운영하면, git 내부의 pack object는 최적화되지 않은 채로 끊임없이 늘어난다. 이럴 수 밖에 없는게, 원격 사용자는 끊임없이 push를 해서 새로운 delta를 만들기 때문이다. 여기서 서버 관리자는 git gc 를 통해 git 저장소를 최적화 해야 한다.

이에 대해서는 BitBucket에 잘 정리된 문서가 있다.

https://www.atlassian.com/git/tutorials/git-gc

하지만 우리가 단순히 git gc 를 수행하면, 이는 완전히 안정된 git을 보장하지 않는다. git gc는 prune, pack, repack, rerere 등을 동시에 수행한다.

Remote Git에서 해줘야 하는 일들

1. 분산되어 있는 pack을 한개로 합친다.

git repack --abdk --window=50 depth=5

window / depth 가 낮을수록 pack 및 object count가 빨라지고, 대신 오래된 history를 가져오는데 오래걸린다.
반대로 이 숫자가 높으면 이전 이력에 접근하기 쉬워지고, 대신 clone 속도는 떨어진다.

  • -a: 전체 분산된 팩을 한개로 합친다.
  • -d 와 같이 쓰이게 된다. 이렇게 되는 경우는 git fsck — full — dangling 과 동일한 역할을 한다.
  • -d: pack이 완료된 후 불필요한 pack들은 제거한다.
  • -b: bitmap index를 생성한다.
    만약 git 설정 내에 repack.writeBitmaps 옵션이 있다면 이걸 오버라이드한다.
    bitmap index를 통해 실제 원격 저장소에 더 쉽게 접근할 수 있게 된다.
  • -k: -ad를 하면 기본적으로 dangling git을 삭제하는데, 이걸 남기도록 한다.
  • window | depth
    이 플래그는 pack 내부의 delta에 접근하기 위한 방법과 압축을 결정한다. pack 이 생성될 때, 기본적으로 파일 종류 / 크기에 기반하고, 부가적으로 이름 그리고 다른 object를 참고한다.
    depth 는 몇개의 delta 이전까지 pack 을 할것인지 정한다. 즉, 위와 같이 depth=5가 되면 5번째 delta까지 pack의 외부에 배치하여 접근 속도를 개선한다.
    git에서 repack을 하면 기본적으로 — window=10, — depth=50 이 기본이다.

2. 한개로 합쳐진 팩을 자주 쓰이는 최신 commit에 대해서 unpack한다.

git repack -f -F

일단 위 명령이 실행되면 git 저장소는 이미 정리된 pack, 그리고 delta에 대한 bitmap까지 갖고 있으므로 효율적인 수준에서 repack을 수행하면 된다.

  • -f: git pack-objects 의 — no-reuse-delta 와 동일하다.
    기본적으로 repack → pack-objects 가 수행되면, 기존에 남아있는 delta를 참조하여 pack을 한다. 이 경우에
    repack 의 목적과는 다르게 최적화가 덜 될 수 있다. 그래서 delta를 사용하지 않고 처음부터 repack을 한다.
  • -F: git pack-objects 의 — no-reuse-object 와 동일하다.
    object로 만들어진 것들은 재사용하지 않는다. 심지어는 objects 외에 delta에 대해서도 재사용을 하지 않는다. 즉
    — no-reuse-delta 보다 더 강력하게 repack 을 수행하는 것이다.

Conclusion

  1. gc를 주기적으로 수행하자.
  2. gc가 잘 수행 안되는 저장소에서는 가끔 다음 명령으로 수행하자.
git repack -abdk — window=? — depth=?
git repack -fF
profile
HUGE FAN OF Freecodecamp, nomadcoder 까먹을까봐, 즐겨찾기에 넣어둔 블로그가 사라질까봐

0개의 댓글