Git 리포지토리를 이전 커밋으로 되돌리려면 어떻게해야합니까?


7630

현재 상태에서 특정 커밋에 대한 스냅 샷으로 되 돌리는 방법은 무엇입니까?

내가 git log하면 다음 출력을 얻습니다.

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <me@me.com>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <me@me.com>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <me@me.com>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <me@me.com>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

11 월 3 일부터 커밋으로 되돌리려면 어떻게해야 0d1d7fc합니까?



116
다음 은 Github에서 직접 git에서 실행 취소하는 것에 대한 매우 명확하고 철저한 게시물 입니다.
노비타

3
관련 : 롤백 오래된 힘내으로는 공공의 repo에 커밋 . 이 질문은 repo가 ​​공개라는 제약을 추가합니다.

58
나는 git을 좋아하지만 엄청나게 간단 해야하는 것에 대한 35 가지 대답이 있다는 사실은 git과 관련된 큰 문제를 노출시킵니다. 아니면 문서입니까?
머핀 남자

2
어떻게 단어를 사용에서 언어 "트랩"입니다 되돌리려 구어체 의미로 재설정 도 여기에 따르기는 하겠지만하지 ??? 차이를 강조하기 위해 6594는 지금까지 이러한 방식으로 편집하지 않고 상향 조정했습니다. "
commiting

답변:


9724

이것은 "되 돌리다"의 의미에 따라 다릅니다.

일시적으로 다른 커밋으로 전환

일시적으로 돌아가서 어리석은 다음 현재 위치로 돌아 오려면 원하는 커밋을 확인하십시오.

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32

또는 당신이 거기있는 동안 커밋을하고 싶다면 계속해서 새로운 지점을 만드십시오.

git checkout -b old-state 0d1d7fc32

현재 위치로 돌아가려면 다시 있던 지점을 확인하십시오. (분기를 전환 할 때 항상 변경 한 경우 분기를 적절하게 처리해야합니다. 버릴 수 있도록 재설정 할 수 있습니다. 버릴 수 있습니다. 당신이 거기에 지점을 원한다면 거기에 지점에.)

게시되지 않은 커밋 강제 삭제

반면에 그 이후로 한 모든 일을 정말로 없애고 싶다면 두 가지 가능성이 있습니다. 하나, 이러한 커밋을 게시하지 않은 경우 간단히 재설정하십시오.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.

혼란 스러우면 이미 로컬 변경 사항을 버렸지 만 최소한 다시 재설정하여 이전 위치로 돌아갈 수 있습니다.

새로운 커밋으로 게시 된 커밋 실행 취소

다른 한편으로, 당신이 작품을 출판했다면, 아마도 역사를 효과적으로 다시 작성하기 때문에 브랜치를 재설정하고 싶지 않을 것입니다. 이 경우 실제로 커밋을 되돌릴 수 있습니다. Git을 사용하면 revert는 매우 구체적인 의미를 갖습니다. 리버스 패치로 커밋을 만들어 취소하십시오. 이렇게하면 기록을 다시 쓰지 않습니다.

# This will create three separate revert commits:
git revert a867b4af 25eee4ca 0766c053

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

#Similarly, you can revert a range of commits using commit hashes:
git revert a867b4af..0766c053 

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use `rebase -i` to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

git-revert맨 페이지는 실제로 해당 설명이 많이 포함한다. 또 다른 유용한 링크는 이 git-scm.com 섹션으로 git-revert에 대해 설명 합니다.

결국 되 돌리지 않기로 결정한 경우 여기에 설명 된대로 되돌리기를 되돌 리거나 되돌리기 전에 다시 재설정 할 수 있습니다 (이전 섹션 참조).

이 경우에도이 답변이 도움이 될 수 있습니다.
HEAD를 이전 위치로 다시 옮기는 방법? (분리 된 머리)


118
커밋 git revert HEAD~3을 되돌릴 수있는 최고의 와트 에 대한 @Rod의 의견3 은 중요한 협약입니다.
새로운 Alexandria

19
정수를 쓸 수 있습니까? 처럼 :git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Spoeken

16
@MathiasMadsenStav 예, 전체 SHA1으로 커밋을 지정할 수 있습니다. 나는 해시를 더 읽기 쉽게 만들기 위해 약식 해시를 사용했으며 입력 할 때도 해시를 사용하는 경향이 있습니다. 복사하여 붙여 넣는 경우 반드시 전체 해시를 사용하십시오. 커밋 이름을 지정하는 방법에 대한 자세한 내용 은 man git rev-parse에서 개정 지정을 참조하십시오 .
Cascabel

59
당신은 git revert --no-commit hash1 hash2 ...한 번의 커밋으로 모든 되돌리기를 커밋하고 사용할 수 있습니다git commit -m "Message"
Mirko Akov

6
이 문맥에서 '게시'는 무엇을 의미합니까?
Howiecamp

1849

여기에 복잡하고 위험한 답변이 많이 있지만 실제로는 쉽습니다.

git revert --no-commit 0766c053..HEAD
git commit

