끌어 오기 후 커밋 된 (그러나 푸시되지 않은) 변경 사항을 새 분기로 이동


460

나는 (37 개의 커밋으로 '출발지 / 마스터'보다 앞서있다.) 공정한 약간의 일을 해냈다 master. 이 커밋은 내 로컬 컴퓨터에만 존재하며 추진되지 않았지만 origin다른 개발자가 추진하고 origin/master있으며 이러한 변경 사항을 적용 했기 때문에 상황이 다소 복잡 합니다.

37 개의 로컬 커밋을 소급하여 새로운 지점으로 소급 이동하려면 어떻게해야합니까? 문서를 기반으로하면 이 작업을 수행 git rebase --onto my-new-branch master하거나 수행 ...origin/master해야하지만 둘 다 "치명적 : 단일 개정이 필요합니다"라는 오류가 발생합니다. man git-rebase에 개정을 제공하는 것에 대해 아무 말도 rebase하지 않으며 예제는 그렇게하지 않으므로이 오류를 해결하는 방법을 모릅니다.

이 것을 (참고 하지 의 중복 기존 이동, 힘내에서 새로운 지점에 미트되지 않은 작업 또는 다른 힘내 지점에 내 로컬 커밋되지 않은 변경 내용을 병합하는 방법은? 그 질문은 로컬 작업 트리에서 커밋되지 않은 변경되지 않은 변경 사항 처리로 현지에서 커밋되었습니다.)


솔루션을 확인하십시오 . 쉽고 깨끗해 보입니다.
Tony

솔루션을 확인하십시오 . 쉽고 깨끗해 보입니다.
Tony

답변:


518

커밋을 아직 다른 곳으로 푸시하지 않았기 때문에 괜찮을 것 origin/master입니다. 우선은이 실행됩니다 git fetch origin있는지 확인하기 위해 origin/master최신입니다. 현재에 있다고 가정하면 다음 master을 수행 할 수 있습니다.

git rebase origin/master

...하는 수없는 커밋의 모든 재생됩니다 origin/master상을 origin/master. rebase의 기본 동작은 병합 커밋 (예 : git pull아마도 도입 된 커밋)을 무시 하는 것 origin/master입니다. 각 커밋이 도입 한 패치를에 적용하려고합니다 . (이 과정에서 일부 충돌을 해결해야 할 수도 있습니다.) 결과에 따라 새 분기를 만들 수 있습니다.

git branch new-work

... 그리고 master다시 다음으로 재설정하십시오 origin/master.

# Use with care - make sure "git status" is clean and you're still on master:
git reset --hard origin/master

와 조작 지사의 이런 종류의 일을 할 때 git branch, git reset등 I를이와 그래프 커밋에 유용 자주보고 찾을 gitk --all또는 유사한 도구를 단지 다른 모든 심판이 가리키는 곳 이해하는지 확인.

또는 마스터가 처음있는 위치 ( git branch new-work-including-merges)를 기반으로 주제 분기를 만든 다음 master위와 같이 재설정 할 수 있습니다. 그러나 주제 분기에는 병합이 포함되며 origin/master아직 변경 사항을 푸시하지 않았으므로 기록을 더 깔끔하게 유지하기 위해 리베이스를 수행하는 것이 좋습니다. 또한 결국 토픽 브랜치를 다시 마스터로 병합하면 변경 사항이 더 분명해집니다.


8
@Olie : 아니요. 질문의 가정과 대답의 맨 위에 설정 한 내용에 따라 답이 정확합니다. 별도의 새 분기에 있어야하는 커밋이 이미 있습니다 master. rebase는 master브랜치를 다시 작성하여 새 커밋이 선형으로 위에 오도록 origin/master한 다음 현재 브랜치 를로 변경 하지 않고 (현재 브랜치) 의 끝을 가리키는 브랜치 를 git branch new-work만듭니다 . 이제 모든 새로운 커밋이 포함됩니다. 그런 다음 재설정하면 현재 분기 (여전히 )가 (으 )로 다시 이동합니다 . new-workmasternew-worknew-workmasterorigin/master
Mark Longair

