자식에서 분기를 삭제하면 기록에서 제거됩니까?


190

svn에서 왔으며 git에 익숙해지기 시작했습니다.

git에서 브랜치가 삭제되면 히스토리에서 제거됩니까?

svn에서는 삭제 작업 (역 병합)을 되돌려 분기를 쉽게 복구 할 수 있습니다. svn의 모든 삭제와 마찬가지로 분기는 실제로 삭제되지 않으며 현재 트리에서 제거됩니다.

분기가 실제로 git의 히스토리에서 삭제되면 해당 분기에서 병합 된 변경 사항은 어떻게됩니까? 그들은 유지됩니까?

답변:


251

브랜치는 git에서 커밋에 대한 포인터 일뿐입니다. git에서 각 커밋에는 완전한 소스 트리가 있으며 svn과는 매우 다른 구조입니다.이 규칙은 모든 분기 및 태그 (일반적으로)가 특별한 '트렁크'와 함께 저장소의 별도 '폴더'에 있습니다.

브랜치가 삭제되기 전에 다른 브랜치로 병합 된 경우, 첫 번째 브랜치가 삭제 될 때 모든 커밋은 다른 브랜치에서 여전히 도달 할 수 있습니다. 그들은 그대로 유지합니다.

브랜치가 다른 브랜치로 병합되지 않고 삭제되면 해당 브랜치의 커밋 (커밋에서 여전히 도달 할 수있는 지점까지)이 표시되지 않습니다.

커밋은 여전히 ​​리포지토리에 유지되며 삭제 후 즉시 커밋 할 수 있지만 결국 가비지 수집됩니다.


3
답변 해주셔서 감사합니다. "각 커밋에 완전한 소스 트리가 있습니다"라는 의미를 명확하게 설명해 주시겠습니까? 내가 이해하는 것처럼 git의 각 커밋은 전체 트리가 아닌 부모 커밋을 다시 참조하는 델타 세트입니다.
Ken Liu

2
@Ken Liu : 커밋에는 0 개 이상의 부모 커밋, 트리 객체 및 커밋에 대한 일부 메타 데이터에 대한 포인터가 포함됩니다. 따라서 커밋은 커플 소스 트리와 부모에 대해 볼 때 도입 한 변경 사항을 고유하게 식별합니다.
CB Bailey

9
@ Ken Liu : 그것은 당신이 '포함'한 것에 정확히 달려 있지만, 본질적으로 각 커밋에는 완전한 트리가 포함됩니다. 객체 데이터베이스에서 객체는 id로 인덱싱되므로 객체를 참조하는 모든 객체 (트리 및 커밋)간에 객체가 공유되므로 암시 적 스토리지 오버 헤드가 처음 들리는 것만 큼 나쁘지 않습니다. git은 디스크 공간을 더욱 효율적으로 사용하는 효율적인 저장소 최적화 (팩 파일) 기능도 제공합니다.
CB Bailey

22
"결국 가비지 수집됩니다" -결국 언제?
BadHorsie

7
@BadHorsie에 따라 다릅니다 .
AliOli

86

Git에서 브랜치는 커밋의 DAG (directed acyclic graph)에서 커밋에 대한 포인터 (참조)입니다. 이는 분기를 삭제하면 커밋에 대한 참조 만 제거되므로 DAG의 일부 커밋에 도달 할 수 없어 보이지 않게 될 수 있습니다. 그러나 삭제 된 브랜치에 있던 모든 커밋은 적어도 도달 할 수없는 커밋이 정리 될 때까지 (예 :를 사용하여 git gc) 여전히 저장소에 있습니다.

참고 git branch -d그것을 삭제하면 도달 할 수없는 커밋을 떠나지 않을 것입니다 있는지 확인 할 수없는 경우 분기를 삭제하는 것을 거부합니다. git branch -D도달 할 수없는 커밋을 남길 수있는 경우 분기를 강제로 삭제 하려면 더 강력하게 사용해야합니다 .

도달 할 수없는 커밋 (있는 경우)은 삭제 된 분기의 마지막 팁과 기존의 다른 분기에 병합 된 커밋, 태그 지정된 커밋 또는 분기 지점 사이의 커밋입니다. 둘 중 나중에 예를 들어 다음과 같은 상황에서 :

---- O ---- * ---- * ---- / M ---- * <-master <-HEAD
     \ /
      \ --.----.-- /-x --- y <-삭제 된 분기

분기를 삭제 한 후에는 커밋 'x'와 'y'만 도달 할 수 없게됩니다.

gc.reflogExpire기본 90 일 기간 동안 삭제 된 지점에서 작업 한 경우 삭제 된 지점 의 마지막 팁이 HEAD reflog에 기록됩니다 ( git reflog show HEAD또는 참조 git log --oneline --walk-reflogs HEAD). HEAD reflog를 사용하여 삭제 된 포인터를 복구 할 수 있어야합니다. 이 경우 삭제 된 분기에서만 도달 할 수없는 커밋은 gc.reflogExpireUnreachable기간 (기본적으로 30 일 ) 내에 제거 (제거)되지 않도록 보호 됩니다.

당신이 머리 reflog에서 바로 삭제 브랜치의 끝을 찾을 수없는 경우, 당신이 사용하려고 할 수 있습니다 git fsck찾을 수 "에 연결할 수는 <SHA1> 커밋"을 (를 통해 그 검사 git show <sha1>또는 git log <sha1>삭제 된 지점의 끝을 찾을 수).

삭제 된 분기의 팁을 찾는 방법에 관계없이 삭제를 취소하거나 방금 삭제 한 분기를 사용하여 다시 생성 할 수 있습니다.

git branch <deleted-branch> <found-sha1-id>

그러나 브랜치에 대한 Reflog는 유실됩니다.


git-resurrect.sh 스크립트 도 있습니다.이 스크립트는 contrib/지정된 이름으로 분기 팁의 흔적을 찾아서이를 삭제 (삭제 취소)하는 데 도움이됩니다.


1
대박! git reflog show HEAD커밋을 나열하고 당신이 말한 것처럼 완벽하게 새 브랜치를 만들었습니다.
Steven Almeroth 2016 년

2

실수로 삭제 된 브랜치에 대해 걱정하고 더 이상 리포지토리의 로컬 사본이없는 경우 Gerrit와 같은 Enterprise Git 서버에 대한 확장 기능이있어 기록 재 작성 및 브랜치 삭제를 감지하고 특별한 참조에 따라 백업합니다. 필요한 경우 복원 할 수 있으며 가비지 수집으로 정리하지 않습니다. Gerrit 관리자는 법적 이유로 필요한 경우 여전히 선택된 커밋을 제거 할 수 있습니다.

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