이것은 HEAD에서 커밋 해시로 모든 것을 되돌릴 것입니다. 즉, 모든 커밋이 되돌아온 것처럼 작업 트리에서 커밋 상태를 다시 만듭니다 . 그런 다음 현재 트리를 커밋 할 수 있으며 "revert"한 커밋과 본질적으로 동일한 새로운 커밋을 만듭니다.

( --no-commit플래그를 사용하면 git은 모든 커밋을 한 번에 되돌릴 수 있습니다. 그렇지 않으면 범위 내의 각 커밋에 대한 메시지가 표시되어 불필요한 새 커밋으로 기록을 잃게됩니다.)

이것은 이전 상태로 롤백 하는 안전하고 쉬운 방법 입니다. 기록이 삭제되지 않으므로 이미 공개 된 커밋에 사용할 수 있습니다.


23
당신이 정말로 (대신 하나 개의 큰 가진 모든 것을 되 돌리는 커밋) 개인의 커밋을 할 경우, 당신은 통과 할 수 --no-edit대신 --no-commitA는 각각의 복귀에 대한 커밋 메시지 편집하지 않아도 것을.

87
0766c053..HEAD 사이의 커밋 중 하나가 병합 인 경우 오류가 발생합니다 (-m을 지정하지 않은 경우와 관련됨). 이것은 다음과 같은 상황에
처한

7
사용하기 전에 diff를 보려면 사용하십시오 git diff --cached.
John Erck

21
$ git revert --no-commit 53742ae..HEAD반환fatal: empty commit set passed
Alex G

10
@AlexG 그것은 당신이 돌아가고 싶은 해시 보다 먼저 해시를 입력해야하기 때문 입니다. 내 경우에는 해시가 81bcc9e HEAD{0}; e475924 HEAD{1}, ...(에서 git reflog)와 81bcc9egit revert e475924..HEAD
같았고

1611

도적 코더?

혼자서 일하고 싶지만 작동하고 싶습니까? 아래의 지침을 따르십시오. 수년 동안 저와 다른 많은 사람들을 위해 안정적으로 일했습니다.

다른 사람들과 함께 일하십니까? 힘내는 복잡하다. 발진이 생기기 전에이 답변 아래의 의견을 읽으십시오.

가장 최근의 커밋으로 작업 복사본 되돌리기

변경 사항을 무시하고 이전 커밋으로 되돌리려면

git reset --hard HEAD

HEAD는 현재 지점의 마지막 커밋입니다.

작업 사본을 이전 커밋으로 되돌리기

가장 최근의 커밋보다 오래된 커밋으로 되돌리려면 :

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

크레딧은 비슷한 스택 오버플로 질문으로 이동합니다. Git에서 SHA 해시로 커밋으로 되 돌리시겠습니까? .


33
나는 그렇게했지만 원격 저장소로 커밋하고 푸시 할 수 없었습니다. 나는 특정 오래된 커밋이 HEAD가되기를 원합니다 ...
Lennon

7
그것은 당신이 이미 되돌릴 커밋을 푸시했다는 것을 의미합니다. 코드를 체크 아웃하고 작업하는 사람들에게 많은 문제가 발생할 수 있습니다. 그들은 커밋을 부드럽게 적용 할 수 없기 때문에. 이 경우 git revert를 사용하는 것이 좋습니다. 당신이 repo를 사용하는 유일한 사람이라면. git push -f (하지만 그렇게하기 전에 두 번 생각하십시오)
vinothkr

6
또한 소프트 리셋 솔루션의 경우 먼저 혼합 재설정을 수행하고 마지막으로 하드 재설정을 수행하는 대신 실제로 다음과 같이 하드 재설정을 먼저 수행 할 수 있음을 지적하고 싶습니다 git reset --hard 56e05fc; git reset --soft HEAD@{1}; git commit.

5
@ nuton linus는 git의 제작자 인 pauling 자신이 너무 복잡하다고 비판했습니다. 그는 "충격을 받았다"고 기록하고있다. git의 복잡성 때문에 인기가
높아졌다

5
@boulder_ruby Linus Torvalds가 git의 제작자라는 것을 의미한다고 생각합니다. 그러나 Linus Pauling은 아마도 자식이 복잡하다는 데 동의 할 것이라고 생각합니다.
Suncat2000

215

나와 다른 사람들에게 가장 좋은 옵션은 Git 재설정 옵션입니다.

git reset --hard <commidId> && git clean -f

이것은 나에게 가장 좋은 옵션이었습니다! 간단하고 빠르며 효과적입니다!


** 참고 : ** 의견에서 언급했듯이 이전 커밋의 사본을 가진 다른 사람들과 지점을 공유하는 경우이 작업을 수행하지 마십시오

또한 의견에서, 덜 'ballzy'방법을 원한다면 사용할 수 있습니다.

git clean -i

37
필수 경고 : 이전 커밋 사본을 가진 다른 사람들과 지점을 공유하는 경우이 작업을 수행하지 마십시오. 이와 같이 하드 리셋을 사용하면 작업이 새로 재설정 된 브랜치와 다시 동기화되어야합니다. 하드 리셋으로 작업을 잃지 않고 커밋을 안전하게 되 돌리는 방법을 자세히 설명하는 솔루션 은이 답변을 참조하십시오 .

