초기 자식 커밋을 되 돌리는 방법?


357

처음으로 git 저장소에 커밋합니다. 그런 다음 커밋을 후회하고 되돌리고 싶습니다. 나는 노력한다

# git reset --hard HEAD~1

이 메시지가 나타납니다.

fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree.

이 커밋은 리포지토리의 첫 번째 커밋입니다. git의 초기 커밋을 취소하는 방법에 대한 아이디어가 있습니까?

답변:


565

현재 지점을 삭제하기 만하면됩니다. git branch -D이 작업에 대한 안전 점검이 있으므로 사용할 수 없습니다 . 이를 위해 사용할 수 있습니다 update-ref.

git update-ref -d HEAD

마십시오 하지 사용 rm -rf .git하거나 같은 이런 건 완전히 다른 모든 지점뿐만 아니라 재설정하려고하는 지점을 포함하여 전체 저장소를 닦아 주실 것이다.


1
rebase에서 이것을 시도했다 – 첫 커밋을 나누고 싶었다 – 그리고 git status깜짝 놀랐다 fatal: Not a git repository (or any parent up to mount point ...).
매트 펜윅

1
이것은 나를 위해 작동하지 않았다. 무시해야하지만 일부는 포함하지 않은 파일을 만드십시오 .gitignore. git add ., git commit -m "initial commit", git update-ref -D HEAD하는 생성 .gitignore자식은 여전히 이전에 무시해야하는 추가 파일을보고있는 것을 통지합니다. 다시 말해 git update-ref -d HEAD, 초기 커밋 이전의 상태로 다시 돌아 가지 않았습니다.
gman

1
그러나 이것이 원래 질문의 요점입니다. 초기 커밋 직전의 상태로 돌아갑니다.
gman

2
git reset --hard HEAD~1다른 모든 커밋에 대해 추가 된 파일을 제거합니다. 분명히 그 질문은 다른 모든 경우에 해당 명령이 작동하는 것과 동일한 상태에 이르는 방법입니다. 증명이 요점을 참조 솔루션하지 않습니다 작업 gist.github.com/greggman/522fa69a21d6cfb3ff0b
G 맨

11
: 경우 사람이 G 맨의 의견에 의해 혼동됩니다 git update-ref -d HEAD 않습니다 실제로 초기 커밋을 되돌리려하지만, 인덱스에 추가 이전에 최선을 다하고 변경을 유지합니다. 이러한 변경 사항도 제거하려면 다음을 실행하십시오 git reset --hard. 불완전 하더라도이 답변은 실제로 가장 좋은 답변이므로 사용 rm -fr .git하지 마십시오 (무엇을하고 있는지 알지 못하는 경우).
rsenna

62

HEAD를 삭제하고 저장소를 새로운 상태로 복원하여 새로운 초기 커밋을 작성할 수 있습니다.

git update-ref -d HEAD

새 커밋을 만든 후 이미 원격으로 푸시 한 경우 이전 초기 커밋을 덮어 쓰려면 원격으로 강제로 보내야합니다.

git push --force origin

1
주목할만한 점은 ... 올바른 명령이지만 HEAD를 삭제하지는 않습니다. .git \ HEAD 파일이 체크 아웃 한 ref (.git \ refs \ heads에 위치)를 삭제합니다. 이 명령을 실행 한 후에도 삭제 한 refs / heads / <name> 파일을 가리키는 HEAD 파일을 여전히 찾을 수 있지만 해당 경로를 따르면 헤드 참조가 더 이상 존재하지 않음을 알 수 있습니다.
DanK

15

이 질문은 이 블로그 게시물 에서 링크되었으며 최신 버전의 Git에 대한 대안 솔루션이 제안되었습니다.

git branch -m master old_master
git checkout --orphan master
git branch -D old_master

이 솔루션은 다음을 가정합니다.

  1. master지점 에 단 하나의 커밋이 있습니다
  2. 라는 지점이 없으므로 old_master그 이름을 자유롭게 사용할 수 있습니다

기존 브랜치의 이름을 바꾸고 old_master새 고아 브랜치 master (예 : 새 리포지토리에 대해 생성 된)를 생성 한 후 자유롭게 삭제할 수 있습니다 old_master. 당신에게 달려 있습니다.

참고 : git 브랜치를 이동하거나 복사하면 reflog ( 이 코드 참조 )는 유지하면서 삭제하고 새 브랜치를 만들면 파괴됩니다. 기록이없는 원래 상태로 돌아가려면 분기를 삭제하고 싶을 수도 있지만 다른 사람들은이 작은 메모를 고려할 수도 있습니다.


11

