특정 커밋으로 원격 재설정


709

commit 후 수행 된 모든 변경 사항을 삭제하고 싶습니다 <commit-hash>. 그래서 나는했다 :

git reset --hard <commit-hash>

이제 리모컨으로도 똑같이하고 싶습니다. 어떻게해야합니까? 나는 몇 가지 커밋 (및 푸시)을 수행 <commit-hash>했으며 모두 버리고 싶습니다. 뭔가 갔다가 정말 길을 잘못 난 이미보다 더 나쁘게 만들고 싶어하지 않습니다. ; (

나는 기본적으로 내 되감기 할 origin/master에를<commit-hash>


3
origin/master다른 사용자가 귀하 를 끌어 당기지 않았습니까? 공용 (즉, 로컬이 아닌) 리포지토리의 기록 변경은 항상 피해야합니다.
vindia

답변:


1251

브랜치를 master여기와 원격으로 모두 호출 하고 리모트를 호출한다고 가정하면 origin다음을 수행 할 수 있습니다.

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

그러나 다른 사람이 원격 저장소를 작업 중이고 변경 사항을 가져온 경우이 작업을 수행하지 마십시오. 이 경우 원하지 않는 커밋 을 돌린 다음 평소대로 푸시하는 것이 좋습니다 .

업데이트 : 당신은 다른 사람들이 당신이 푸시 한 변경 사항을 가져 왔음을 아래에서 설명 했으므로 모든 변경 사항을 되 돌리는 새로운 커밋을 만드는 것이 좋습니다 . Jakub Narębski 의이 답변 에서이 작업을 수행하는 옵션에 대한 좋은 설명이 있습니다 . 가장 편리한 방법은 되돌릴 커밋 수와 가장 적합한 방법에 따라 다릅니다.

귀하의 질문에서 이미 지점 git reset --hard을 재설정 하는 데 사용 했음이 분명하기 때문에 master지점 git reset --hard ORIG_HEAD을 이전 위치로 다시 이동 하는 데 사용해야 할 수도 있습니다 . (와 항상 똑같이, 깨끗하고, 올바른 지점에 git reset --hard있는지 git status, git reflog명백하게 손실 된 커밋을 복구하는 도구로 알고 있는지 확인하십시오.) 또한 ORIG_HEAD을 사용하여 올바른 커밋 을 가리키는 지 확인해야합니다 git show ORIG_HEAD.

문제 해결:

" ! [원격 거부 됨] a60f7d85-> 마스터 (수신 수신 거부) " 와 같은 메시지가 표시되는 경우

그런 다음 특정 지점에 대한 지점 기록 다시 작성을 허용해야합니다. 예를 들어 BitBucket에서는 "분기 기록 다시 쓰기가 허용되지 않습니다"라고 말했습니다. 체크 Allow rewriting branch history해야하는 체크 박스 가 있습니다.


21
위험 위험 :이 재설정에서는 해당 ( 추적 ) 분기가 현재 체크 아웃 되어 있고 커밋하지 않은 변경 사항이 없다고 가정합니다. 대신에 사용하십시오git update-refreset --hard ; 그것은 당신이 작업 트리 / 체크 아웃 지점없이 동일한 작업을 수행 할 수있게합니다
sehe

3
내가 참조. 그것은 다른 사람들에 의해 밀려지고 변경되었습니다. 그래서 나는 사용해야 revert 하지만 지난 4 개의 커밋을 되돌리고 싶다고 git revert comit1; git push; git revert comit2; git push; ...말하면됩니다 git revert commit4; git push.
nacho4d

1
@ nacho4d : 각 복귀 후 푸시 할 필요가 없습니다-Jakub Narębski 의이 답변에서 수행 할 작업에 대한 좋은 설명 있습니다. 각 커밋을 거꾸로 되돌릴 필요가 있습니다. 이렇게 git revert commit4하면 도입 된 변경 사항 만 취소하는 새로운 커밋이 만들어집니다 commit4. 그러나 내가 대답 한 것처럼, 단일 커밋으로 롤백 할 수 있습니다.
Mark Longair

1
@Mark 나는 이미 실행 git reset --hard했지만 로컬을 삭제하고 원점에서 다시 가져 왔 으므로 git revert ...지금 내 의심은 할 수 있습니다 . 각 커밋을 되돌리고 (하나씩) 푸시하거나 첫 커밋을 되돌려 야합니다 바로 커밋?
nacho4d

1
@sehe : 전체 참조 이름을 사용해야하기 때문에 사용하기가 어렵 기 때문에 사람들 .git이 만들려는 의도가 아닌 참조로 디렉토리를 흩 뜨리기가 쉽습니다 . 그러나 안전 점검이 없다고 말하는 것은 잘못입니다. git man page 에서 "plumbing"및 "porcelain"명령으로 분류를 찾을 수 있습니다 .
Mark Longair

123

로컬 변경 내용을 잃어 버릴 염려가 없으면 다른 답변을 사용하십시오. 되돌아 갈 잘못된 커밋 해시를 선택하면이 방법으로 여전히 원격 장치가 손상 될 수 있습니다.

원격 저장소를 로컬 리포지토리의 어느 곳에서나 커밋하려면 다음을 수행하십시오.

  1. 마십시오 하지 어떤 재설정을한다.
  2. git log리모컨에 원하는 커밋을 찾는 데 사용하십시오 . git log -p변경 사항을 보거나 git log --graph --all --oneline --decorate콤팩트 한 트리를 봅니다.
  3. 커밋의 해시 또는 태그 또는 해당 분기의 이름 (팁인 경우)을 복사하십시오.
  4. 다음과 같은 명령을 실행하십시오.

    git push --force <remote> <commit-ish>:<the remote branch>
    

    예 :

    git push --force origin 606fdfaa33af1844c86f4267a136d4666e576cdc:master
    

    또는

    git push --force staging v2.4.0b2:releases
    

git go2 단계와 같이 기록을 볼 때 편리한 별칭 ( )을 사용 하며, 다음과 같이 추가 할 수 있습니다.

    git config --global alias.go 'log --graph --all --decorate --oneline'`

3
그래프는 아주 좋은 팁이었습니다. 마지막 n 커밋 만 가져 오기 위해 -5를 추가했습니다. 다른 거대한 트리였습니다. 또한 재설정을 피하는 것이 내가 찾던 것입니다. 위대한
AlexanderD

@AlexanderD 쉘이 아닌 Git에 별칭을 추가 할 수 있으므로 어디에서나 작동합니다. Git은 전체 명령에서 이러한 별칭과 탭 완성을 이해하므로 인수를 추가 할 수 있습니다. git config --global alias.graph 'log --graph --all --decorate --oneline'덜 지저분하고 여전히 제한 할 수 있습니다. 예 :git graph -5
Walf

이것은 완벽 해요. 나는 항상 내 지역을 엉망으로 만들었습니다. 이것은 내 스테이징을 실수로 밀어 붙인 후 정확히 필요한 것입니다. (감사합니다!
Jake

1
Windows q에서 git log를 종료하려면 입력하십시오 . 2 분은 다시는 돌아올 수 없습니다.
dst3p

1
@ dst3p 모든 플랫폼에 있습니다. 페이저 프로그램은 보통 lessq를 종료하는 일반적인 방법입니다. Git Bash는 * nix 터미널과 같습니다.
Walf


13

GitLab에서는 이를 수행하기 전에 브랜치를 보호되지 않은 상태 로 설정해야 할 수도 있습니다 . [repo]> 설정> 리포지토리> 보호 된 분기에서이를 수행 할 수 있습니다. 그런 다음 Mark의 답변 방법이 작동합니다.

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

10

이전 버전의 파일을 원한다면 git checkout을 사용하는 것이 좋습니다.

git checkout <commit-hash>

이렇게하면 시간을 되돌려 보내며 프로젝트의 현재 상태에 영향을 미치지 않습니다. 메인 라인 git checkout mainline에 올 수 있습니다

그러나 인수에 파일을 추가하면 해당 파일이 이전 시간에서 현재 프로젝트 시간으로 다시 가져옵니다. 즉 현재 프로젝트가 변경되어 커밋해야합니다.

git checkout <commit-hash> -- file_name
git add .
git commit -m 'file brought from previous time'
git push

이것의 장점은 기록을 삭제하지 않으며 특정 코드 변경 사항을 되 돌리지 않는다는 것입니다 (git revert)

https://www.atlassian.com/git/tutorials/undoing-changes#git-checkout 여기에서 확인 하십시오


이것은 훌륭한 해답입니다. 효과가 있고 기간이 있으며 매우 안전합니다. 당신이 그것을 망쳐 놓으면 쉽게 돌아갈 수 있습니다.
bob

8

이전 답변에 대한 2 센트 : if

git push --force <remote> <the-hash>:<the remote branch>

여전히 작동하지 않으면 <your-remote-repo>.git/config파일의 수신 섹션 을 편집 할 수 있습니다 .

[receive]
  #denyNonFastforwards = true
  denyNonFastforwards = false

대부분의 답변이 github 또는 bitbucket과 같은 원격 서비스를 가정하는 것처럼 보이기 때문에 앞으로 빨리 밀지 못하도록 원격을 구성하는 방법을 아는 것이 도움이됩니다.
strongbutgood

2

브랜치가 개발 또는 프로덕션이 아닌 경우이를 달성하는 가장 쉬운 방법은 로컬로 특정 커밋으로 재설정하고 새 브랜치를 생성하는 것입니다. 당신이 사용할 수있는:

자식 체크 아웃 000000

문제가있는 지점에서 000000은 가고 싶은 커밋 ID입니다.

자식 원격 추가 [name_of_your_remote]

그런 다음 새로운 PR을 만들면 모든 것이 잘 작동합니다!


1

한 가지를 수행하고 커밋의 SHA 번호를 가져옵니다. 87c9808과 같은

  1. git reset --hard 89cef43 // 멘션 번호를 사용하여 지정된 커밋으로 머리를 이동하십시오.
  2. 다음으로 무작위 파일에서 약간의 변경을 수행하여 git이 로컬에서 원격으로 커밋하도록 요청합니다. 따라서 지금해야 할 일은입니다. 변경 사항 적용 후 git commit -a -m "평가판 커밋"
  3. 이제 git push origin master에 의해 다음 커밋을 푸시하십시오 (이것이 로컬로 커밋 된 경우).
  4. 이제 자식이 물어볼 것은

오류 : 일부 참조 를 ' https://github.com/YOURREPOSITORY/AndroidExperiments.git ' 으로 푸시하지 못했습니다. 힌트 : 현재 지점의 끝이 힌트 뒤에 있기 때문에 업데이트가 거부되었습니다. 다시 밀기 전에 원격 변경 사항 (예 : 힌트 : 'git pull ...')을 통합하십시오. **

  1. 따라서 지금 할 수있는 일은

git push --force origin master

  1. 따라서, 그것이 작동하기를 바랍니다 :)

1

소스 트리 : 특정 커밋으로 원격 재설정

  1. 아래 그림과 같이 리모컨 (origin / feature / 1337_MyAwesomeFeature)에 잘못된 커밋을 푸시 한 경우

리모컨으로 이동

  1. 리모컨> 출처> 기능> 1337_MyAwesomeFeature로 이동하십시오.
  2. 마우스 오른쪽 버튼을 클릭하고 "원점 / 기능 삭제 / 1337_MyAwesomeFeature"를 선택하십시오 (또는 백업을 원하면 이름을 변경하고 4 단계를 건너 뛰십시오).
  3. "강제 삭제"및 "확인"을 클릭하십시오.

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

  1. 이전 커밋을 선택하고 "현재 커밋을이 커밋으로 재설정"을 선택하십시오.
  2. 원하는 모드 (마지막 변경을 원하지 않는 경우)와 "확인"을 선택하십시오.

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

  1. 이 커밋을 새로운 출발지 / 기능 / 1337_MyAwesomeFeature로 푸시 여기에 이미지 설명을 입력하십시오

  2. 로컬 기능 분기 및 원격 기능 분기가 이제 이전 (선택한) 커밋에 있습니다. 여기에 이미지 설명을 입력하십시오

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