단일 Git 커밋 리베이스


116

분기에서 다른 분기로 단일 커밋을 리베이스하는 방법이 있습니까?

이 분기 구조가 있습니다.

-- -- -- -- -- (Master)
            \
              -- -- -- -- -- XX (Feature-branch)

내가 원하는 것은 마지막 커밋 Feature-branch을 마스터 로 리베이스하고 Feature-branch하나의 커밋을 롤백하는 것입니다.

-- -- -- -- -- XX (Master)
            \
              -- -- -- -- -- (Feature-branch)

어떻게하나요?


3
어떤 수의 커밋을 리베이스 할 수 있다면 왜 하나의 커밋을 리베이스하는 것에 대해 질문합니까? 그래서 질문을 할 수 있다면 리베이스 (단일 커밋)와 체리 피킹의 차이점이 무엇인지 묻습니다.
Val

9
체리 따기가 존재하는지 몰랐기 때문에 "지점에 대한 Faff", "다른 지점에 대한 수정 요청", "수정", "잘못된 지점에 커밋", "D' OH!" 질문하는 것이 유용 할 정도로 충분했습니다.
Kevin Meyer

답변:


116

XX를 체리로 골라 마스터 할 수 있습니다.

git checkout master
git cherry-pick <commit ID of XX>

그리고 git reset을 사용하여 기능 분기에서 마지막 커밋을 제거하십시오.

git checkout Feature-branch
git reset --hard HEAD^

64
구체적으로 'git rebase ...'라는 질문이 완전히 다른 개념이며 때로는 그 자체로 부정한 것으로 간주되는 체리 픽을 포함하는 것보다 수용된 대답을 어떻게 가질 수 있습니까?
Bondax

1
이것이 관련성이 있는지 확실하지 않지만 리베이스하려는 커밋에는 일부 파일이 이동 cherry-pick되어 이전 위치에서 삭제되고 새 위치에 생성 된 것처럼 보이게했습니다. 나는 rebase가 그것을 처리했을 것이라고 생각하지만 지금까지 나는 그것을 테스트 할 수 없도록 업스트림으로 밀어 넣었다. 어쨌든 비슷한 상황이 있는지 조심하십시오.
waldyrious

참고 : 당신이 변경 밀어 Feature-branch당신이 필요합니다 원점 git push -f origin Feature-branch당신은 다음과 같이 Feature-branch이제 1이 뒤에 커밋로 간주됩니다 origin/Feature-branch.
jojo

1
이 솔루션과 CharlesB의 솔루션 간의 실질적인 차이점은 무엇입니까 ?
Lii

96
git rebase --onto master branch~1 branch 

이것은 "마스터 브랜치의 끝에서 마지막 이전 브랜치와 브랜치 (즉, XX 커밋) 사이의 커밋 범위를 리베이스"한다고 말합니다.

이 작업 branch팁이 commit으로 이동 한 후 XX다시 설정하고 싶습니다.

git checkout branch
git reset --hard branch@{1}^

"이전 상태 이전의 커밋으로 분기 팁을 재설정"이라고 말합니다.

따라서 체리 선택은 더 간단한 해결책입니다 ...


5
이것은 나를 위해 작동하지 않는 것 같습니다 .XX 전에 커밋을 잃고 브랜치가 단일 커밋으로 마스터로 리베이스되었지만 --onto이전에 사용한 적이 없으므로 뭔가 잘못되었을 수 있습니다. BTW OP는 rebase라고 말했지만 체리 픽을하고 싶어하는 것 같습니다.
tewe

1
내 오류, rebase는 실제로 마스터에서 분기를 이동합니다. 재설정해야합니다
CharlesB

1
이 솔루션과 tewe 의 실질적인 차이점은 무엇입니까 ?
Lii

1
유일하게 내가 볼 수는 3 개 단계 4 대신 사용한다는 것입니다 @Lii
CharlesB

52

