programing

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

jooyons 2023. 7. 19. 21:21
반응형

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

없는 있습니다. 저는 Git 저장소를 할 수 .git show포함된 분기를 나열하려고 하면 아무 것도 반환되지 않습니다.

저는 이것이 (-D 분기의 결과로) 달링 커밋/트리 문제인 줄 알고 레포를 제거했지만, 그 이후에도 여전히 동일한 동작이 보입니다.

$ git fetch origin

$ git fsck --unreachable
$ git fsck

출력도 없고 매달린 것도 없습니다.하지만 커밋은 존재합니다.

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

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

$ git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

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

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

모든 매달린 커밋(스태시 및 다른 리프로그에서 여전히 도달할 수 있는 커밋 포함)을 제거하려면 다음 작업을 수행합니다.

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

하지만 이것이 당신이 원하는 것이라는 것을 확실히 하라.저는 당신이 남성 페이지를 읽는 것을 추천하지만 요점은 다음과 같습니다.

git gc연결할 수 없는 개체(트리, 트리, 블롭(파일))를 제거합니다.개체가 일부 분기의 기록에 포함되지 않은 경우 개체에 연결할 수 없습니다.사실 그것은 조금 더 복잡합니다.

스택은 리필로그를 사용하여 구현됩니다(즉, 분기 또는 태그가 아님).그것은 그들이 쓰레기 수거 대상이라는 것을 의미합니다.

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

할 수 없는 주연할수없전 2는이제않사다용으니를 합니다.--prune=now즉, "이전에 생성된 연결할 수 없는 개체 제거"를 의미합니다.

reflog를 통해 객체에 도달할 수도 있습니다.분기는 일부 프로젝트의 기록을 기록하는 반면, reflog는 이러한 분기의 기록을 기록합니다.수정, 재설정 등의 커밋은 분기 기록에서 제거되지만 실수한 경우를 대비하여 Git을 사용하면 커밋이 유지할 수 있습니다.리플로그는 분기(또는 HEAD)에서 수행된 파괴(및 기타) 작업을 확인할 수 있는 편리한 방법으로 파괴 작업을 쉽게 실행 취소할 수 있습니다.

그래서 우리는 리플로그를 제거해야 합니다. 실제로는 분기에서 도달할 수 없는 모든 것을 제거하기 위해서요.만료를 통해 이를 수행합니다.--all리필그하지 : 다시사용보자호보위리약를다관그로므그합말하렇다말니야해고라지게시는하플로간의해기하를는log합말다니▁sos야해▁a▁keeps리▁ref필▁g▁again▁to고.--expire-unreachable=now.

에 reflog를 합니다.--expire=now재로그를 완전히 재핑합니다.