1
@Quintesse : 일을 잃어버린 경우 정말 죄송합니다.하지만 원래 답변자가 설명한 상황에 대해서는이 답변이 정확한 것입니다. (나는 방금 Olie의 발언에 희망을 분명히 밝혔습니다.) 어쨌든, 당신의 일을 되 찾는 데 도움이되는 경우를 대비하여 지난 며칠 내에 당신의 일이 저질러 졌다면 (이 질문과 대답의 가정 중 하나) ) git reflog를 통해 쉽게 검색 할 수 있어야합니다.
Mark Longair

5
@Olie : 아마도 더 나은 설명 방법 : git의 브랜치는 특정 커밋을 가리키는 레이블과 같습니다. 해당 분기에서 커밋을 만들거나 git reset다른 방법 으로 이동할 수 있으면 새 커밋으로 자동 이동됩니다 . 은 git branch new-work그냥 "나는 (마스터가이 경우이다) 내 현재 지점에 남아있는 동안이 커밋에서 분기 포인팅을 만들"말하고있다. 따라서 커밋을 마스터에서 새 분기로 이동 하는 명령이 필요하지 않습니다. 여기 에 새 분기를 만들고 마스터를 재설정하면 새 분기가 마스터가 있던 곳에 남아 있습니다.
Mark Longair

1
파티에 약간 늦었지만 @Olie, 새로운 지점에있을 때 자식 상태가 마스터보다 앞서 커밋을 표시하지 않는다고해서 실제로 그들이 존재하지 않는다는 것을 의미하지는 않습니다 (그렇기 때문에 걱정했다고 가정). 새 지점을 원점으로 밀어보십시오. 커밋이있는 것을 볼 수 있습니다
Félix Gagnon-Grenier

2
@ FélixGagnon-Grenier, "늦은"에 대해 걱정하지 마십시오. 항상 오래된 질문을 찾는 사람들이 있으며 모든 설명이 도움이됩니다. 감사! :)
Olie

148

커밋 수가 적고 하나의 메가 커밋으로 결합되어 있는지 상관하지 않으면 잘 작동하며 그렇게하는 것이 무섭지 않습니다 git rebase.

파일을 스테이지 해제하십시오 (1을 커밋 수로 대체)

git reset --soft HEAD~1

새 지점을 만들다

git checkout -b NewBranchName

변경 사항을 추가하십시오

git add -A

커밋하다

git commit -m "Whatever"

5
이해하기 쉬운 그래프를 표시하려면을 사용하십시오 git log --all --decorate --oneline --graph.
EliuX

안녕하세요 @EliuX-관련성이 누락되었습니다. 확장 할 수 있습니까?
Stachu

이것은 당신이 한 일에서 원하는 결과를 얻었는지 확인하는 데 유용한 것입니다
EliuX

4
고마워!! 이것은 매우 간단한 솔루션이며 완벽하게 작동했습니다!
Chris Sim

90

나는 같은 문제를 고수했다. 내가 공유하고 싶은 가장 쉬운 솔루션을 찾았습니다.

1) 변경 사항으로 새 지점을 만듭니다.

git checkout -b mybranch

2) (선택 사항) 원격 서버에서 새 분기 코드를 푸시하십시오.

git push origin mybranch

3) 마스터 지점으로 다시 체크 아웃하십시오.

git checkout master

4) 원격 서버로 마스터 분기 코드를 재설정하고 로컬 커밋을 제거하십시오.

git reset --hard origin/master

10
그건 정말 쉬운 방법
dhilt

4
2 단계를 생략 할 수 있습니다. 나는 최고 답변 이후 시간에 git이 변경 되었고이 절차는 전에 허용되지 않았다고 가정합니다.
Sebastian

이것은 내 의견으로는 가장 좋은 대답입니다.
Macindows 2014

1
이 답변은 맨 위로 이동해야합니다. 감사합니다.
amit

