1 커밋으로 로컬 및 원격 git 저장소 롤백


188

나는이 주제에 대한 비슷한 게시물을 읽었으며 내 인생에서는이를 올바르게 수행하는 방법을 알 수 없습니다.

나는 원하지 않는 약 1000 개의 파일을 체크인했으며, 1by1을 거치지 않고 저장소에서 모두 제거하지 않아도됩니다.

  • 원격 master지사가 있습니다.
  • 현지 master지사가 있습니다.

그들은 모두 같은 개정판에 있습니다.

1 커밋으로 리모컨을 롤백하고 싶습니다.

내 역사는 master입니다 A--B--C--D--E.
내 지역을로 롤백하고 싶습니다 D.
그런 다음 원격으로 푸시하여 현재 해시가 원격 및 로컬 모두 D가되도록하십시오.

이 작업을 수행하는 데 문제가 있습니다.
Git Tower를 사용하고 있지만 커맨드 라인에 익숙합니다. 어떤 도움?

업데이트 : 아래에 큰 의견. 특히 리포지토리가 다른 사용자와 공유되는 경우 재설정을 사용하지 않는 것이 좋습니다. 하드 리셋을 사용하지 않고 이전 커밋의 변경 사항을 취소하는 가장 좋은 방법은 무엇입니까 ? 방법이 있습니까?


"하드 재설정을 사용하지 않고 이전 커밋의 변경 사항을 취소하십시오"라는 답변을 업데이트했습니다.
VonC

3
git revert하드 리셋없이 사용자를 방해하지 않고 사용하십시오 .
user562374


리모컨을 롤백하는 것은 바람직하지 않지만, 원하는 경우 수행하십시오. 이를 수행하는 방법은 수백 가지가 있지만 결과는 서버 측에서 동일합니다.
FelipeC 2016 년

답변:


307

아무도 원격 저장소를 아직 가져 오지 않은 경우 분기 HEAD를 변경하고 해당 원격 저장소로 강제 푸시 할 수 있습니다.

git reset --hard HEAD^ 
git push -f 

(또는 원격 리포지토리에 직접 액세스 할 수 있는 경우 베어 리포지토리 인 경우에도 HEAD 참조를 변경할 수 있음 )

아래의 의견 에서 alien-technology 가 언급 한대로 Windows (CMD 세션)에서는 다음이 필요합니다 .^^

git reset --hard HEAD^^
git push -f 

2011 업데이트 :
사용 git push --force-with-lease( 내가 여기에 제시하는 것이 힘내 1.8.5 2013 년에 도입은) 안전합니다.

그림은 Schwern답변 을 참조하십시오 .


누군가 이미 저장소를 가져간 경우 어떻게됩니까? 그러면 어떻게해야합니까?

그런 다음 역사를 다시 쓰지 않는 것을 제안합니다.

  • git revert 로컬로 마지막 커밋 (이전 커밋과 반대로 새로운 커밋 만들기)
  • 에서 생성 한 '되돌리기'를 누릅니다 git revert.

1
누군가 이미 저장소를 가져간 경우 어떻게합니까? 그러면 어떻게해야합니까?
Jamis Charles

1
@gwho는 분기를 작성합니까? 아니요, 지점의 헤드를 이동하지만 여전히 같은 지점에 있습니다. 그러나 푸시는 더 이상 빨리 감기되지 않으므로 해당 푸시를 강제로 수행해야합니다.
VonC

1
누군가가 repo를 뽑았는지 알 수있는 방법이 있습니까?
Pinkerton

4
Windows에서 ^ 문자는 줄 연속 및 문자를 이스케이프 처리하는 데 사용됩니다. git reset --hard HEAD ^^
Alien Technology

1
@AlienTechnology Windows 10에서 Powershell을 사용 하면 마지막 커밋 을 입력 reset --hard HEAD^하고 reset --hard HEAD^^재설정 하지 않아도 됩니다.
Gaspacchio

58

로컬 브랜치를 하나의 수정본으로 다시 설정하십시오 ( HEAD^하나의 수정본을 다시 의미).

git reset --hard HEAD^

변경 사항을 원점으로 푸시하십시오.

git push --force

그렇지 않으면 git이 뒤에 있다는 것을 인식하기 때문에 강제로 밀어야합니다. origin 한 번의 커밋으로 하고 아무것도 변하지 합니다.

그것을 사용하면 --forcegit HEAD은 원격 저장소에서 사전에 상관없이 덮어 쓰라고 지시 합니다.


1
나는 이것을 vert에서 매우 다른 의미를 가진 특정 용어이기 때문에 이것을 되돌리기라고 제안하지 않을 것이다.
Cascabel

@Jefromi : 힌트 주셔서 감사합니다. 편집했습니다.
eckes

좋은 대답입니다. 리포지토리가 다른 사용자와 공유되는 경우 재설정을 사용하는 것이 부분적으로 권장되지 않는 것 같습니다. 이전 커밋의 모든 변경 사항을 취소하는 더 깨끗한 방법이 있습니까?
Jamis Charles

조심해! 커밋되지 않은 변경 사항 또는 잃어버린 변경 사항을 보관하십시오
Nosov Pavel

멋지다. 따라서 이것은 우리가 할 때 git push origin master로컬 지점이 적어도 한 번 커밋보다 앞서서 Git이 원격에서 새 커밋을 만들 수 있음을 의미 합니까? 또한 후자는 원격 저장소의 머리가 가리키는 것과 실질적으로 달라야합니까?
MadPhysicist

18

마지막 커밋 청취를 되돌리려면 다음을 수행하십시오.

1 단계:

메시지로 지역 커밋 확인

$ git log

2 단계:

로컬 브랜치 (또는 마스터)에서 변경 사항을 재설정하지 않고 마지막 커밋 제거

