원격 브랜치에서 커밋을 영구적으로 제거하는 방법


489

나는 그것이 야마다 야다라는 역사를 다시 쓰는 것을 안다.

그러나 원격 브랜치에서 커밋을 영구적으로 제거하는 방법은 무엇입니까?


96
그래, 야다 야다가 정말 나쁘지만 어떤 이유로 든 좋아해야합니다.
James Morris

44
나는 이것이 어리 석다는 것을 알고 있지만 때로는 로그인 테스트 및 실제 로그인 자격 증명 인 코드에서 일반 텍스트 비밀번호 사용과 같은 똥이 발생합니다. 그리고
으악

6
실제 로그인 자격 증명 .. 네, 후 투스를 생각 나게합니다
Hello Universe


2
나는 이것이 얼마나 위험한지, 어떻게 야다 야다를 절대로해서는 안되는지에 대해이 학문적 기분이 너무 피곤합니다. git history에서 물건을 제거하고 다른 개발자의 충돌 / 파괴를 처리하는 것이 훨씬 더 좋은 경우가 있습니다. 정말 간단합니다. 이것을 무시하는 사람들은 아마도 교실 밖에서 일한 적이 없을 것입니다.
호감

답변:


368

당신은 git reset --hard해당 지역의 지점은 당신에게 작업 트리와 인덱스의 변경 사항을 제거하려면 git push --force원격으로 수정 된 지역의 지점을. ( 다른 솔루션 은 원격 브랜치를 삭제하고 다시 푸시하는 것을 포함합니다)

SO 답변 은 특히 ​​사람들이 자신의 로컬 저장소에 대한 원격 기록에 의존하는 경우 이러한 명령의 위험을 보여줍니다. 맨 페이지 의 RECUPING FROM UPSTREAM REBASE 섹션으로
사람들을 가리켜 야git rebase 합니다.


Git 2.23 (2019 년 8 월, 9 년 후)에서는 새로운 명령을 사용합니다 git switch.
즉 : ( 제거 할 커밋 수로 대체 )git switch -C mybranch origin/mybranch~n
n

그러면 인덱스와 작업 트리가 원하는대로 복원됩니다 git reset --hard.


이상한. 내가 이미 시도한 것 같습니다. 일부 rebasing과 함께-매력처럼 작동합니다. 감사.
Arnis Lapsa

7
@Arnis : 완벽한 다음;) push --force떨어져
VonC

