2010-04-28 4 views
15

git에서 서브 브랜치가있는 브랜치를 리베이스 할 수 있습니까?git rebase branch with all subbranches

나는 종종 특정 커밋을 표시하기 위해 빠른/변경 가능한 태그로 브랜치를 사용합니다.

* master 
* 
* featureA-finished 
* (changed/reworded) 
* origin/master 

하지만 내가 얻을 것은 :

* master 
* 
* featureA-finished 
* 
* origin/master 

는 지금은 featureA-finished^

git rebase -i --onto origin/master origin/master master 후, 나는 기본적으로 역사이 원하는 커밋 바꾸어 말하다/변경, origin/masterrebase -imaster 원하는 :

거기에 방법이 있습니까, 아니면 새로운 rebased 커밋에 지점을 재현하는 데 붙어 있습니까?

+0

브랜치 대신'git notes'를 사용하여 커밋을 표시 할 수 있습니다. 커밋을 표시 할 때 자동으로 리셋됩니다. (그것은 새로운 기능이므로 최신 버전이 필요합니다.) http://www.kernel.org/pub/software/scm/git/docs/git-notes.html – Cascabel

+0

참고 사항 [어떻게 rebase 할 것인가?] 전체 subhistory - 그들 사이의 몇 가지 링크와 여러 가지, 병합의 결과] (http://stackoverflow.com/a/9706495/94687). 그 해결책의 불쾌한 부분은 주제 분기 참조를 새로운 rebased 커밋으로 재설정해야 할 필요가 있다는 것입니다. –

답변

2

난 당신이 거기에 도착하지만, 정확히 어떻게하지 확신 :

git branch -f (same changeset as featureA-finished) 

이 바로 역사와 featureA-finished 지점을 재설정하기에 충분합니다.

+0

네, 그게 새로운 리스터드 커밋에서 브랜치를 다시 만드는 것입니다. 나는 그것이 이런 식으로 가능하다는 것을 안다. 그러나 그것은 이미 3 개의 가지에 대해 정말로 성가 시게된다. – knittl

+0

@knittl : 흥미 롭다. 이전 및 이후 분기에 대한 자세한 로그 다이어그램이 도움이 될 수 있습니다. – VonC

+0

그냥 15 개의 커밋을 가진 동일한 그래프를 상상해보십시오. 두 번째 커밋은 featureA 완료, featureB 완료, featureC 완료 등입니다. – knittl

1

먼저 origin/masterfeatureA-finished을 리베이스하는 것이 좋습니다. 그런 다음 다시 단계를 수행하십시오. 그 후 masterfeatureA-finished에 리베이스하십시오. 이것은 당신이 원하는 최종 결과를 얻을 것입니다.

두 리베이스 모두에서 -i을 사용해야하며 두 번째 리베이스의 원본 인 featureA-finshed에서 모든 커밋을 삭제해야 할 수도 있습니다. 원하는 경우 중간 브랜치를 저장하고 리베이스의 기본으로 사용하여이 문제를 해결할 스크립트를 작성할 수 있습니다 --onto 새 버전. 그것은 당신이 그것을 썼다면 그러한 '하부 구조'의 순서를 다룰 수도 있습니다. 도움이 필요하다면 한 명만 탕할 수 있습니다.

5

git의 Object Model에 따르면 커밋 (즉 커밋 메시지)의 메타 데이터 만 변경하고 내부 데이터 ('트리 (들)')는 변경하지 않으면 트리 해시가 변경되지 않습니다.

커밋 메시지 편집 외에도 origin/master에서 변경 한 내용이 다시 쓰여진 기록의 파일에 영향을 미치기 때문에 커밋 메시지를 편집하는 것 외에 리스터레이션을 수행하여 기록에있는 각 커밋의 트리 해시를 변경합니다. 즉 커밋이 가리키는 일부 파일 (blob)이 변경되었습니다.

그래서 원하는대로 할 수있는 방탄 방법이 없습니다.

즉, rebase -i으로 커밋을 편집해도 커밋의 타임 스탬프와 작성자가 변경되지 않으므로 리베이스 작업 전후의 커밋을 고유하게 식별 할 수 있습니다.

리베이스를 수행하기 전에 이러한 모든 "timestamp : author"식별자에 대한 모든 브랜치 시작점을 기록한 스크립트를 작성한 다음 동일한 "timestamp : author"ID로 다시 작성한 커밋을 찾아 리스터 그 위에 가지.

슬프게도, 지금이 스크립트를 직접 작성해볼 시간이 없으므로 나는 당신에게 최선의 운을 빌 수 있습니다!

편집 : 다음을 사용하여 저자의 이메일 주소와 타임 스탬프를 얻을 수 있습니다

$ git log --graph --all --pretty=format:"%h %ae:%ci" 
* 53ca31a [email protected]m:2010-06-16 13:50:12 +0100 
* 03dda75 [email protected]:2010-06-16 13:50:11 +0100 
| * a8bb03a [email protected]:2010-06-16 13:49:46 +0100 
| * b93e59d [email protected]:2010-06-16 13:49:44 +0100 
|/ 
* d4214a2 [email protected]:2010-06-16 13:49:41 +0100 

을 그리고 당신은 자신의 커밋 해시를 실시하고이를 근거로이 각 지점의 목록을 얻을 수 있습니다

$ git branch --contains 03dda75 
* testbranch 

커밋마다 여러 가지 브랜치에주의하십시오. 공통 조상 d4214a2은 두 브랜치에 모두 속합니다!

2

이 기능이 천천히 git에 들어가는 것처럼 보입니다. rebase은 원래의 답변에서 묻는 질문과 정확히 일치하는 대답 --rebase-refs을 얻을 수 있습니다. 제안 된 패치 시리즈는 gmane의 스레드 rebase: command "ref" and options --rewrite-{refs,heads,tags}을 참조하십시오.

+0

이것은 Git에 들어간 것 같지 않은 유감입니다. git-rebase에 대한 현재 설명서 (맨페이지)! (git-1.7.9.3) –

관련 문제