분기가없는 Git 커밋 나열 및 삭제 (댕글?)


146

특정 분기 아래에 많은 커밋이있는 Git 리포지토리가 있는데 할 git show수 있지만 포함 된 분기를 나열하려고하면 아무것도보고하지 않습니다.

나는 이것이 -D 브랜치의 결과로 매달려있는 커밋 / 트리 문제라고 생각했기 때문에 리포지를 정리했지만 여전히 그 후에도 동일한 동작을 봅니다.

$ git fetch origin

$ git fsck --unreachable
$ git fsck

출력도없고 매달려있는 것도 없습니다 (오른쪽?). 그러나 커밋이 존재합니다

$ git show 793db7f272ba4bbdd1e32f14410a52a412667042
commit 793db7f272ba4bbdd1e32f14410a52a412667042
Author: ...

그리고 그것은 어떤 지점을 통해서도 도달 할 수 없습니다

$ git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

출력을 제공하지 않습니다.

그 커밋의 상태는 정확히 무엇입니까? 모든 커밋을 유사한 상태로 나열하려면 어떻게해야합니까? 그런 커밋을 어떻게 삭제합니까?


답변:


75

출력이없고 매달려있는 것이 없습니다 (맞습니까?)

참조 로그에서 언급 된 커밋은 도달 가능한 것으로 간주됩니다.

그 커밋의 상태는 정확히 무엇입니까? 비슷한 상태의 모든 커밋을 나열하는 방법

패스 --no-reflogs설득하는 git fsck당신에게 보여.

그런 커밋을 어떻게 삭제합니까?

reflog 항목이 만료되면 해당 객체도로 정리됩니다 git gc.

만기가에 의해 규제되고 gc.pruneexpire, gc.reflogexpiregc.reflogexpireunreachable설정. Cf. git help config.

기본값은 모두 합리적입니다.


2
그래서 당신은 기본적으로 매달려있는 커밋에 대한 리플 로우가 잠시 후에 자동으로 제거 될 것이라고 말하고 있습니까?
MoralCode

2
기본적으로 그렇습니다 – 질문이 약간 혼란 스럽다는 점을 제외하고. 나는 것을 말하고 모든 reflog 항목이 잠시 후 자동으로 제거됩니다,하지만 당신은 구성 설정을 통해 그것을 변경할 수 있습니다. 그리고 커밋은 참조 로그 항목을 포함하여 아무 것도 가리 키지 않을매달려 이라고 만하기 때문에“매달려있는 커밋에 대한 참조”는 문제가되지 않습니다. 그들은“ 도달 할 수없는 커밋에 대한 거부 ”입니다.
아리스토텔레스 Pagaltzis

'그들은“도달 할 수없는 커밋에 대한 거부”일 것입니다.' 그러나 당신은 "귀하의 리플 로그에서 언급 된 커밋은 도달 가능한 것으로 간주된다"고 말했다. 그렇다면 어떻게 "도달 할 수없는 커밋에 대한 리 로그 로그"가 될 수 있을까요? 난 너무 혼란 스러워요.
LarsH

1
그래, 난 일관성이 없었어 일반적으로 사람들은 거부에 대해 생각하지 않으며, "도달 할 수 없다"고 말하면 "참조에서"를 의미합니다. 심지어 git help glossary"도달"에 대한 정의는 그런 식으로 좁혀되지 않는 반면, 그들이 모순 그래서 ... 그런 식으로 정의한다. 웃긴-그래서 내가 말한 것은 실제로 혼란과 일치합니다 gitglossary... 그러나 그것은 단지 용어가 혼동되는 개념이 아닙니다. 요점은 "매달린"커밋은 다른 것을 가리키는 것이 아니라는 것입니다 . 그것은 도움 나는 "에 대한 reflogs 말을하면 , 그렇지 않으면 도달 할 수없는 커밋"...?
아리스토텔레스 Pagaltzis

이것은 모두 매우 혼란 스럽다. 간단하게합시다. 나뭇 가지에 때 master, 당신이 git commit, 그리고 커밋 얻을 000001. 그런 다음 git commit --amend커밋 000002합니다. 000001더 이상 가리키는 태그 나 분기가 없으며 --reflog옵션 없이는 로그에서 볼 수 없지만 원하는 경우을 (를) 사용하여 얻을 수 있습니다 git checkout 000001. 이제 질문은,이다 매달려은 커밋 또는 연결할 수는 모두 커밋 또는 둘, 또는? 000001
chharvey

