힘내-푸시 된 커밋 취소


608

로컬 저장소 (개발) 및 서버 프로젝트 (prod)와 동기화 된 원격 저장소에 프로젝트가 있습니다. 커밋 된 변경 사항을 이미 원격으로 푸시하고 서버에서 가져 왔습니다. 이제 변경 사항을 취소하고 싶습니다. 그래서 git checkout변경 사항을 커밋하고 새로운 변경 사항을 커밋 할 수는 있지만 다시 원격으로 푸시하는 데 문제가 있다고 생각합니다. 어떻게 진행해야합니까?


답변:


735

다음을 사용하여 개별 커밋을 되돌릴 수 있습니다.

git revert <commit_hash>

지정한 커밋의 변경 사항을 되 돌리는 새로운 커밋이 생성됩니다. 특정 커밋 만 되돌리고 그 이후에는 커밋하지 않습니다. 커밋 범위를 되돌리려면 다음과 같이하십시오.

git revert <oldest_commit_hash>..<latest_commit_hash>

지정된 커밋 사이에서 커밋을 포함하여 커밋을 되돌립니다.

상기 봐 자식-되돌리기 man 페이지 에 대한 자세한 내용은 git revert명령. 또한 볼 이 답변 커밋을 되 돌리는에 대한 자세한 내용은.


22
다시 말해 <oldest_commit_hash>;)로 되돌아갑니다.
David

7
@mr_jigsaw 사용git log
gitaarik

2
git 문서에서 revert 명령은 첫 번째 커밋과 마지막 커밋 사이의 커밋을 되돌립니다 (첫 번째와 마지막 포함).
Onur Demir

4
@aod가 맞습니다.이 답변을 업데이트해야합니다. 되돌리기에 대한 현재 git API가 되돌리기 <oldest_commit_hash>목록에 포함되었습니다
JHixson

4
git 2.17.2 revert <old> ... <new>는 old는 포함하지 않지만 <new>는 포함
chingis

353

"실행 취소"의 흔적을 남기지 않는 솔루션.

참고 : 누군가가 이미 변경 사항을 가져간 경우이 작업을 수행하지 마십시오 (개인 저장소에서만 사용함)

하다:

git reset <previous label or sha1>

이것은 모든 업데이트를 로컬에서 다시 체크 아웃합니다 (git 상태는 모든 업데이트 된 파일을 나열합니다)

그런 다음 "작업을 수행"하고 변경 사항을 다시 커밋합니다 (참고 :이 단계는 선택 사항입니다)

git commit -am "blabla"

이 시점에서 로컬 트리가 리모컨과 다릅니다

git push -f <remote-name> <branch-name>

원격이 푸시를 고려하고 이전 푸시를 제거하도록 강제합니다 (원격 이름 및 분기 이름을 지정하는 것은 필수는 아니지만 업데이트 플래그로 모든 분기를 업데이트하지 않는 것이 좋습니다).

!! 조심 일부 태그는 여전히 삭제 커밋을 가리킬 수 있습니다! 원격 태그 삭제 방법


4
-a 추적 된 모든 파일이 커밋됩니다. -m 커밋 메시지가 다음과 같습니다.
jo_

3
정확히 내가 찾은 것. 누군가 잘못된 커밋을 한 후 다시 푸시하고 되돌 렸습니다. 이 때문에 브랜치를 병합 할 수 없었고 리포지토리를 다시 올바른 상태로 만들고 싶었습니다 (어쨌든 결함이있는 기록에서 커밋을 제거)
byemute

1
어떤 "이전 레이블 또는 sha1"을 사용해야합니까?. 마지막 "올바른"항목 또는 그 이전의 항목을 입력하고 마지막으로 올바른 변경 사항을 다시 수행해야합니까?
elysch


1
정확히 내가 필요한 것. 실수로 지점을 마스터로 밀었습니다. 결과적으로 모든 커밋 기록 중에 많은 쓰레기 커밋이있었습니다. 방금 git push -f마지막 커밋과 원격 기록을 정리했습니다! 감사!
Anton Rybalko

193

이 경우 내가하는 일은 :

  • 서버에서 커서를 마지막으로 알려진 올바른 커밋으로 다시 이동하십시오.

    git push -f origin <last_known_good_commit>:<branch_name>
    
  • 로컬에서 동일한 작업을 수행하십시오.

    git reset --hard <last_known_good_commit>
    #         ^^^^^^
    #         optional
    



my_new_branch이 목적으로 만든 지점에 대한 전체 예를 참조하십시오 .

$ git branch
my_new_branch

이것은 몇 가지 물건을 추가 한 후의 최근 역사입니다 myfile.py.

$ git log
commit 80143bcaaca77963a47c211a9cbe664d5448d546
Author: me
Date:   Wed Mar 23 12:48:03 2016 +0100

    Adding new stuff in myfile.py

commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

이미 푸시 된 마지막 커밋을 제거하고 싶습니다.

$ git push -f origin b4zad078237fa48746a4feb6517fa409f6bf238e:my_new_branch
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:me/myrepo.git
 + 80143bc...b4zad07 b4zad078237fa48746a4feb6517fa409f6bf238e -> my_new_branch (forced update)

좋은! 이제 커밋 ( myfile.py) 에서 변경된 파일이 "커밋 준비되지 않음"에 표시됩니다.