출력도 없고 매달린 것도 없습니다(맞습니까?

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

그 약속의 상태는 정확히 무엇입니까?상태가 비슷한 커밋을 모두 나열하려면 어떻게 해야 합니까?

통과하다--no-reflogs납득시키기 위해git fsck보여드리기 위해서요.

그런 커밋을 삭제하려면 어떻게 해야 합니까?

도 reflog 항이만해개당다통정다리니됩해목에 의해 됩니다.git gc.

만료는 다음에 의해 조절됩니다.gc.pruneexpire,gc.reflogexpire,그리고.gc.reflogexpireunreachable설정.Cf.

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

이 스레드의 모든 조언을 따르더라도 여전히 동일한 문제가 있었습니다.

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>그리고 청소를 다시 했고, 이전의 커밋은 사라졌습니다.

업데이트: 태그가 아닌 것으로 밝혀진다면, 그것은 또한 저장일 수도 있습니다! 답변과 이 답변확인합니다.

git branch --contains 793db7f272ba4bbdd1e32f14410a52a412667042

아마 그냥 필요할 것입니다.

git branch -a --contains 793db7f272ba4bbdd1e32f14410a52a412667042

원격에서 분기에 대해서도 보고합니다.

실수로 동일한 상황에 도달했는데, 내 스택에 도달할 수 없는 커밋에 대한 참조가 포함되어 있으므로, 예상 도달할 수 없는 커밋에 도달할 수 있습니다.

이것들이 제가 정말로 도달할 수 없게 만들기 위해 한 일들입니다.

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

저도 비슷한 문제가 있었습니다.도망친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>정확히 내가 필요로 했던 것.이것이 저처럼 꼼짝 못했던 다른 누군가에게 도움이 되기를 바랍니다.

TL:DR;

커밋은 다음 사용자가 참조할 수 있습니다.

  • 가지
  • 꼬리표(!)
  • 저장고(!!)
  • "대체"(!!?)

이 명령을 사용하여 정확히 무엇인지 찾습니다.

git for-each-ref --contains <SHA>

롱 버전

나는 했습니다.filter-repo레포가 어떤 거대한 파일을 정리하는 것.

분명히 몇 가지 위험한 범죄로 끝났습니다.저는 모든 답을 시도했지만 아무 것도 작동하지 않았습니다.

git branch --contains <SHA>           # nothing!
git fsck --unreachable --no-reflogs   # nothing!

그리고 이 답변 덕분에 태그를 찾아서 삭제했습니다.

그럼에도 불구하고 그 약속은 계속 증가했습니다!

그래서 저는 마침내 다음 명령을 실행했습니다.

git for-each-ref --contains <SHA>

그리고 그것은 돌아왔습니다.

1b9bf9c63209a4728b2d3dc7946da836dc331bbd commit refs/stash

빙고!

도망친git stash그리고 그것은 비어 있었습니다.내가 나의 저장소에 아무것도 없는데 어떻게 나의 저장소가 커밋을 참조할 수 있습니까?

그러나 실행 중git stash drop몇 번이나 오래된 가지를 기반으로 포기된 "달링" 스테이시를 삭제했고 마침내 저는 할 수 있었습니다.gc그 약속으로 제 레포는 순식간에 15MB 작아졌습니다.

더 긴 버전

(다른 사용자로부터) 위의 팁을 사용했는데 반환되었습니다.

4c79e05b102c673e1f60242c022ff06e017b9a1d commit refs/replace/2acd8f182e14d7d367b3469fd8751f2d9738a884

대체란 대체 무엇입니까?

git replace -h

에서는 이러한 '교체 개체'를 삭제하고 편집할 수 있는 목록을 보여 줍니다.이상해요. 달리기git replace -d 2acd8f커밋을 제거합니다!

git gc --prune=<date>기본적으로 2주 전보다 오래된 개체를 잘라냅니다.더 최근 날짜를 설정할 수 있습니다.그러나 느슨한 개체를 만드는 git 명령은 일반적으로 git gc --auto(그 수가 구성 변수 gc.auto의 값을 초과하는 경우 느슨한 개체를 자릅니다)를 실행합니다.

이러한 커밋을 삭제하시겠습니까? gc.auto의 기본 설정은 느슨한 개체가 비정상적인 양의 메모리를 차지하지 않도록 보장하며, 느슨한 개체를 일정 시간 동안 저장하는 것이 일반적으로 좋습니다.이렇게 하면 삭제된 분기에 필요한 커밋이 포함되어 있다는 사실을 내일 알게 되면 해당 분기를 복구할 수 있습니다.

그 " 라면,
git fsck --full
도움이 될 수 있습니다.다른 해결책이 없을 때 효과가 있었습니다.

(Git: 손상된 스택 제거는 이 스레드보다 내 문제를 더 정확하게 설명합니다.)

이것이 좋은 해결책이 아니라는 것을 알지만, 저는 했습니다.filter-branch분기에 속하지는 않지만 자동으로 제거할 수 없는 중복된 연결 불가능한 커밋이 발생했습니다. 여기에 게시된 모든 솔루션을 사용해봤지만 전혀 효과가 없었습니다.로 푸시하고 도달할 수 했습니다.

먼저 도달할 수 없는 모든 커밋을 적극적으로 삭제/제거해야 하는지 여부를 고려해야 합니다.

다음 메시지가 표시되었을 수 있습니다.

warning: There are too many unreachable loose objects; run 'git prune' to remove them.

그리고 나서.git prune문제가 해결되지 않은 것 같아서 좀 더 적극적으로 삭제할 수 있는 노브를 찾고 있습니다.

최근 커밋을 정리할 때의 문제는 리모컨과도 상호 작용할 경우 최악의 경우(이것이 얼마나 가능성이 있는지는 모르겠습니다) 손상될 수 있다는 것입니다.

이 프로세스 중에 리포지토리가 하나 이상의 푸시를 수신할 때 속도 동작이 발생합니다.주요 원인은 서버가 광고를 기반으로 클라이언트가 보낸 객체를 처리하는 것과 다른 시점에 객체를 광고하는 것입니다.

중 가 […] 이전에 ,C실제로 제거되면 리포지토리가 손상된 상태가 될 수 있습니다.

따라서 디스크 공간이 부족하거나 개체가 너무 많은 것이 아니라 "느슨한 개체"가 직접적인 문제라면 이 실험 기능을 활성화할 수 있습니다(Git 2.40.1 기준).

git config gc.cruftPacks true

지금이다git gc연결할 수 없는 개체를 패킹하여 해당 경고를 제거합니다.


도달할 수 없는 최신 개체를 제거할 이유가 없다면 실험 기능을 사용하는 것이 더 안전한 것 같습니다.

언급URL : https://stackoverflow.com/questions/3765234/listing-and-deleting-git-commits-that-are-under-no-branch-dangling

반응형