GIT가 파일 델타를 저장하지 않는다는 사실에도 불구하고 여전히 이전 파일 버전으로 롤백 할 수 있습니까 (무제한 시간?)


14

Git이 파일 델타를 저장하지 않는다는 것을 읽었습니다 . 이것이 사실이라면, 이전 버전으로 파일 롤백을 어떻게 지원합니까? 전체 파일을 저장하는 경우 디스크의 저장소 공간이 관리 할 수 ​​없을 정도로 커야합니다. Git은 파일 롤백 및 diff를 파일 버전 1로 다시 지원합니까? 파일과 관련된 버전 관리 개념을 지원합니까? 이것은 VCS / DVCS와 나의 요구를 이해하는 데 필수적입니다. 이전 버전과 체크인하려는 내용을 비교할 수 있어야합니다.

답변:


44

Git은 자체적으로 정보버리지 않습니다 *. 모든 파일의 모든 이전 버전은 되돌리기, 차이, 검사 등에 항상 사용할 수 있습니다.

전체 트리 및 개별 파일

조정하려고 시도하는 것은 Git의 히스토리 모델이 전체 트리에 집중되어 있다는 사실과 개별 파일의 이전 버전에 액세스한다는 아이디어입니다. 전체 트리 버전 관리는 foo.c10 개의 foo.c변경 이전에 존재했던 버전 과 10 개의 전체 트리 변경 이전에 존재했던 버전을 보려면 약간의 작업이 더 필요합니다 .

# 10 foo.c-changes ago
git show $(git rev-list -n 10 --reverse HEAD -- foo.c | head -1):foo.c

# 10 whole-tree-changes ago
git show HEAD~10:foo.c

트리 방향의 이점, 주로 커밋을 전체 트리의 여러 부분에 대한 상호 의존적 변경 단위로 볼 수있는 기능은 일반적으로 여분의 타이핑 (별칭, 스크립트 등으로 완화 할 수 있음) 및 CPU 시간보다 훨씬 큽니다. 과거 커밋을 파헤쳐 보냈습니다.

저장 효율성

새로운 객체 (예 : 이전에 보이지 않은 내용을 가진 파일)가 시스템에 들어가면 일반 (zlib) 압축으로“느슨한 객체”로 저장됩니다. gc.auto구성 옵션 에 따라 충분한 느슨한 객체가 누적 되거나 사용자가 git gc 또는 하위 레벨 패킹 명령 중 하나를 실행할 때 Git은 많은 느슨한 객체를 단일 "팩 파일"로 수집합니다.

팩 파일의 객체는 일반 압축 데이터 (느슨한 객체와 동일, 다른 객체와 번들로 제공) 또는 다른 객체에 대한 압축 델타로 저장 될 수 있습니다. 델타는 구성 가능한 깊이 ( pack.depth)에 함께 연결될 수 있으며 적절한 객체에 대해 만들어 질 수 있습니다 ( pack.windowGit이 최고의 델타베이스를 얼마나 광범위하게 검색하는지 제어합니다. 좋은 델타 압축). 깊이 및 창 크기 구성이 델타 압축 엔진에 제공하는 위도는 종종 CVS 스타일의 간단한 1- 버전 대 다음 / 이전 버전 "diff"압축보다 델타 압축이 더 우수합니다.

Git 리포지토리 (전체 히스토리 및 압축되지 않은 작업 트리가있는)가 단일 SVN 체크 아웃 (압축되지 않은 작업 트리 및 깨끗한 사본 사용)보다 공간을 덜 차지하게하는 것은이 공격적인 델타 압축 (일반 zlib 압축과 결합)입니다.

Git 커뮤니티 북의 Git 객체를 저장 하는 방법Packfile 섹션을 참조하십시오 . 또한 자식 팩 - 객체 .

* Git에게 커밋을“기록을 다시 작성”하고 git reset 과 같은 명령 을 사용하여 커밋을 폐기 할 수는 있지만, 이러한 경우에도 Git은 새로 폐기 된 커밋을 필요로하는 경우를 대비하여 잠시 동안 중단됩니다. git refloggit prune을 참조하십시오 .