질문에 명시된 조건에서 :

  • 커밋은 저장소에서 첫 번째 커밋입니다.
  • 이는 실행 된 명령이 거의 없다는 것을 의미합니다.
    • git init,
    • 아마도 일부 git add작업은
    • 그리고 git commit,
    • 그리고 그게 전부입니다!

이러한 전제 조건이 충족되면 초기 커밋을 취소하는 가장 간단한 방법은 다음과 같습니다.

rm -fr .git

당신이 한 디렉토리에서 git init. 그런 다음을 다시 실행하여 git initGit 저장소를 다시 작성하고 처음 작성하지 않은 것을 후회 한 변경 사항이 있으면 추가를 다시 실행하고 초기 커미트를 다시 실행할 수 있습니다.

위험! Git 리포지토리 디렉토리가 제거됩니다.

어딘가에 백업이 없으면 Git 저장소 디렉토리를 영구적으로 복구 할 수 없습니다. 전제 조건에서, 당신은 저장소에 보관하고 싶은 것이 없으므로 아무것도 잃지 않습니다. 추가 한 모든 파일은 아직 수정하지 않았거나 삭제하지 않았다고 가정 할 때 작업 디렉토리에서 계속 사용할 수 있습니다. 그러나이 작업은 저장소에 다른 것이없는 경우에만 안전합니다. '저장소를 처음 커밋 한 후 유감'이라는 질문에 설명 된 상황에서는 안전합니다. 그러나 종종 안전하지 않습니다.

또한 원치 않는 복제 된 저장소를 제거하기 위해이 작업을 수행하는 것이 안전합니다. 복제 된 저장소에 손상을주지 않습니다. 사본에서 수행 한 모든 것을 버리지 만 원래 저장소에는 영향을 미치지 않습니다.

주의하십시오. 그러나 전제 조건이 충족되면 안전하고 효과적입니다.

리포지토리에서 보존하려는 다른 작업을 수행 한 경우 이는 적절한 기술이 아닙니다. 리포지토리가 더 이상이를위한 전제 조건을 충족하지 않습니다.


9
이것은 나쁜 조언입니다. repo에 잃고 싶지 않은 다른 것들이 있다면 어떨까요?
매트 펜윅

5
그렇다면 그것은 초기 커밋이 아닐 것입니다. 초기 커밋은 하나뿐입니다.
Jonathan Leffler

9
"그러면 초기 커밋이되지 않을 것입니다."-실제로는 그렇습니다. 다중 브랜치의 매우 일반적인 경우를 무시하고 있습니다. Charles의 답변을 참조하십시오.
매트 펜윅

2
그러나 도움이되는 경고가 표시되어야합니다.
Simon Bengtsson

5
이것은 실제로 작동합니다. 수락 된 답변은 그렇지 않습니다. 의견보기
gman

3

당신은 할 수 없습니다. 그래서:

rm -rf .git/
git init
git add -A
git commit -m 'Your new commit message'

1
그는 말을하려고했는데 git reset --hard왜 그렇게했을 git add -A까요?
아리스토텔레스 Pagaltzis

3

나는 결국 나를 위해 일한 것을 던질 것입니다. 격리 된 데이터가 잘못 배치되어 커밋이 이미 푸시되어 리포지토리에서 초기 커밋을 제거해야했습니다.

현재 올바른 지점에 있는지 확인하십시오.

git checkout master

git update-ref -d HEAD

git commit -m "Initial commit

git push -u origin master

이것은 문제를 해결할 수있었습니다.

중대한

공개적으로 액세스 할 수없는 내부 저장소에 있습니다. 저장소에 공개적으로 액세스 할 수있는 경우 되돌려 야 할 항목이 이미 다른 사람에 의해 풀려 졌다고 가정하십시오.


1

"amend"이 왜 제안되지 않았고 @damkrat에 의해 넘어 갔는지 궁금합니다. amend은 초기 커밋이없는 목적이 없기 때문에 잘못된 커밋을 수정하는 근본적인 문제를 가장 효율적으로 해결하는 올바른 방법으로 나타납니다. 범하다. 스트레스를받은 사람이 아무도 당신의 저장소를 복제하지 않은 경우 마스터 같은 "공개"분기를 수정해야합니다 ...

git add <your different stuff>
git commit --amend --author="author name <author.name@email.com>"-m "new message"


0

git reset --hard 변경 후 수행

git add -A
git commit --amend --no-edit 

또는

git add -A
git commit --amend -m "commit_message"

그리고

git push origin master --force

--force는 첫 번째 단계에서 재설정 한 커밋을 다시 작성합니다.

VCS 시스템의 모든 아이디어에 반대하고 특히 git을 사용하려고하기 때문에이 작업을 수행하지 마십시오. 유일한 좋은 방법은 새 분기를 만들고 불필요한 분기를 삭제하는 것입니다. git help branch정보를 참조하십시오 .


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