git bare 저장소에서 마지막 커밋을 어떻게 해제 할 수 있습니까?


94

베어 리포지토리에서 의미가없는 여러 git 명령이 있다는 점을 고려하면 (베어 리포지토리는 인덱스를 사용하지 않고 작업 디렉토리가 없기 때문에),

git reset --hard HEAD^ 

이러한 저장소에서 마지막 변경 사항을 커밋 해제하는 솔루션이 아닙니다.

인터넷을 통해 검색하면 주제와 관련하여 찾을 수있는 것은 이것 뿐입니다.이 작업을 수행하는 세 가지 방법이 있습니다.
1. "수동으로 참조 업데이트 (배관 관련)";
2. " git push -f베어가 아닌 저장소에서";
3. " git branch -f this $that".

어떤 솔루션이 더 적절하다고 생각하거나이를 수행하는 다른 방법이 있습니까? 불행히도 git bare 저장소에 대해 찾은 문서는 상당히 열악합니다.


8
@ Lavinia-Garbriela Dobrovol 아래의 복잡한 내용은 사용하지 마십시오. 당신은 HEAD를 다른 커밋으로 옮기려고하는데, 그것이 베어 레포에서도 git reset이 의도 한 것입니다. 아래 내 대답에 따라 다음을 사용하십시오. git reset --soft <commit> --soft를 사용하면 존재하지 않는 작업 트리와 인덱스를 변경하지 않아도되므로 git을 사용하면 문제없이 재설정 할 수 있습니다.
Hazok

답변:


133

git update-ref명령을 사용할 수 있습니다 . 마지막 커밋을 제거하려면 다음을 사용합니다.

$ git update-ref HEAD HEAD^

또는 마지막 커밋을 제거 할 수없는 분기에 있지 않은 경우 :

$ git update-ref refs/heads/branch-name branch-name^

원하는 경우 sha1을 전달할 수도 있습니다.

$ git update-ref refs/heads/branch-name a12d48e2

git-update-ref 명령에 대한 문서를 참조하십시오 .


@ Lavinia-Gabriela Dobrovolschi : 맞습니다. 정확한 구문에 익숙하지 않았습니다.
VonC 2011 년

@VonC git update-ref <ref> <newvalue>예를 들어 HEAD 대신 "refs / heads / master"와 같이 오른쪽 분기가되도록 <ref>를 지정할 수 있습니다 . 나는 당신의 질문을 오해하지 않았기를 바랍니다.
Lavinia-Gabriela Dobrovolschi

@Sylvain : +1 좋은 편집. @ Lavinia-Gabriela Dobrovolschi는 정밀도에 감사드립니다. 훨씬 더 실용적입니다 (원격 서버에 직접 액세스 할 수있는 경우).
VonC 2011 년

3
예제는 branch-name인수 와 관련하여 오해의 소지가 있습니다. update-ref"브랜치"와 함께 사용할 때는 반드시 브랜치의 전체 참조 이름을 지정해야합니다 (즉 refs/heads/, 일반 짧은 브랜치 이름 앞에 추가 ). 짧은 이름을 사용하는 경우 $GIT_DIR/branch-name대신 생성 / 업데이트하게 됩니다 $GIT_DIR/refs/heads/branch-name. branch-name및 둘 다 존재 refs/heads/branch-name하면 "refname… is ambiguous"경고가 발생합니다.
Chris Johnsen

이 대답은 Zach가 제안한 것보다 훨씬 더 복잡합니다. 그리고 그의 솔루션은 잘 작동합니다.
Krystian 2012

32

베어 저장소에서 다음을 사용하는 경우 :

git reset --soft <commit>

그러면 베어 레포에없는 것을 변경하려고하지 않기 때문에 베어 레포에서 사용하는 문제 --hard--mixed옵션 (예 : 작업 트리 및 인덱스)이 발생하지 않습니다. 귀하의 경우에는 (베어 레포에서) 사용하고 싶을 것입니다.

git reset --soft HEAD^

원격 저장소에서 분기전환 하려면 다음을 수행하십시오.

git symbolic-ref HEAD refs/heads/<branch_name>

현재 선택된 지점을 보려면 다음을 사용하십시오.

git symbolic-ref HEAD

https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html


3
이동하려는 분기를 어떻게 선택합니까? 귀하의 예제는 마스터 git checkout other_branch에서는 잘 작동 하지만 베어에서는 작동하지 않습니다.
Gauthier

1
흠 ... 누가이 문제에 대해 투표했는지 궁금합니다. 이 질문은 원격 저장소에서 분기를 전환하는 방법이 아니라 베어 저장소에서 재설정하는 방법을 물었습니다. 원격 저장소의 기본 분기를 변경하려면 git symbolic-ref HEAD refs / heads / <branch_name>을 사용하십시오.
Hazok

7

git push -f잘 작동합니다 :
당신이 베어의 repo를 복제하는 경우, 마지막 커밋 제거 ( git reset --hard HEAD^(당신이 언급으로, 그러나 로컬이 아닌 베어 REPO)에 푸시 백 -f) :

  • 제거하는 커밋 이전의 다른 커밋에 대해서는 SHA1을 변경하지 않습니다.
  • 베어 리포지토리의 정확한 내용에서 추가 커밋을 뺀 내용을 푸시 백 할 수 있습니다 (먼저 복제했기 때문입니다).

@ VonC 안녕하세요 Von, Git에서 많은 답변을 봤기 때문에 물어보고 싶었습니다 ... 궁금했습니다. git reset --soft <sha1>아래 답변에 표시된대로 베어 저장소에서 HEAD를 이동하는 데 권장되는 연습 이 아닌 이유는 무엇입니까?
Hazok

내가 묻는 또 다른 이유는 베어 리포지토리에 소프트 리셋을 사용하는 것은 쉽게 사용할 수있는 정보가 아니며 소프트 리셋이 최소한의 입력과 최소한의 기회로 인해 모범 사례 인 것처럼 보일 때 많은 포럼에서 불필요하게 복잡한 해결 방법을 가지고있는 것 같습니다. 오류.
Hazok

2
@Zach : a reset --soft는 베어 저장소에서 직접 수행 할 때 작동합니다. 베어 리포지토리는 일반적으로 업스트림 리포지토리 (즉, 데이터를 푸시하는 리포지토리)이고 대부분의 경우 로컬에 직접 액세스 할 수 없기 때문에 거의 수행되지 않는 것 같습니다. 그러나 그렇게한다면 이것은 확실히 " reset --soft"사용 의 또 다른 좋은 예입니다 (예 : stackoverflow.com/questions/5203535/… ). 따라서 답에 +1하십시오.
VonC

2

git refspec 표기법을 사용하여 다음과 같이 할 수도 있습니다.

git push -f origin +<commit you want to revert to>:<destination_head | branch_name>

이렇게하면 대상 분기 (ref로 표시됨)가 +<object ref>부분 으로 표시된대로 소스 커밋으로 업데이트됩니다 .


2
당신이 "필요 베어의 repo 자체에 그것을 할"경우 보통의 경우 ... - 지점의 ACL이있는 경우를 제외하고
데이비드 슈미트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.