$ git status
On branch my_new_branch
Your branch is up-to-date with 'origin/my_new_branch'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   myfile.py

no changes added to commit (use "git add" and/or "git commit -a")

이러한 변경 사항을 원하지 않으므로 커서를 로컬로 다시 이동하면됩니다.

$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit

이제 HEAD는 로컬 및 원격 모두에서 이전 커밋에 있습니다.

$ git log
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

10
이것이 정답입니다! 이 새로운 것을 오늘 : 배운 내 경우 덕분에 할 수 O를 필요로 정확히입니다
Egli 베 세라

2
이것이 정답입니다! 푸시 (!) 커밋에 관한 것입니다!
powtac

3
당신이 (당신이 그들을 밀어 적이 것처럼) 진정으로 되돌리기 변경하려는 경우이 있다 정답.
Jacob

1
완벽한 답변. 예상대로 잘 작동했습니다!
RafiAlhamd

2
누군가이 사람에게 맥주를 사요!
Jay Nebhwani

72

git 명령 행을 통해 아래 주어진 단계를 수행하면 Git Commit BOTH를 로컬 및 원격으로 REVERT (또는 DELETE 라고도 함) 할 수 있습니다 .

되돌리려는 커밋 ID를 보려면 다음 명령을 실행하십시오.

git log --oneline --decorate --graph

다음과 같은 스크린 샷이 나타납니다. 여기에 이미지 설명을 입력하십시오

웹 인터페이스를 통해 원격을 확인 하면 아래 표시된 것과 동일하다는 것을 알 수 있습니다.

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

현재 스크린 샷에 따라 커밋 ID e110322에 있지만 030bbf6 BOTH LOCALLY 및 REMOTELY 로 되돌리고 싶습니다 .

다음 단계를 수행하여 로컬로 커밋 + 원격 커밋 삭제


ID 030bbf6 을 커밋하기 위해 로컬로 처음 되돌리기

git reset --hard 030bbf6

뒤에

git clean -f -d

이 두 명령은 아래 그림과 같이 스테이지 030bbf6 을 커밋하도록 강제 재설정합니다.

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

이제 git status를 실행하면 아래와 같이 원격 브랜치에서 두 번 커밋되었음을 알 수 있습니다 여기에 이미지 설명을 입력하십시오

다음을 실행하여 색인을 업데이트하십시오 (업데이트가있는 경우). 모든 개발자에게 주 원격 지점에서 끌어 오기 요청을 수락하지 않도록 요청하는 것이 좋습니다.

git fetch --all

당신이 그것으로 완료되면 아래에 표시된 것처럼 분기 앞의 + 기호를 사용 하여이 커밋을 강제푸시 해야 합니다. 나는 여기에서 마스터 브랜치 로 사용 했습니다.

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

git push -u origin +master

이제 원격의 웹 인터페이스가 표시되면 커밋도 되돌려집니다.

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


61

푸시 된 커밋을 제거합니다.

git reset --hard 'xxxxx'

git clean -f -d

git push -f

7
이 메소드는 커밋을 삭제하기 위해 히스토리를 올바르게 다시 작성합니다. 최고
Jesse Reza Khorasanee

2
이 답변은 el magnifeco입니다!
truthadjustr

3
답변 사랑, 감사합니다 :)
Dzenis H.

1
명확하게하기 위해 (확실하지 않았습니다) : 커밋은 작업 후 현재 커밋이됩니다. 마지막으로 삭제할 것이 아닙니다.
Maik639

21
git revert HEAD -m 1

위의 코드 라인에서. "마지막 논쟁은"

  • 1-한 커밋을 되돌립니다.

  • 2-마지막 두 커밋을 되돌립니다.

  • n-마지막 n 커밋을 되돌립니다.

원격에 영향을 미치려면이 명령을 누른 후 밀어야합니다. 되돌릴 커밋 범위 지정과 같은 다른 옵션이 있습니다. 이것은 옵션 중 하나입니다.


나중에 사용 git commit -am "COMMIT_MESSAGE"git push또는git push -f


8
이는 사실이 아닙니다. -m 매개 변수는 되돌릴 상위 수를 지정합니다 (일반적으로 수신 변경 "그들의"변경을 되돌리려는 경우 1, 병합 된 변경의 경우 2, "우리의"-병합 2의 경우) 커밋). 커밋 범위를 되돌리려면 커밋 범위를 되돌리려면 다음을 사용하십시오.git revert ref1..ref2
Null Reference

1
원하는 효과가 없었습니다
Sam Tuke

2

2020 간단한 방법 :

git reset <commit_hash>

(최종 유지하려는 커밋의 해시).

커밋되지 않은 변경 사항을 로컬에 유지합니다.

다시 푸시하려면 다음을 수행해야합니다.

git push -f

0

여기 내 방법이 있습니다.

지점 이름이이라고 가정 해 봅시다 develop.

# Create a new temp branch based on one history commit
git checkout <last_known_good_commit_hash>
git checkout -b develop-temp

# Delete the original develop branch and 
# create a new branch with the same name based on the develop-temp branch
git branch -D develop
git checkout -b develop

# Force update this new branch
git push -f origin develop

# Remove the temp branch
git branch -D develop-temp

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