3
제공 한 정보의 양과 세부 정보에 대해서만 +1
타마라 Wijsman

3
또한 Git은 델타가 아닌 파일의 스냅 샷을 사용하기 때문에 역사상 먼 길을 되돌아가는 것이 실제로 더 쉽습니다. 20 개의 커밋에서 파일을보아야한다고 상상해보십시오. 델타를 사용하면 20 개의 변경 세트를 실행 취소해야합니다. 스냅 샷을 사용하면 올바른 스냅 샷을 얻을 수 있습니다. 역사가 길수록 유리합니다. 그리고 현재 버전과 그 버전 사이의 차이점을보고 싶다면 수행 된 작업, 실행 취소, 다시 실행 등을 결정하지 않고 단지 하나의 차이점 일뿐입니다.
Nathan Long

크리스, Git 내부를 잘 다루는 것 같습니다. 이 기회에 기회가 있습니까? stackoverflow.com/questions/5176225/…
Nathan Long

@ChrisJohnsen 이해해주세요. 당신이 말한 것을 기반으로, Git은 Subversion과 비슷한 스토리지 효율성을 얻을 수 있습니까? 작은 변화로 파일을 커밋하면 1GB의 데이터를 100MB로 저장할 수 있습니다. 힘내도 똑같이 할 수 있습니까?
Alireza Noori

@AlirezaNoori : 데이터의 특성과 캡처 된 변경 사항 (파일 크기, 파일 압축성, 변경 크기 및 위치 등)에 따라 다릅니다. 그와 같은 것이 분명히 가능해야합니다 (세부 사항에 따라 다름). 일반적으로, Git의 팩 파일은 SVN 서버가 사용하는 엄격하게 역 시간적 델타와 비교할 때 델타 압축을 위해 더 많은베이스를 선택할 수 있습니다. 구체적인 질문이있는 경우 모든 관련 세부 정보가 포함 된 새로운 질문을 고려해야합니다.
Chris Johnsen 2013

1

같은 페이지에서 읽을 수 있습니다 :

...

따라서 Git은 소스 코드 트리 아래의 어떤 수준에서도 파일 개정 관계를 명시 적으로 기록하지 않습니다.

...

전체 프로젝트보다 단일 파일의 변경 기록을 검사하는 것이 약간 더 비쌉니다. 주어진 파일에 영향을주는 변경 히스토리를 얻으려면 Git이 글로벌 히스토리를 따라 간 다음 각 변경 사항이 해당 파일을 수정했는지 판별해야합니다. 그러나 히스토리를 검사하는이 방법은 Git이 임의의 파일 세트에 대한 변경 사항을 보여주는 단일 히스토리를 동일한 효율로 생성하도록합니다. 예를 들어, 소스 트리의 하위 디렉토리와 관련 전역 헤더 파일이 매우 일반적인 경우입니다.

...

따라서 이전 버전의 파일로 돌아가서 두 파일을 비교할 수 있습니다.


1

git은 실제로 델타 파일을 저장하지만 전체 파일 트리의 델타로 저장합니다.

버전 간 차이점을 보려면 다음 중 하나를 수행하십시오.

  1. git diff- 마지막으로 체크인 한 버전과 변경되었지만 아직 git add실행 되지 않은 파일의 차이점을 보여줍니다 .
  2. git diff --cached- 이전 버전과 git add실행되었지만 커밋되지 않은 모든 파일의 차이점을 보여줍니다.
  3. git diff commitid - commitid 로 지정된 현재 작업 디렉토리와 이전 커밋의 차이점을 보여줍니다.
  4. git diff commita..commitb- 두 커밋 a와 b의 차이점을 보여줍니다. 커밋은 분기 또는 태그와 같은 기호 이름 일 수도 있습니다.

이 답변은 실제로 정확하지 않습니다. 이러한 명령은 모두 트리 전체뿐만 아니라 임의의 파일 세트에도 적용 할 수 있습니다. 끝에 파일 이름을 추가하기
만하면됩니다
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.