7
나는 @Cupcake의 경고를 두 번째로 ... 그 결과를 매우 잘 알고있다. 그러나 실제로 커밋이 히스토리에서 영원히 사라지게하는 것이 필요한 경우이 재설정 + 정리 메소드가이를 수행하므로 수정 된 브랜치 를 강제로 모든 원격으로 푸시해야합니다.
ashnazg

5
git clean -f 위험 위험
Tisch

2
로컬 사본의 헤드를 원하는 커밋으로 설정합니다. 그러나 리모컨 뒤에 있기 때문에 변경 사항을 푸시 할 수 없습니다. 그리고 원격에서 당기면 원격 지점의 최신 커밋이었던 곳으로 돌아갑니다. 푸시 된 로컬 사본에서 여러 커밋을 어떻게 (어디에서나) 완전히 말살합니까?
Ade

2
@Ade .. 당신은 git push -f깃발을 사용할 수 있습니다 . 그러나 조심, 그것은 리모컨을 무시할 것입니다 .. 당신이하고 싶은 일을 알고 있는지 확인하십시오 ..
Pogrindis

176

대답하기 전에 배경을 추가하고 이것이 무엇인지 설명해 봅시다 HEAD.

First of all what is HEAD?

HEAD단순히 현재 분기의 현재 커밋 (최신)에 대한 참조입니다. HEAD주어진 시간에 하나만있을 수 있습니다 (제외 git worktree).

의 내용은 HEAD에 저장 .git/HEAD되며 현재 커밋의 40 바이트 SHA-1을 포함합니다.


detached HEAD

HEAD히스토리에서 이전 커밋을 가리키는 최신 커밋-의미가 아닌 경우 호출 detached HEAD됩니다.

여기에 이미지 설명을 입력하십시오

명령 행에서 분기 이름 대신 SHA-1은 다음과 같습니다. 왜냐하면 HEAD현재 분기의 끝을 가리 키지 않기 때문 입니다.

여기에 이미지 설명을 입력하십시오


분리 된 HEAD에서 복구하는 방법에 대한 몇 가지 옵션 :


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

원하는 커밋을 가리키는 새 분기를 체크 아웃합니다. 이 명령은 주어진 커밋을 체크 아웃합니다.

이 시점에서 분기를 작성하고이 시점부터 작업을 시작할 수 있습니다.

# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# Create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

당신은 항상 사용할 수 있습니다 reflog. git reflog변경 사항을 표시 HEAD하고 원하는 참조 로그 항목을 체크 아웃하면 HEAD이 커밋으로 다시 설정됩니다 .

HEAD가 수정 될 때마다 reflog

git reflog
git checkout HEAD@{...}

원하는 커밋으로 돌아갑니다.

여기에 이미지 설명을 입력하십시오


git reset HEAD --hard <commit_id>

머리를 원하는 커밋으로 "이동"하십시오.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • 참고 : ( Git 2.7 ) 부터 도 사용할 수 있습니다 git rebase --no-autostash.

이 스키마는 어떤 명령이 무엇을 수행하는지 보여줍니다. 보시다시피을 reset && checkout수정하십시오 HEAD.

여기에 이미지 설명을 입력하십시오


6
에 대한 훌륭한 힌트 git reflog, 그것이 바로 내가 필요했던 것
smac89

4
아야! 이 모든 것이 굉장히 복잡해 보입니다 ... 프로세스에서 한 단계 뒤로 돌아가는 간단한 명령이 없습니까? 프로젝트의 버전 1.1에서 버전 1.0으로 돌아가는 것처럼? git stepback_one_commit 또는 ....
Kokodoko