264

매달린 커밋과 reflog에서 도달 가능한 커밋을 제거하려면 다음을 수행하십시오.

git reflog expire --expire-unreachable=now --all
git gc --prune=now

그러나 이것이 당신이 원하는 것임을 확신하십시오. 맨 페이지를 읽는 것이 좋지만 여기 요점이 있습니다.

git gc도달 할 수없는 오브젝트 (커밋, 트리, 얼룩 (파일))를 제거합니다. 일부 지점의 내역에 속하지 않으면 개체에 연결할 수 없습니다. 실제로는 조금 더 복잡합니다.

git gc 다른 일을하지만 여기서는 관련이 없으며 위험하지 않습니다.

2 주 미만의 도달 할 수없는 개체는 제거되지 않으므로 --prune=now"이전에는 만든 연결할 수없는 개체 제거"를 의미합니다.

reflog를 통해 객체에 접근 할 수도 있습니다. 브랜치는 일부 프로젝트의 이력을 기록하지만 리플 로그는이 브랜치의 이력을 기록합니다. 수정하면 재설정 등의 커밋이 브랜치 히스토리에서 제거되지만 git은 실수를 저지른 경우를 대비하여 유지합니다. Reflogs는 브랜치 (또는 HEAD)에서 수행 된 파괴적인 (및 기타) 조작을 알아내는 편리한 방법으로 파괴적인 조작을보다 쉽게 ​​취소 할 수 있습니다.

따라서 지점에서 도달 할 수없는 모든 것을 실제로 제거하려면 reflog를 제거해야합니다. 우리는 --allreflog 를 만료 시켜서 그렇게합니다 . 다시 git은 사용자를 보호하기 위해 약간의 reflog를 유지하므로 그렇게하지 말라고 다시 지시해야 --expire-unreachable=now합니다.

필자는 파괴적인 작업에서 복구하기 위해 주로 reflog를 사용하기 때문에 일반적으로 reflog를 --expire=now완전히 방해합니다.


1
사용할 명령이 명확하지 않은 경우 gc로 충분하지 않아야합니까? 당신이 모르기 전에 git-reflog를 사용한 적이 없다면. 이제 어떤 명령을 사용해야하는지 알았으므로 해당 맨 페이지에서 언급 된 옵션을 찾아야합니다. 물론 그 대신 정보를 복사 할 수도 있습니다.
tarsius

1
실제로 나는 그것이 무엇을 하는지를 정확히 말한다 : "모든 매달린 커밋과 reflogs에서 접근 가능한 커밋을 제거하라". reflog가 무엇인지 모르는 경우 : 설명서를 다시 읽으십시오.
tarsius

7
주어진 답변은 정확할 수 있지만 @ erikb85는 귀하가 무엇을했는지에 대한 교육이 없다는 것을 지적하는 것이 옳습니다. RTFM에 대한 후속 조치는 그다지 도움이되지 않습니다. 예, 모든 문서를 읽어야합니다. 어떤 경우에는 검색을하는 사람이 무슨 일이 일어나고 있는지 알기에 충분한 문서를 작성하지 않았을 수도 있습니다. 따라서 명령이 수행하는 작업에 대한 약간의 교육은 나중에이 답변을 찾는 모든 사람에게 도움이 될 것입니다.
이 Saferite

@LeeSaferite 당신이 지금 모두 행복하길 바랍니다 :-)
tarsius

12
git reflog expire --expire-unreachable=now --all모든 은신처를 떨어 뜨립니다!
Vsevolod Golovanov 2018 년

22

이 스레드의 모든 조언을 따른 후에도 동일한 문제가 발생했습니다.

git reflog expire --expire-unreachable=now --all
git gc --prune=now
git fsck --unreachable --no-reflogs   # no output
git branch -a --contains <commit>     # no output
git show <commit>                     # still shows up

참조가 아닌 분기가 아닌 경우 ... 태그 여야합니다 !

git tag                             # showed several old tags created before the cleanup

git tag -d <tagname>정리 태그를 제거하고 정리를 다시 수행했는데 이전 커밋이 사라졌습니다.


태그 ( stackoverflow.com/a/37335660/450127 ) 에 대한 답변이 이미 있으며 이것이 새로운 것을 추가하는 것처럼 보이지 않습니다. 이전 답변에 찬성하여 이것을 제거해서는 안됩니까?
Ian Dunn

