저장소와 히스토리

저장소 유지 보수

git은 저장소가 얼마나 비싼지 절대 알려주지 않아요. 객체 데이터베이스가 어떤 상태든 계속 동작하기 때문에, 문제의 첫 신호는 대개 기어가는 클론이거나 디스크가 바닥난 노트북이에요 — 명령 하나면 해결됐을 시점을 한참 지나서 말이죠.

이 패널은 빠져 있던 계기판이에요. 공간이 어디로 갔는지, 그중 얼마를 되찾을 수 있는지, 그리고 각 작업이 실행되기 전에 무엇을 하는지 보여줘요.

⌘K → 저장소 유지 보수.

팩된 객체, 루스 객체, 도달 불가 객체로 나뉜 디스크 사용량과 그 아래의 유지 보수 작업들

숫자 읽기

모든 값은 git count-objects -v와 실제 도달성 탐색에서 나와요 — 추정치는 하나도 없어요.

항목 무엇인가 왜 늘어나는가
팩됨 팩파일 안에 압축되고 델타화되어 들어 있는 객체 이것이 건강한 상태예요
루스 객체당 파일 하나, 압축은 거의 되지 않음 커밋마다, 페치마다 이것이 쓰여요
도달 불가 이제 아무것도 가리키지 않는 객체 버려진 커밋, 수정된 메시지, 포기한 리베이스

루스 옆의 개수 — "n개 객체, 그중 m개는 이미 팩됨" — 이 눈여겨볼 값이에요. 그 m개는 두 번 저장되어 있어요. 한 번은 루스로, 한 번은 팩 안에. 순수한 중복이고, 이것을 접어 없애는 것이 git gc예요.

도달 불가는 아직 쓰레기가 아니에요. 그 객체들이야말로 리셋해서 날린 커밋을 git reflog가 되살려 주는 근거예요. git은 일부러 2주 동안 그것들을 보관해요.

작업들

버튼 실행하는 것 비용
최적화 git gc 수 초에서 1분. 거의 언제나 정답이에요
처음부터 다시 팩 git gc --aggressive 큰 저장소에서는 수 분. 모든 델타를 다시 계산해요
커밋 그래프 재생성 git commit-graph write --reachable 빨라요. 로그와 그래프 탐색이 눈에 띄게 빨라져요
무결성 검사 git fsck --dangling 큰 저장소에서는 느리고, 아무것도 바꾸지 않아요
도달 불가 객체 지금 버리기 git gc --prune=now reflog의 안전망을 파괴해요

손이 가야 할 것은 최적화예요. 루스 객체를 팩으로 묶고, 2주 넘게 도달 불가 상태였던 것을 버리며, 최근 히스토리는 복구 가능한 상태로 남겨 둬요.

처음부터 다시 팩은 과대평가되어 있어요. 기존 델타를 전부 버리고 아무것도 없는 상태에서 다시 계산하는데, 수 분이 걸리고 보통은 평범한 gc보다 몇 퍼센트 아끼는 데 그쳐요. 거대한 히스토리를 가져온 뒤 한 번쯤은 해볼 만하지만, 일상적으로 할 일은 아니에요.

도달 불가 객체 지금 버리기는 먼저 묻고, 확인 문구가 객체 몇 개와 공간 얼마인지 알려줘요. 실행한 뒤에는 한 시간 전에 리셋해서 날린 커밋을 되찾을 수 없어요 — reflog 항목은 여전히 목록에 있을지 몰라도, 그 뒤의 객체는 사라졌어요.

무결성 검사

git fsck는 다른 객체가 참조하는 모든 객체가 실제로 존재하며 내부적으로 일관된지 확인해요.

  • 매달린(dangling) 객체는 정상이에요. 도달 불가 객체를 이름으로 나열한 것뿐이에요. 리베이스 뒤에 수백 개가 있는 저장소도 건강한 저장소예요.
  • 없는 객체는 손상이에요 — 잘려 쓰인 파일, 불량 디스크, 중단된 전송. 하나라도 나타나면 다시 팩하지 마세요. 손상된 데이터베이스를 다시 팩하면 복구 가능한 문제가 영구적인 문제로 바뀔 수 있어요. 원격에서 정상 사본을 클론하고, 푸시하지 않은 브랜치는 번들로 옮기세요.

백그라운드 유지 보수

체크박스는 저장소를 **git maintenance**에 등록해요. 운영체제가 돌리는 스케줄(launchd, systemd 또는 작업 스케줄러)에 따라 팩과 사전 페치를 수행하죠.

여기에는 Gitcito 고유의 것이 없어요. 같은 스케줄이 여러분의 터미널에도 적용되고, git maintenance unregister는 어디서든 이를 취소해요. 체크를 해제하면 정확히 그 일을 하며, 등록되어 있는 다른 저장소들을 위해 스케줄 자체는 남겨 둬요.

알아둘 만한 한계

  • 도달 불가 개수는 전체 도달성 탐색이 필요해요. 그래서 아주 큰 저장소에서 패널을 열면 잠시 시간이 걸려요. 그것이 추정이 아닌 정직한 숫자예요.
  • 크기는 디스크가 내어주는 양이지 내용의 길이가 아니에요. 400바이트짜리 루스 객체도 4 KB 블록 하나를 차지하고, 그래서 그런 객체 천 개가 메가바이트를 잡아먹으며 — 그래서 팩으로 묶을 가치가 있어요.
  • 워크트리나 서브모듈은 자기 .git을 가져요. 따라서 표시되는 크기는 이 저장소만의 것이에요.
  • 유지 보수는 히스토리를 줄이지 못해요. 400 MB짜리 블롭이 커밋 안에 있다면 그것은 도달 가능하고, gc는 그것을 영원히 지켜요 — 그건 히스토리에서 파일 제거하기이며, 훨씬 파괴적인 다른 작업이에요.
  • Gitcito는 몰래 gc를 돌리지 않아요. git 자체의 gc --auto는 늘 그랬듯 여전히 돌 수 있어요. 그것이 실패하면 .git/gc.log에 기록을 남기고, 이 패널이 그것을 드러내 줘요.

함께 보기: 히스토리에서 파일 제거 · 번들과 아카이브 · 복구

GitHub에서 이 번역 개선하기