이 : git reset HEAD^--hard`
CodeWizard

3
@Kokodoko 네, 그것은 끔찍하게 복잡합니다 ... 그리고 방금 시작한 사람들에게 배려 전문가가 얼마나 적은지에 대한 완벽한 예입니다. 여기에 내 답변과 내가 추천하는 책을 참조하십시오. Git은 직관적으로 선택할 수있는 것이 아닙니다. 그리고 CodeWizard가 그렇게하지 않았다는 것을 절대 확신 할 수 있습니다.
마이크 설치류

145

"커밋 해제", 마지막 커밋 메시지를 지우고 수정 된 파일을 다시 스테이징에 넣으려면 다음 명령을 사용하십시오.

git reset --soft HEAD~1
  • --soft커밋되지 않은 파일은 파일 --hard을 버리는 대신 작업 파일로 유지해야 함을 나타냅니다 .
  • HEAD~1마지막 커밋입니다. 3 커밋을 롤백하려면을 사용할 수 있습니다 HEAD~3. 특정 개정 번호로 롤백하려는 경우 SHA 해시를 사용하여이를 수행 할 수도 있습니다.

이것은 잘못된 것을 커밋하고 마지막 커밋을 취소하려는 경우에 매우 유용한 명령입니다.

출처 : http://nakkaya.com/2009/09/24/git-delete-last-commit/


3
이 작업은 부드럽고 부드럽게 진행됩니다. 작업을 진행하지 않은 경우 위험 부담
nilsM

124

다음 두 명령으로이를 수행 할 수 있습니다.

git reset --hard [previous Commit SHA id here]
git push origin [branch Name] -f

이전 Git 커밋을 제거합니다.

변경 사항을 유지하려면 다음을 사용할 수도 있습니다.

git reset --soft [previous Commit SHA id here]

그런 다음 변경 사항을 저장합니다.


2
나는이 게시물에 도달 할 때 까지이 게시물에서 1/2 개의 답변을 시도했습니다 .. 다른 모든 것들, 내 자식 구성은 푸시하려고 할 때 계속 오류가 발생했습니다. 이 답변은 효과가있었습니다. 감사!
Gene Bo

나를위한 한 가지 세부 사항은 내가 diffs를 잃어 버렸다는 것입니다. 나는 그것이 작동하지 않은 커밋에서 내가 한 일을 계속보고 싶었습니다.
Gene Bo

1
이것은 내가 잘못된 병합을 취소하는 유일한 방법이었습니다.이 경우 되돌리기가 작동하지 않았습니다. 감사!
Dave Cole

가장 좋은 답변입니다. 감사합니다
Imran Pollob

가장 좋은 답변입니다. 감사합니다.
user1394

114

Git에서 로컬 변경 사항을 되 돌리는 많은 방법을 시도했지만 최신 커밋 상태로 되돌리려는 경우 이것이 가장 효과가있는 것 같습니다.

git add . && git checkout master -f

간단한 설명:

  • 커밋을 만들지 git revert않습니다.
  • HEAD를 분리 git checkout <commithashcode>하지 않습니다.
  • 분기의 마지막 커밋 이후 모든 로컬 변경 사항을 무시하고 추가 된 모든 파일을 삭제합니다.
  • 분기 이름에서만 작동하므로 이런 방식으로 분기의 최신 커밋으로 되돌릴 수 있습니다.

위의 결과를 달성하는 훨씬 더 편리하고 간단한 방법을 찾았습니다.

git add . && git reset --hard HEAD

HEAD는 현재 지점의 최신 커밋을 가리 킵니다.

boulder_ruby가 제안한 코드 코드와 동일하지만 , 마지막 커밋 이후에 생성 된 모든 새 파일을 지우기 git add .전에 추가했습니다 git reset --hard HEAD.


83

좋아, Git의 이전 커밋으로 돌아가는 것은 매우 쉽습니다 ...

변경 사항 을 유지하지 않고 되 돌리십시오 .

git reset --hard <commit>

변경 사항 을 유지상태로 되 돌리십시오 .

git reset --soft <commit>

설명 :을 사용하여 git reset특정 상태로 재설정 할 수 있습니다. 위에서 본 것처럼 커밋 해시와 함께 사용하는 것이 일반적입니다.

당신이 차이가 두 플래그를 사용하고 볼 수 그러나 --soft--hard기본적으로 git reset사용하여 --soft항상 플래그를 사용하여 플래그를하지만 좋은 연습이다, 나는 각 플래그를 설명합니다 :


--부드러운

설명 된 기본 플래그는 제공 할 필요가 없으며 작업 트리를 변경하지 않지만 커밋 할 준비가 된 모든 변경된 파일을 추가하므로 커밋 상태로 돌아가 파일의 변경 사항이 스테이지되지 않습니다.


--단단한

이 플래그에주의하십시오. 작업 트리와 추적 된 파일의 모든 변경 사항을 재설정하면 모든 것이 사라집니다!


또한 Git을 사용하여 실제 작업에서 발생할 수있는 아래 이미지를 만들었습니다.

Git을 커밋으로 재설정


의 기본은 git reset있다 git reset --mixed, 없다 git reset --soft. git reset --mixed, --soft 및 --hard의 차이점은 무엇입니까?를 확인하십시오 . 일반 영어에서 "자식 재설정은"무엇을합니까?
Fabio는

70

마스터와 해당 지점에 대해 이야기하고 있다고 가정하면 (이것은 관심있는 작업 지점이 될 수 있습니다).

# Reset local master branch to November 3rd commit ID
git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50

# Reset remote master branch to November 3rd commit ID
git push -f origin 0d1d7fc32e5a947fbd92ee598033d85bfc445a50:master

블로그 게시물에서 답변을 찾았습니다 (더 이상 존재하지 않음).

이것은 팀의 다른 사람들이 이미 깃을 뽑아서 문제를 일으킬 수 있도록 재설정 및 원격 변경을 강제합니다. 변경 내역을 파괴하고 있는데, 이것이 사람들이 처음에 git을 사용하는 중요한 이유입니다.

재설정보다 되돌리기 (다른 답변 참조)를 사용하는 것이 좋습니다. 당신이 한 남자 팀이라면 아마 중요하지 않을 것입니다.


6
이 답변은 무수한 다른 사람들과 어떻게 다릅니 까?
Matsmath

운이 없었어. 나는 블로거에게 이메일을 보냈다.
markreyes


2
이 문제를 해결하는 방법에 대한 대부분의 다른 제안에서 푸시 구문이 누락되었습니다. 잘 했어.
jpa57

61

라는 이름의 텍스트 파일에 다음 커밋을 말해봐 ~/commits-to-revert.txt(I 사용 git log --pretty=oneline을 얻기 위해)

fe60adeba6436ed8f4cc5f5c0b20df7ac9d93219
0c27ecfdab3cbb08a448659aa61764ad80533a1b
f85007f35a23a7f29fa14b3b47c8b2ef3803d542
e9ec660ba9c06317888f901e3a5ad833d4963283
6a80768d44ccc2107ce410c4e28c7147b382cd8f
9cf6c21f5adfac3732c76c1194bbe6a330fb83e3
fff2336bf8690fbfb2b4890a96549dc58bf548a5
1f7082f3f52880cb49bc37c40531fc478823b4f5
e9b317d36a9d1db88bd34831a32de327244df36a
f6ea0e7208cf22fba17952fb162a01afb26de806
137a681351037a2204f088a8d8f0db6e1f9179ca

Bash 쉘 스크립트를 작성하여 각각을 되 돌리십시오.

#!/bin/bash
cd /path/to/working/copy
for i in `cat ~/commits-to-revert.txt`
do
    git revert $i --no-commit
done

파일 및 디렉토리 작성 및 삭제를 포함하여 모든 것을 이전 상태로 되돌리고 분기로 커밋하고 기록을 유지하지만 동일한 파일 구조로 되돌립니다. Git이없는 이유 git revert --to <hash>는 저 너머에 있습니다.


41
git revert HEAD~3마지막 3 개의 커밋을 제거 할 수 있습니다
Rod

25
@Rod-아니요, 맞지 않습니다. 이 명령은 HEAD의 세 번째 조부 인 커밋을 되돌립니다 (마지막 세 커밋이 아님).
kflorence

1
@kflorence 정보를 주셔서 감사합니다. 시겠습니까 git revert -n master~3..master~1일? ( kernel.org/pub/software/scm/git/docs/git-revert.html 참조 )
Rod

3
@로드-맞습니다. 확실하지 않은 구문입니까? 나는 항상 "복귀"하고 싶은 커밋을 확인한 다음보다 직관적으로 커밋했습니다.
kflorence

7
Git의 새로운 (또는 모든?) 버전에서 커밋 범위를 허용 하기 때문에 이와 같은 스크립트를 사용하는 것보다 지금이 작업을 수행 하는 훨씬 쉬운 방법이 있습니다 . 범위의 시작은 되돌리기에 포함되지 않습니다. git revert --no-commit <start>..<end>git revert

58

Jefromi의 솔루션에 대한 추가 대안

Jefromi의 솔루션 은 확실히 최고의 솔루션 이므로 반드시 사용해야합니다. 그러나 완벽을 기하기 위해 커밋을 되돌릴 때 사용할 수있는 다른 대안 솔루션을 보여주고 싶었습니다 ( 이전 커밋의 변경 사항을 취소하는 새 커밋을 만드는 것과 같은 의미입니다 git revert).

명확하게하기 위해, 이러한 대안이 커밋을 되돌리려하는 가장 좋은 방법은 아니다 , Jefromi의 솔루션입니다 ,하지만 난 당신이 또한 같은 일을 달성하기 위해 이러한 다른 방법을 사용할 수 있음을 지적하려는 git revert.

대안 1 : 하드 및 소프트 리셋

이것은 Git의 SHA 해시로 커밋으로 되 돌리는 Charles Bailey 솔루션의 약간 수정 된 버전 입니까? :

# Reset the index to the desired commit
git reset --hard <commit>

# Move the branch pointer back to the previous HEAD
git reset --soft HEAD@{1}

# Commit the changes
git commit -m "Revert to <commit>"

이것은 기본적으로 소프트 리셋이 이전 커밋 상태를 인덱스 / 스테이징 영역에서 단계적으로 남겨두고 커밋 할 수 있다는 사실을 사용하여 작동합니다.

대안 2 : 현재 트리를 삭제하고 새 트리로 교체

이 솔루션은 svick의 솔루션에서 기존 커밋Checkout하고 새로운 커밋으로 만듭니다 .

git rm -r .
git checkout <commit> .
git commit

대안 # 1과 마찬가지로 <commit>현재 작업 사본 의 상태를 재현합니다 . 이후에 추가 된 파일을 제거하지 않으므로 git rm먼저 수행해야합니다 .git checkout<commit>


대안 1에 관한 한 가지 간단한 질문 : 그렇게함으로써 커밋 사이를 느슨하게하지 않습니까?
Bogac

2
@Bogac-점은 파일 경로,이 경우 현재 디렉토리를 나타내므로 작업 복사본의 루트에서 실행한다고 가정합니다.
Tom

대답은 여러 차례 반복되지만 경고는 @Cascabel (@Jefromi)의 링크 된 솔루션 과 비교 하여 왜 이것이 최선의 방법아닌지를 추가 할 수 git revert HEAD~2..HEAD있습니다. 문제가 보이지 않습니다.
Joshua Goldberg

55

다음은 이전 커밋으로 돌아가고 커밋되지 않은 상태로 만들고 원하는 방식으로 수행 하는 훨씬 간단한 방법입니다.

git reset HEAD~1

따라서 커밋 ID 등이 필요하지 않습니다. :)


작동하지 않음,이 결과 후 git pull 발생 : error : 다음 파일에 대한 로컬 변경 사항을 merge로 덮어 씁니다.
malhal

1
@malhal 커밋되지 않은 변경 사항이 있기 때문입니다. 그것들을 숨기거나 재설정하면 오류없이 작동합니다.
Paul Walczewski

39

이전 커밋을 되돌리고 스테이징하기위한 명령 (핵심 Git의 일부는 아니지만 git-extras 패키지에 있음)이 있습니다.

git back

맨 페이지 , 그것은 또한 같은 수 있습니다 :

# Remove the latest three commits
git back 3

38

가장 좋은 방법은 다음과 같습니다.

git reset --hard <commidId> && git push --force

이것은 브랜치를 특정 커밋으로 재설정 한 다음 로컬에서와 동일한 커밋으로 원격 서버를 업로드합니다 (이는 특정 커밋 후 명령을 완전히 분리합니다)

조심 --force선택한 후 이후의 모든 커밋을 복구 할 수있는 옵션을 사용하지 않고 커밋 플래그 삭제합니다.


3
매력처럼 일했다!
Gaurav Gupta

귀하의 답변이 stackoverflow.com/a/37145089/1723886 , stackoverflow.com/a/27438379/1723886 또는 stackoverflow.com/a/48756719/1723886과 같이 아직 제공되지 않은 새로운 정보를 어떻게 제공하는지 알지 못했기 때문에 하향 투표했습니다 . 실제로 대부분의 커밋은 이미 git reset --hard를 언급하고 --force 또는 -f를 사용하여 푸시하는 것에 대해 더 많이 언급합니다.
Alex Telon

명확하고 간단한 하나의 명령으로 작업을 수행합니다. 내 대답이 마음에 들지 않으면 자유롭게 내릴 수 있습니다.
david.t_92

1
미래에 고려해야 할 또 다른 옵션은 이전 답변에 대한 편집을 제안하거나 '&&를 사용하여 한 줄로 수행 할 수도 있습니다'라는 주석을 추가하는 것입니다. 그렇게하면 모든 사람이 한 곳에서 개선 된 답변을 볼 수 있습니다.
Alex Telon

36

모든 변경 후,이 명령을 모두 누르면 다음을 사용해야합니다.

git push -f ...

뿐만 아니라 git push.


15
강제 경고 : 이전 커밋 사본을 가진 다른 사람들과 지점을 공유하는 경우이 작업을 수행하지 마십시오. 이와 같은 강제 푸시를 사용하면 작업을 다시 동기화해야합니다. 강제 푸시로 작업을 잃지 않고 커밋을 안전하게 되 돌리는 방법을 자세히 설명하는 솔루션 은이 답변을 참조하십시오 .

3
때때로 이것은 당신이 원하는 것입니다. 예 : 커밋하고 여러 가지 커밋을 잘못된 분기 (지점 A)로 푸시했습니다. 분기 B로 체리 피킹 후 분기 A에서 이러한 커밋을 제거하고 싶습니다. 분기 A와 B가 병합되면 나중에 되돌리기가 적용되기 때문에 되돌리고 싶지 않습니다. 분기 A에서 재설정 --hard <commitId> 다음에 강제 푸시를 수행하면 분기 B에서 커밋을 유지하면서 분기에서 이러한 커밋을 제거합니다. 분기 A에서 개발중인 사람이 아무도 없기 때문에이 커밋을 피할 수 있습니다.
Doug R

감사! 원격 지점을 로컬 지점과 일치시키는 방법을 알 수 없었습니다. 강제 푸시해야했습니다.
Mido

32

이러한 모든 초기 단계를 직접 완료하고 Git 리포지토리로 되돌릴 수 있습니다.

  1. git pull --all명령을 사용하여 Bitbucket에서 최신 버전의 저장소를 가져옵니다 .

  2. -n 4터미널에서 Git log 명령을 실행하십시오 . 다음 -n의 숫자는 로컬 히스토리에서 가장 최근의 커밋부터 시작하여 로그의 커밋 수를 결정합니다.

    $ git log -n 4
    
  3. git reset --hard HEAD~N여기서 N은 헤드를 다시 가져 오려는 커밋 수를 사용하여 저장소 히스토리 헤드를 재설정하십시오 . 다음 예제에서 헤드는 하나의 커밋을 저장소 히스토리의 마지막 커밋으로 다시 설정합니다.

  4. 변경 사항을 git push --force강제로 사용하여 변경 사항을 Git 저장소 로 푸시하십시오.

Git 리포지토리를 이전 커밋에 적용하려는 경우 :

git pull --all
git reset --hard HEAD~1
git push --force


28

필요한 커밋을 선택하고 확인하십시오.

git show HEAD
git show HEAD~1
git show HEAD~2 

필요한 커밋을 얻을 때까지. HEAD가이를 가리 키도록하려면

git reset --hard HEAD~1

또는 git reset --hard HEAD~2무엇이든.


7
필수 경고 : 이전 커밋 사본을 가진 다른 사람들과 지점을 공유하는 경우이 작업을 수행하지 마십시오. 이와 같이 하드 리셋을 사용하면 작업이 새로 재설정 된 브랜치와 다시 동기화되어야합니다. 하드 리셋으로 작업을 잃지 않고 커밋을 안전하게 되 돌리는 방법을 자세히 설명하는 솔루션 은이 답변을 참조하십시오 .

2
또한 명확하게 git show HEAD하기 위해서는을 사용하는 것과 같습니다 git log HEAD -1.

25

상황이 긴급한 상황이고 프로젝트가 "my project"와 같은 디렉토리에 있다고 가정하면 질문자가 빠르고 더러운 방식으로 요청한 것을 수행하려고합니다 .


QUICK AND DIRTY : 상황에 따라 빠르고 더러워진 것이 실제로 매우 좋습니다. 여기에서 내 솔루션입니다 않습니다 NOT 파일이 작업 디렉토리에 비가 역적 당신이 가지고있는 파일을 대체하는 것은 거기에있는 어려워 영리하고 들렸 강력한 자식 명령을 사용하여 .git / 디렉토리 아래에 숨어 자식 저장소의 깊이에서 추출 / 최대 운반 많은. 당신은 비참한 상황 인 것처럼 보이는 것을 회복하기 위해 그러한 심해 다이빙을해서는 안되며, 충분한 전문 지식 없이는 그렇게하지 않으면 치명적일 수 있습니다 .


  1. 전체 디렉토리를 복사하고 "my project-copy"와 같은 다른 디렉토리로 호출하십시오. git 저장소 ( "repo") 파일이 "my project"디렉토리 ( ".git"디렉토리 아래의 기본 위치)에 있다고 가정하면 작업 파일과 repo 파일이 모두 복사 된 것입니다.

  2. "내 프로젝트"디렉토리에서이를 수행하십시오.

    .../my project $ git reset --hard [first-4-letters&numbers-of-commit's-SHA]
    

이렇게하면 "내 프로젝트"아래의 레포 상태가 커밋 할 때의 상태로 돌아갑니다 ( "커밋"은 작업 파일의 스냅 샷을 의미합니다). 그 이후의 모든 커밋은 "내 프로젝트"에서 영원히 잃어 버릴 것입니다 ...하지만 ... /. git 아래의 파일을 포함하여 모든 파일 을 복사했기 때문에 여전히 레포지토리의 "내 프로젝트-복사"에 표시 됩니다. /.

그런 다음 시스템에 두 가지 버전이 있습니다. 이전 커밋에서 관심있는 파일 등을 검사하거나 복사 또는 수정할 수 있습니다. 복원 된 커밋이 아무데도 진행되지 않은 이후에 새 작업을 결정한 경우 "내 프로젝트-복사"에서 파일을 완전히 버릴 수 있습니다.

검색된 커밋이 있기 때문에 실제로 작업을 버리지 않고 프로젝트의 상태를 계속 유지하려면 분명한 것은 디렉토리의 이름을 다시 바꾸는 것입니다. 검색된 커밋이 포함 된 프로젝트를 삭제하거나 임시 이름을 지정하고 " 내 프로젝트- "디렉토리를"내 프로젝트 "로 다시 복사하십시오. 그런 다음 여기에 다른 답변 중 일부를 이해하려고 시도하고 아마도 곧 다른 커밋을 수행하십시오.

힘내는 훌륭한 창조물이지만 아무도 "즉시 집어들"수는 없다. 너무 멀리 설명하려고 시도하는 사람들 은 다른 VCS [Version Control Systems]에 대한 사전 지식을 너무 자주 생각하고 너무 깊이 파고 들었다. "체크 아웃"이라는 용어를 교환 할 수있는 용어와 같은 다른 범죄를 저지르는 경우도 있습니다.

스트레스를 많이 받으려면 내 흉터에서 배운다. Git에 관한 책을 읽어야한다 . "Git을 이용한 버전 관리"를 추천한다 . 나중에보다 빨리하십시오. 그렇게한다면 Git의 복잡한 부분이 분기 된 다음 다시 생성된다는 점을 명심해야한다. 어떤 책에서든 그 부분을 건너 뛸 수있다. 당신의 질문에서 사람들이 왜 당신을 과학으로 눈을 멀게해야하는 이유없습니다 .

특히, 예를 들어 이것이 절박한 상황이고 Git의 초보자라면!

추신 : 한 가지 다른 생각 : 실제로 파일을 가지고있는 디렉토리가 아닌 다른 디렉토리에 Git 저장소를 유지하는 것은 실제로 간단합니다. 이것은 위의 빠르고 더러운 솔루션을 사용하여 전체 Git 저장소를 복사하지 않아도됨을 의미합니다. --separate-git-dir 여기를 사용하여 Fryer의 답변을 참조 하십시오 . 그러나 경고 : 복사하지 않는 "별도의 디렉토리"저장소가 있고 강제 재설정을 수행하는 경우, 재설정 커밋 이후의 모든 버전은 반드시 필요한 경우를 제외하고는 영원히 손실됩니다. 저장소를 정기적으로 백업하는 것이 좋습니다 (예 : 다른 곳 에서 클라우드 (예 : Google 드라이브 )).

이 "클라우드에 백업"이라는 주제에서 다음 단계는 GitHub 또는 (나의 관점에서 더 나은) GitLab 계정을 개설하는 것입니다 (물론) . 그런 다음 정기적으로 git pushCloud 저장소를 "적절하게"최신 명령으로 만들 수 있습니다. 그러나 다시 말하지만, 이것에 대해 너무 빨리 이야기 할 수 있습니다.


23

이것은 최근 커밋으로 직접 재설정하는 또 다른 방법입니다.

git stash
git stash clear

마지막 커밋 이후에 수행 한 모든 변경 사항을 직접 지 웁니다.

추신 : 약간의 문제가 있습니다. 또한 최근에 저장된 숨김 변경 사항을 모두 삭제합니다. 나는 대부분의 경우 중요하지 않다고 생각합니다.


참고 : 색인에 추가되지 않은 새 파일은 보관되지 않습니다. 너무 추가했거나 수동으로 삭제했습니다.
andreyro

왜 오면 숨겨 지나요? 비 솔루션 일뿐 아니라 실제로는 해 롭습니다. 질문의 첫 문장을 읽으면 숨김 솔루션이 즉시 무효화됩니다 (LAST 커밋으로 재설정하는 데만 유용 할 수 있음).
RomainValeri

22

우발적 인 변경으로 코더의 디렉토리를 완전히 정리하기 위해 다음을 사용했습니다.

git add -A .
git reset --hard HEAD

그냥 git reset --hard HEAD수정을 제거하지만, 그것은 "새로운"파일을 제거하지 않습니다. 그들의 경우 그들은 실수로 중요한 폴더를 임의로 어딘가로 끌었고, 모든 파일은 Git에 의해 새로운 것으로 취급되었으므로 reset --hard그것을 고치지 않았습니다. git add -A .미리 실행하면 git으로 명시 적으로 모두 추적하여 재설정으로 지워집니다.


21

이전 커밋에서 HEAD로 변경 사항을 유지하고 이전 커밋으로 이동하려면 다음을 수행하십시오.

git reset <SHA>

이전 커밋에서 HEAD 로의 변경이 필요하지 않고 모든 변경 사항을 버릴 경우 다음을 수행하십시오.

git reset --hard <SHA>


18

되돌리기는 커밋을 롤백하는 명령입니다.

git revert <commit1> <commit2> 

견본:

git revert 2h3h23233

아래와 같이 HEAD로부터 범위를 취할 수 있습니다. 여기 1은 "마지막 커밋 되돌리기"라고 말합니다.

git revert HEAD~1..HEAD

그리고 나서 git push


14

원하는 커밋으로 재설정하십시오-

git reset <COMMIT_ID>

(COMMIT_ID 사용을 확인하기 위해 git log )

변경된 모든 파일이 추가되지 않은 상태로 재설정됩니다.

이제 checkout추가되지 않은 모든 파일을

git checkout .

검사 git log 변경 사항을 확인합니다.

최신 정보

당신이 하나만 가지고 당신의 레포에 헌신 한다면 , 시도하십시오

git update-ref -d HEAD


13

커밋이 원격으로 푸시되면 커밋을 제거해야합니다. 당신의 브랜치가 개발 되었다고 가정 하고 그것이 원점 으로 밀려 들어 오게하겠습니다 .

먼저 origin 에서 develop 을 제거해야합니다 .

git push origin :develop (note the colon)

그런 다음 커밋 해시가 EFGHIJK라고 가정하고 원하는 상태로 개발해야합니다.

git reset --hard EFGHIJK

마지막으로 다시 개발을 푸시 하십시오.

git push origin develop

13

주의! 사용자가 잘못된 커밋을 잘못 입력 한 경우이 명령으로 커밋 기록이 손실 될 수 있습니다. 실수를 할 경우를 대비하여 조금 더 안전하기 때문에 항상 git을 추가 백업하십시오. :)

비슷한 문제가 있었고 이전 커밋으로 되돌리려 고했습니다. 내 경우에는 최신 커밋을 유지하는 데 관심이 없었으므로Hard .

이것이 내가 한 방법입니다.

git reset --hard CommitId && git clean -f

이것은 로컬 리포지토리를 되돌리고 사용 후 git push -f원격 리포지토리를 업데이트합니다.

git push -f

13

에서 GitKraken 당신은이 작업을 수행 할 수 있습니다

  1. 재설정하려는 커밋을 마우스 오른쪽 버튼으로 클릭하고 다음을 선택하십시오. 이 커밋 / 하드로 재설정 :

    여기에 이미지 설명을 입력하십시오

  2. 커밋을 다시 마우스 오른쪽 버튼으로 클릭하고 현재 분기 이름 / 푸시 :

    여기에 이미지 설명을 입력하십시오

  3. 강제 푸시를 클릭하십시오 .

    여기에 이미지 설명을 입력하십시오

Obs. : 하드 재설정 후 모든 커밋 히스토리가 유실되고이 조치는 되돌릴 수 없으므로주의해야합니다. 무엇을하고 있는지 확인해야합니다.


11

마지막 커밋에서 일부 오류를 수정하려면 git commit --amend 명령을 사용하는 것이 좋습니다 . 마지막 커밋이 참조에 의해 지시되지 않으면 마지막 커밋과 동일한 부모로 커밋을 생성하므로 트릭을 수행합니다. 마지막 커밋에 대한 참조가 없으면 단순히 삭제되고이 커밋이 마지막 커밋이됩니다. 이것은 커밋을 되 돌리지 않고 커밋을 수정하는 좋은 방법입니다. 그러나 자체 제한이 있습니다.

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