강제 업데이트 후 Git pull


332

난 그냥 몇 가지 커밋을 숙청 git rebase하고했다 git push --force(악한, 나는 알고있다).

이제 다른 소프트웨어 엔지니어는 다른 역사를 가지고 있으며 git pullGit이 합병하면 병합됩니다. ?를 수행하는 것을 제외하고이 문제를 해결하는 방법이 rm my-repo; git clone git@example.org:my-repo.git있습니까?

의 반대와 같은 것이 필요 git push --force하지만 git pull --force의도 한 결과를주지 못했습니다.


16
그들은 전체 저장소를 삭제하지 않고도 지점을 삭제하고 다시 만들 수 있습니다.git checkout master && git branch -D test && git checkout -b test origin/test
Florian Klein


답변:


509

새로운 커밋을 받으려면

git fetch

초기화

을 사용하여 로컬 브랜치에 대한 커밋을 재설정 할 수 있습니다 git reset.

로컬 지점의 커밋을 변경하려면

git reset origin/master --hard

그러나 설명서에 명시된대로주의하십시오.

색인 및 작업 트리를 재설정합니다. <commit> 이후 작업 트리에서 추적 된 파일에 대한 모든 변경 사항은 무시됩니다.

실제로 변경 한 내용을 그대로 유지하려면 --soft대신 재설정하십시오. 브랜치의 커밋 히스토리를 업데이트하지만 작업 디렉토리의 파일을 변경하지 마십시오 (그리고 커밋 할 수 있습니다).

리베이스

다음을 사용하여 다른 커밋 / 브랜치 위에서 로컬 커밋을 재생할 수 있습니다 git rebase.

git rebase -i origin/master

그러면 대화식 모드에서 rebase가 호출되어 기반이되는 히스토리에없는 각 개별 커밋을 적용하는 방법을 선택할 수 있습니다.

삭제 한 커밋 git push -f이 이미 로컬 히스토리로 가져온 경우 재 적용될 커밋으로 나열됩니다. 리베이스의 일부로 삭제해야하거나 단순히 히스토리에 다시 포함됩니다. 분기에 대해-다음 푸시에서 원격 기록에 다시 나타납니다.

git command --help위의 (또는 다른) 명령에 대한 자세한 내용과 예를 보려면 도움말 을 사용하십시오 .


2
@iblue는 모든 변경 사항 손실, 커밋 기록 제거, 파일 변경 사항 유지 또는 새 커밋 위에 각 커밋 적용 시도 중 하나를 선택합니다. 가장 간단한 옵션은 소프트 리셋 일 것입니다.
AD7six

1
@iblue 동료가`git reabse origin / master '를 사용할 때, 그들이 이미 커밋을 한 상태라면, git은 커밋 뒤에 커밋을 작성합니다.
Tim

6
이것이 다른 지점에 해당되는 경우 다음과 같이 언급 할 가치가 있습니다.git reset origin/otherbranch --hard
bmaupin

그래서, 이것이 명확히하는 옵션 1 : reset --hard, 또는 옵션 2 : reset --soft+를 rebase, 맞죠?
PlasmaBinturong

2
@PlasmaBinturong 번호 git reset --soft origin/master원격으로 원격 및 단계의 차이에 맞게 역사를 커밋 변경됩니다 다음 커밋을 . 커밋 히스토리에는 차이가 없으므로 해당 시나리오에서 리베이스 할 필요가 없습니다 (커밋되지 않은 변경으로 인해 그렇게하지 못하게됩니다). 두 가지 옵션은 재설정 또는 재 베이스 (둘 다의 조합이 아님)입니다. 제발 질문 시나리오는 내가 여기에 대답 한 것과 다른 경우.
AD7six

16

이것은 이미 원하지 않는 코드가있는 분기를 수정하지는 않지만 (이를 수행하는 방법은 아래 참조) 분기를 가져 와서 깨끗하게 만들고 싶다면 원산지 / 일부 지점) 다음과 같이하면됩니다.

git checkout some-branch   # where some-branch can be replaced by any other branch
git branch base-branch -D  # where base-branch is the one with the squashed commits
git checkout -b base-branch origin/base-branch  # recreating branch with correct commits

참고 : &&를 넣어서이 모든 것을 결합 할 수 있습니다.

Note2 : Florian은 이것을 주석으로 언급했지만, 답변을 찾을 때 누가 주석을 읽습니까?

참고 3 : 오염 된 가지가있는 경우 새 "덤 지점"을 기반으로 새 가지를 만들 수 있고 체리 픽 (Cherry-pick) 커밋 만 가능합니다.

전의:

git checkout feature-old  # some branch with the extra commits
git log                   # gives commits (write down the id of the ones you want)
git checkout base-branch  # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd   # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch

이제 새로운 기능은 여분의 커밋이없는 지점입니다!


이것이 내가 정말로 원하는 것입니다. 누군가가 마스터 브랜치를 리베이스했지만 (하나님은 어떤 이유를 알고 있기 때문에) 커밋하고 싶었던 로컬 변경 사항이 없었습니다. 그래서 내가해야 할 일은 로컬 마스터 브랜치를 삭제하고 (정말 이상하다고 느꼈습니다) 다시 체크 아웃하는 것입니다. 감사!
Danilo Carvalho

@ peter-mortensen 편집은 stackoverflow.com/help/editing
Tom Prats

마지막 단계를 위해 다음을 사용할 수도 있습니다 git checkout -b base-branch origin/base-branch.git checkout --track origin/base-branch
bluesmonk

1

리베이스로 당겨

정기적으로 당기는 것은 페치 + 병합이지만 원하는 것은 페치 + 리베이스입니다. 다음 pull명령을 사용 하는 옵션입니다 .

git pull --rebase

역사에서 모든 병합 커밋을하지 않고도 마스터에서 기능 분기로 최신 코드를 가져 오기 위해 항상 이것을 사용합니다.
herman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.