$ git reset HEAD^

또는 마지막 커밋 파일 및 업데이트 수신을 원하지 않는 경우

$ git reset HEAD^ --hard

3 단계 :

파일과 코드를 업데이트 할 수 있으며 이전 커밋을 삭제하도록 강제로 다시 푸시해야합니다. 새로운 커밋을 유지합니다.

$ git push origin branch -f

그게 다야!


그건 아니에요 복귀 는 하나를 교체하는 것, 커밋. 일반적인 용어를 잘못 사용하여 git 초보자를 혼동하지 마십시오.
Suncat2000

7

다음 명령을 입력하면 git commit history를 볼 수 있습니다-

$ 자식 로그

특정 분기의 히스토리가 commit_A, commit_B, commit_C, commit_D와 같다고 가정 해 봅시다. 여기서 commit_D는 마지막 커밋이고 HEAD가 남아있는 곳입니다. 이제 로컬 및 원격에서 마지막 커밋을 제거하려면 다음을 수행해야합니다.

1 단계 :-로 로컬에서 마지막 커밋 제거

$ git reset-하드 헤드 ~

커밋 HEAD가 commit_C로 변경됩니다.

2 단계 : 새 HEAD 커밋에 대한 변경 사항을 원격으로 푸시

$ git push origin + HEAD

이 명령은 원격에서 마지막 커밋을 삭제합니다.

PS이 명령은 Mac OSX에서 테스트되었으며 다른 운영 체제에서도 작동합니다 (다른 OS에 대해서는 주장하지 않음).



3

보다 안전한 업데이트 된 버전의 절차가 있습니다.

git reset --hard HEAD^ 
git push --force-with-lease

git push -f원격 저장소를 자신의 변경 사항으로 무차별 적으로 대체합니다. 다른 사람이 변경 사항을 푸시하면 손실됩니다. git push --force-with-lease리포지토리가 예상 대로만 리베이스를 푸시합니다. 다른 사람이 이미 푸시 한 경우 푸시에 실패합니다.

유해한 것으로 간주되는 힘을 참조하십시오 . git의 임대에 대한 이해 .

이 별칭을로 지정하는 것이 좋습니다 repush = push --force-with-lease.

누군가 이미 저장소를 가져간 경우 어떻게됩니까? 그러면 어떻게해야합니까?

그들에게 알려주십시오 git pull --rebase=merges. 대신의 git fetch origingit merge origin/master그것을 의지 git fetch origin하고 git rebase -r origin/master. 이것은 master새로운 rebased 위에 로컬 변경 사항을 다시 작성합니다 origin/master.-r병합 한 내용을 보존합니다.

이것을 기본 동작으로 설정하는 것이 좋습니다. 안전하고 다른 사람의 리베이스를 처리하고 불필요한 병합을 줄입니다.

[pull]
        rebase = merges

1
동의하고 찬성했습니다. 국방을 위해 2011이전 답변--force-with-lease옵션 도입 2 년 전에 작성 되었습니다 .
VonC

나는 이미 (어제) 그렇게 생각했습니다 : stackoverflow.com/posts/4647362/revisions
VonC



0

방금 원격에서 커밋을 지우고 커밋 기록을 지우고 싶었습니다. 다음은 매력처럼 작동했습니다.

git reset --hard HEAD^ 
git push -f 

그러나 "다음"은 위의 답변 과 어떻게 다른 가요?
VonC

0

헤드를 재설정하고 이전 커밋으로 되 돌리는 방법은

$ git reset HEAD^ --hard
$ git push <branchname> -f

그러나 때로는 원격 지점에서 허용되지 않을 수 있습니다.

To ssh:<git repo>
 ! [rejected]        develop -> develop (non-fast-forward)
error: failed to push some refs to 'ssh:<git repo>'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

다른 방법은

git revert HEAD
git push <remote branch>

이것은 잘 작동합니다.

참고 : git push -f <force>실패한 경우 기억 하고 되 돌리십시오. 를 수행 git pull원격 및 로컬 동기화에 다음 시도 그래서 전에 git revert.
확인 git log확인 원격 있도록 지역은 같은 SHA1으로 커밋의 같은 지점에있다 ..

git revert 
A --> B --> C -->D
A--> B --> C --> D --> ^D(taking out the changes and committing reverted diffs)

0

로컬 마스터

git reflog
-- this will list all last commit
  e.g Head@{0} -- wrong push
      Head@{1} -- correct push  
git checkout Head@{1} .
  -- this will reset your last modified files

git status 
git commit -m "reverted to last best"
git push origin/master

다른 사람이 당겼는지 걱정하지 않아도됩니다.

끝난!


0

로컬 저장소를 엉망으로 만들지 않고 원격 저장소에서 마지막 커밋을 제거하려는 경우 하나의 라이너가 있습니다.

git push origin +origin/master~:master

이것은 다음 구문을 사용합니다.

git push <remote> <refspec>

여기에, <remote>이다 origin, 그리고 <refspec>다음과 같은 구조를 가지고 :

+origin/master~:master

자세한 내용은에서 확인할 수 있습니다 git-push(1). 앞의 내용 +은 "이 기준을 강제로 푸시"를 의미하고 다른 부분은 " 원격 origin/master~에서 master(원격 origin)"을 의미합니다. origin/master~마지막 커밋이 무엇인지 알기 어렵지 않습니다 origin/master.


0

나를 위해이 두 가지 명령을 수행합니다.

git checkout commit_id
git push origin +name_of_branch

0

당신은 또한 이것을 할 수 있습니다 :

git reset --hard <commit-hash>
git push -f origin master

최신 나쁜 커밋을 얻은 다른 모든 사람이 재설정하도록하십시오.

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