27

또 다른 방법은 branch1-커밋 된 변경 사항이있는 branch입니다. branch2-바람직한 분기입니다.

git fetch && git checkout branch1
git log

이동해야 할 커밋 ID를 선택하십시오.

git fetch && git checkout branch2
git cherry-pick commit_id_first..commit_id_last
git push

이제 초기 브랜치에서 푸시되지 않은 커밋을 되돌립니다.

git fetch && git checkout branch1
git reset --soft HEAD~1

5
Cherry-pick은 실제로 가장 좋은 "단일 커밋 복사 / 이동"명령입니다 (예 : esp). 역사가 당신의 목적을 위해 수하물 일 때.
John Neuhaus

이것은 지금까지 가장 편리한 질문에 대한 답변입니다. 명령 주셔서 감사합니다!
Farah

1 또는 n이 푸시되지 않은 커밋 수인 마지막 주석을 업데이트 할 수 있습니까? 이것은 여전히이 질문에 대한 정말 좋은 해결책입니다.
chAlexey 2016 년

9

또는 잘못된 분기를 커밋 한 직후 다음 단계를 수행하십시오.

  1. git log
  2. git diff {previous to last commit} {latest commit} > your_changes.patch
  3. git reset --hard origin/{your current branch}
  4. git checkout -b {new branch}
  5. git apply your_changes.patch

1 단계와 2 단계에 대한 더 간단한 접근법이 있다고 상상할 수 있습니다.


6

이건 어떤가요:

  1. 현재 HEAD에서 분기합니다.
  2. 새 지점이 아닌 master 에 있는지 확인하십시오 .
  3. git reset 변경을 시작하기 전에 마지막 커밋으로 돌아갑니다.
  4. git pull 리셋으로 버린 원격 변경 사항 만 다시 잡아 당깁니다.

아니면 지점을 다시 병합하려고 할 때 폭발합니까?


2
아, 이것은 기본적으로 위의 @ Mark-Longair에 의해 설명 된 옵션 B입니다
Tim Keating

2

훨씬 간단한 방법은 다음과 같습니다.

  1. 새로운 지점 만들기

  2. 새 브랜치에서 수행 git merge master-커밋 된 (푸시되지 않은) 변경 사항을 새 브랜치에 병합합니다.

  3. 로컬 마스터 분기 삭제 분기를 강제로 삭제하려는 대신에 git branch -D master사용하십시오 .-D-d

  4. 그냥 할 git fetch마스터 지점에와을 git pull당신이 당신의 팀의 최신 코드를 확인하기 위해 마스터 분기에.


1

내가 사용하고있는 더 간단한 접근법 (4 개의 커밋을 옮기고 싶다고 가정) :

git format-patch HEAD~4

(4 개의 .patch파일에 대한 마지막 명령을 실행 한 디렉토리를보십시오 )

git reset HEAD~4 --hard

git checkout -b tmp/my-new-branch

그때:

git apply /path/to/patch.patch

원하는 순서대로


0
  1. 당신의 소스의 신선한 사본을 체크 아웃

    git clone ........

  2. 원하는 위치에서 분기 만들기

    git checkout {position} git checkout -b {branch-name}

  3. 원격 저장소 추가

    git remote add shared ../{original sources location}.git

  4. 원격 소스 받기

    git fetch shared

  5. 원하는 지점 확인

    git checkout {branch-name}

  6. 소스 병합

    git merge shared/{original branch from shared repository}


0

나에게 이것은 가장 좋은 방법이었다.

  1. 변경 사항 확인 및 병합 충돌 git fetch
  2. 새 지점을 git branch my-changes만들고 원격으로 푸시
  3. 새로 생성 된 지점으로 업스트림 변경 git master -u upstream-branch remotes/origin/my-changes
  4. 커밋을 새로운 업스트림 브랜치로 푸시하십시오.
  5. 이전 업스트림으로 다시 전환 git branch master --set-upstream-to remotes/origin/master
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.