BFG Repo-Cleaner 를 사용 하여 민감한 데이터를 제거했습니다. 원본 파일이 포함 된 "이름이없는"브랜치를 남겨두고 마지막 원했던 커밋으로 재설정하고 원점으로 강제 푸시 한 후 모든 것이 정상적으로 진행되었습니다 (:
Rodrirokr

커밋의 URL은 여전히 ​​(최소한 시간 동안) 살아있어서 누군가가 커밋의 URL을 가지고 있다면 (당신이 신에게 알린 이유를 알고 있다면) 코드에 액세스 할 수 있습니다.
Mosh Feu

1
@MoshFeu True : git gc항상 원격에서 충분히 자주 실행되는 것은 아닙니다. 예를 들어 GitHub에서 : twitter.com/githubhelp/status/387926738161774592?lang=es
VonC

248

last_working_commit_id작동하지 않는 커밋을 되돌릴 때을 사용하십시오 .

git reset --hard <last_working_commit_id>

따라서 우리는 원하지 않는 것으로 재설정해서는 안됩니다 commit_id.

그런 다음 원격 지점으로 푸시해야합니다.

git push --force

10
완벽하고 우아하며 간단한 답변. 난 그냥 내가 로컬 원격 및 모두에 필요한 마지막 커밋 stabe에 복귀
lauWM

2
이로 인해 로컬 변경 사항도 손실되었습니다. 나는 그것을 기대하지 않았다. 그러나 meh는 개인 암호를 사용하여 repo를 작동시키는 것보다 낫습니다.
Airwavezx

3
git stash로 로컬 변경 사항을 저장할 수 있습니다 .... 몇 가지 .... 및 git stash pop (로컬 변경 사항이 돌아 왔습니다)
MonTea

이것은 "원격 : 오류 : 빨리 감기 참조 / 헤드 / 마스터 거부 (먼저 뽑아야 함)"로 오류를 표시합니다.
Saurabhcdt

@Airwavezx가해야 git reset --hard할 일입니다.
누가 복음

146

중요 사항 : "git push -f"에서 어떤 분기를 지정했는지 확인하십시오. 그렇지 않으면 다른 분기를 실수로 수정할 수 있습니다! [*]

이 튜토리얼 에는 세 가지 옵션 이 있습니다 . 링크가 끊어지면 여기에 주요 단계를 남겨 두겠습니다.

  1. 전체 커밋 되돌리기
  2. 마지막 커밋 삭제
  3. 목록에서 커밋 삭제

1 전체 커밋을 되돌립니다

git revert dd61ab23

2 마지막 커밋 삭제

git push <<remote>> +dd61ab23^:<<BRANCH_NAME_HERE>>

또는 지점이 로컬로 제공되는 경우

git reset HEAD^ --hard
git push <<remote>> -f

여기서 + dd61 ...은 커밋 해시이며 git은 x ^를 x의 부모로 해석하고 +는 fast-fastforwared 푸시로 해석합니다.

3 목록에서 커밋 삭제

git rebase -i dd61ab23^

그러면 모든 커밋 목록이 표시된 편집기가 열립니다. 제거하려는 것을 삭제하십시오. 리베이스를 마무리하고 힘을 가하여 리포하십시오.

git rebase --continue
git push <remote_repo> <remote_branch> -f

5
"git push <remote_repo> <remote_branch> -f"에서 어떤 브랜치를 지정했는지 확인하십시오. 그렇지 않으면 다른 브랜치가 실수로 수정 ​​될 수 있습니다!
Nigel Sheridan-Smith

1 단계와 2 단계만이 작업을 수행하고 원래 질문에 대답했습니다. (3 단계를 실행하지 마십시오)
Saad Benbouzid

이 단계는 수행해야 할 단계가 아닌 다양한 시나리오에 대한 옵션입니다. 제 경우에는 대화 형 리베이스 (옵션 3)가 내가 원하는 것을했습니다.
Steve Blackwell

그래도 3 단계를 수행해야했습니다. 왜 @Saad를 실행해서는 안됩니까? 다행히 내는 << 원격 >> 단순히 기본 '기원'과 <remote_branch> 기본 '마스터'입니다
바트

30

예를 들어 마지막 3커밋 을 삭제하려면 다음 명령을 실행하여 로컬 브랜치의 파일 시스템 (작업 트리) 및 커밋 기록 (인덱스)에서 변경 사항을 제거하십시오.

git reset --hard HEAD~3

그런 다음 로컬 컴퓨터에서 다음 명령을 실행하여 원격 분기가 기록을 다시 쓰도록합니다.

git push --force

축하합니다! 다됐다!

몇 가지 참고 사항 :

다음을 실행하여 원하는 커밋 ID를 검색 할 수 있습니다

git log

그런 다음 다음 HEAD~N<desired-commit-id>같이 바꿀 수 있습니다 .

git reset --hard <desired-commit-id>

파일 시스템에 대한 변경 사항을 유지하고 색인 (커밋 기록)을 수정하려면 다음 --soft과 같은 플래그를 사용하십시오 git reset --soft HEAD~3. 그런 다음 최신 변경 사항을 확인하고 변경 사항 전부 또는 일부를 유지하거나 삭제하십시오. 후자의 경우 runnig git status는 이후에 변경된 파일을 표시합니다 <desired-commit-id>. --hard옵션 을 사용 git status하면 로컬 지점이 원격 지점과 정확히 동일하다는 것을 알 수 있습니다. --hardnor를 사용하지 않으면 --soft기본 모드 인가 사용됩니다 --mixed. 이 모드에서는 다음과 git help reset같이 말합니다.

작업 트리가 아닌 인덱스를 재설정하고 (즉, 변경된 파일은 유지되지만 커밋으로 표시되지 않음) 업데이트되지 않은 내용을보고합니다.


10

너무 늦었을 수도 있지만 멋진 '핵'옵션이 도움이되었습니다. 기본적으로 명령 filter-branch을 사용하면 전체 git 기록에서 파일을 제거하거나 많은 수의 파일에서 무언가를 변경할 수 있습니다.

여기에 가장 잘 설명되어 있습니다 .


9
너무 늦지 않았습니다. 비슷한 문제가있는 방랑자에게 유용 할 수 있습니다 :)
Arnis Lapsa

9

블로그 게시물을 기반으로 pctroll의 답변을 단순화 합니다.

# look up the commit id in git log or on github, e.g. 42480f3, then do
git checkout master
git checkout your_branch
git revert 42480f3
# a text editor will open, close it with ctrl+x (editor dependent)
git push origin your_branch
# or replace origin with your remote

2
고맙습니다. 그리고 원격 지사 기록에서 하나의 커밋 (예 : pwd 포함)을 영구적으로 삭제하고 싶습니다. 어떻게합니까?
Smiles

1
나에게도 효과가 있지만 스마일과 같은 질문이 있습니다. 나는 역사에서 내 커밋 / 리버를보고 싶지 않습니다. 어떻게 제거합니까?
Roberto Rodriguez

4

때로는이 문제를 해결하는 가장 쉬운 방법은 코드가 좋은 곳에서 새로운 지점을 만드는 것입니다. 그런 다음 나중에 다른 커밋을 체리 선택해야 할 경우를 대비하여 잘못된 분기 기록을 그대로 둘 수 있습니다. 또한 커밋 히스토리를 잃어 버리지 않도록합니다.

현지 오류 지점에서 :

git log

브랜치를 원하는 커밋 해시를 복사하고 git log를 종료하십시오.

git checkout theHashYouJustCopied
git checkout -b your_new_awesome_branch

이제 원하는 방식으로 새 분기가 생겼습니다.

새 브랜치에없는 잘못된 브랜치에서 특정 커밋을 유지해야하는 경우 필요한 특정 커밋을 선택하면됩니다.

git checkout the_errant_branch
git log

좋은 브랜치로 가져 와서 git log를 종료하는 데 필요한 커밋의 커밋 해시를 복사하십시오.

git checkout your_new_awesome_branch
git cherry-pick theHashYouJustCopied

등을 두 드리십시오.


당신이 다리가 나쁜 지사를 가지고 있다면 매우 쉽고 누가 걱정합니까? 새로운 지사를 만들고 그것을 완료하십시오!
앤드류 폭스

이것은 정말 훌륭한 답변입니다. 체리 따기 커밋이나 원격 지점 조작 대신이 작업을 수행하게되어 기쁩니다.
Magnilex

0
 git reset --soft commit_id
 git stash save "message"
 git reset --hard commit_id
 git stash apply stash stash@{0}
 git push --force
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.