실제로, 나는 그 대답을 간과했다. 4 명이 내 답변이 도움이되었다고 생각했지만 그다지 쓸모가 없습니까? 또한 모든 가능성을 하나의 간결한 답변으로 그룹화했습니다.
jakub.g

1
중복 된 경우에도이 페이지가 Google 검색 결과에 표시 될 수 있으며 동일한 문제가있는 사람들에게 도움이 될 수 있습니다. 정답이있는 링크로 사람들을 반복해서 리디렉션하는 것보다 낫습니다 .
Alexandre T.

14
git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

아마 단지

git branch -a --contains 793db7f272ba4bbdd1e32f14410a52a412667042

리모컨의 분기에 대해서도보고


고마워, 이제이 커밋을 보유하고있는 리모컨 / 출처 / 다음을 찾았습니다. 그것을 제거하는 방법? git push -d origin next도움이되지 않습니다.
iRaS


고마워- git fetch --prune트릭을했다. 그러나 모든 답변 에서이 커밋을 참조하는 태그 검사가 누락되었습니다. 여전히 커밋으로 태그를 확인하는 방법을 모릅니다 (모두 제거했습니다).
iRaS

그러나 ... 이것은 원격 브랜치 에서만 도달 할 수 있고 로컬 브랜치에서는 도달 할 수없는 커밋이 도달 가능한 것으로 간주되므로 git fsck --unreachable실제로 어떤 커밋에 도달 할 수 있는지 확인하기 위해 원격으로 네트워크를 통해 통신하고 있습니까?
LarsH

1
내 자신의 질문에 대답 ... 예, 원격 지점에서만 도달 할 수있는 커밋 (및 로컬 지점 없음)은 도달 가능한 것으로 간주됩니다. 그러나 git fsck --unreachable어떤 원격 브랜치에 어떤 커밋이 있는지 알아 내기 위해 네트워크를 통해 원격으로 통신 할 필요는 없습니다. 원격 지사 정보는 예를 들어 .git/refs/remotes/origin(또는로 packed-refs) 로컬에 저장됩니다 .
LarsH

8

나는 비슷한 문제가 있었다. 나는 실행 git branch --contains <commit>했고 질문에서와 같이 출력을 반환하지 않았습니다.

하지만 도망친 후에도

git reflog expire --expire-unreachable=now --all
git gc --prune=now

내 커밋은 여전히을 사용하여 액세스 할 수 있습니다 git show <commit>. 분리 / 매달린 "지점"의 커밋 중 하나에 태그가 지정 되었기 때문입니다. 태그를 제거하고 위의 명령을 다시 실행했으며 황금색이었습니다. git show <commit>반환 fatal: bad object <commit>-정확히 내가 필요한 것. 바라건대 이것은 내가 갇힌 다른 누군가를 돕기를 바랍니다.


태그를 어떻게 제거 했습니까?
bapors

@bapors 모든 태그를 나열하고 해당 커밋을 참조하는 태그를 찾은 다음 삭제합니다. stackoverflow.com/questions/5480258/…
Andrew Larsson

4

실수로 같은 상황에 부딪쳐서 숨김에 도달 할 수없는 커밋에 대한 참조가 포함되어있는 것으로 추정되어 도달 할 수없는 커밋이 숨김에서 도달 할 수 있다고 가정했습니다.

이것들은 내가 진정으로 도달 할 수 없도록하기 위해했던 것입니다.

git stash clear
git reflog expire --expire-unreachable=now --all
git fsck --unreachable
git gc --prune=now

2

git gc --prune=<date>2 주 전보다 오래된 객체를 제거하는 것이 기본값입니다. 더 최근 날짜를 설정할 수 있습니다. 그러나 느슨한 객체를 생성하는 git 명령은 일반적으로 git gc --auto를 실행합니다 (이는 개수가 구성 변수 gc.auto의 값을 초과하면 느슨한 객체를 제거합니다).

이 커밋을 삭제 하시겠습니까? gc.auto의 기본 설정은 느슨한 객체가 불합리한 양의 메모리를 차지하지 않도록하며, 일정한 시간 동안 느슨한 객체를 저장하는 것이 좋습니다. 이렇게하면 내일 삭제 된 분기에 필요한 커밋이 포함되어 있음을 알게되면이를 복구 할 수 있습니다.

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