실제로하는 것은 매우 간단합니다. 해결책은 대화 형 리베이스를 수행하고 리베이스에 포함하지 않으려는 모든 커밋을 "삭제"하는 것입니다.

git rebase -i <target_branch>target_branch리베이스하려는 지점은 어디에 있습니까?

그럼 당신은 열린 파일 편집합니다 pick당신이 원하는 않는 커밋 및 drop(또는 d당신이 함께 가지고 싶지 않아 짧은에 대한) 모든 커밋.


6
IMO는 훨씬 더 나은 솔루션이며 실제로 문제를 해결합니다.
GabrielOshiro

이것은 얼마나 일반적이고 직관적이며 짧은 지 고려할 때 허용되는 솔루션이어야합니다.
Pablo Arias

1

@Charles 응답이 정확합니다. 어쨌든 나는 이것을 여러 번 사용하여 결국 프로젝트의 특정 구성을 다시 작성했습니다.

  * a8f9182 (HEAD-> 생산) 생산 구성
  | * daa18b7 (사전) 사전 제작 구성
  | /  
  | * d365f5f (로컬) 로컬 구성
  | /  
  * 27d2835 (dev) 세상을 구할 놀라운 새로운 기능
* | 56d2467 (마스터) 프로젝트를위한 지루한 상태
| /

이에 대한 새 명령을 만듭니다.

$ 고양이 ~ / bin / git-rebaseshot 
커밋 = $ 1
DEST = $ {2 : -HEAD}
git rebase $ {COMMIT} ^ $ {COMMIT}-$ DEST에

일반적으로 해당 명령에 대한 브랜치 이름을 자동 완성하고 싶으므로이 함수를 소싱하여 추가합니다 (.bashrc 또는 .profile에 추가).

_git_rebaseshot () 
{ 
    __gitcomp_nl "$ (__ git_refs)"
}

git autocomplete가 검색합니다.

이 명령을 다음과 같이 사용할 수 있습니다.

# rebase config on prepro on actual HEAD
$ git rebaseshot prepro 
# rebase config on local onto dev
$ git rebaseshot local dev
# rebase production config on master
$ git rebaseshot pro master

기능을 올바르게 나누면 가능성은 무한합니다.

* a8f9182 (HEAD-> postgres) BBDD 구성
* a8f9182 (로컬) 로컬 구성
* a8f9182 (디버그) 로그 수준 구성
* a8f9182 (dev) 새로운 기능
|

나는 이것이 사람들 이 퀼트를 좋아하는 것 같아요 .

이 명령은 어떤 sha / ref를 제공하든 상관없이 작동합니다.

$ git rebaseshot <Feature branch> master
$ git rebaseshot <commit of XX> master

//, 이것이 실제로 작동하는 것을 볼 수있는 프로젝트에 연결할 수 있습니까?
Nathan Basanese

특성상 rebaseshot에 사용할 수있는 분기는 로컬 저장소 외부에서 커밋되지 않습니다. 마스터 (로그 수준, 데이터베이스 연결, 구성) 위에 여러 분기를 만들고 그 사이에 명령을 사용하면됩니다. 효과를 알기 쉽다.
albfan 2016 년

//, 몇 가지 문제가 발생했습니다. 다시 해보겠습니다.
Nathan Basanese 2016 년

0

다른 옵션이 있습니다.

  1. 기능 브랜치의 사본이있는 리모컨이 있는지 확인하십시오.
  2. 로컬 기능 분기 삭제
  3. 방금 마스터에서 삭제 한 이전 기능 브랜치와 동일한 이름으로 새 브랜치를 만들고 체크 아웃합니다.
  4. 원하는 기능 브랜치의 원격 사본에서 하나의 커밋을 선택합니다.

명령은 다음과 같습니다.

git checkout Feature-branch
git push -u origin HEAD
git checkout master
git branch -D Feature-branch
git checkout -b Feature-branch
git cherry-pick HASH-OF-XX

리베이스 명령은 아니지만 정신적으로 리베이스입니다.

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