2014-04-08 3 views
2

단일 - 부모 커밋의 브랜치가있는 경우; 이 브랜치에서 연속적인 커밋 영역을 선택하고 다른 브랜치에 스쿼시를 추가하려면 어떻게해야합니까? 나는 원래의 브랜치를 바꾸고 싶지 않다. (그리고 각각의 커밋은 하나의 부모만을 가졌다 고 가정한다.)JGit : 하나의 브랜치에서 다른 브랜치로 커밋 영역을 선택하고 스쿼시하는 방법

다음은 예입니다 : 내가 C, DE를 선택 그들을 스쿼시, 그리고 Z에 그들을 배치 할. 그런 다음 FG을 골라 스쿼시하고 Z의 머리에 놓습니다. 우리는 아래의 나무로 시작 :

A-----B------C------D------E------F------G------H 
\ 
    \ 
    Z 

그리고이 결과를 얻을 :

Y가 숙청이 C, D의 커밋이고, E

X은 다음과 같습니다

A-----B------C------D------E------F------G------H 
\ 
    \ 
    Z------Y------X 

F과의 압박받은 커밋 10.

A-----B------C------D------E------F------G------H 
\ 
    \ 
    Z------C------D------E------F------G 

JGit에서이 작업을 수행 할 수있는 직접적인 방법이 있나요 :

내가 원하는

아래 중간 결과를 피하기? MergeCommand, CherryPickCommandRebaseCommand을보고 있었지만 중간 결과를 피하면서이를 수행하는 방법을 잘 모르겠습니다. 나는 많은 JGit 예제를 찾을 수 없다. 어떤 제안이라도 도움이 될 것입니다.

+1

*** 스쿼시 ***는 C, D 및 E를 커밋하고 "병합"하지 않으려는 것처럼 들립니다. "병합"은 git에서 두 가지 개발 영역을 병합하는 것과 매우 구체적인 의미가 있습니다. 하지만 두 개의 분기를 병합하지 않고 일련의 커밋을 결합하려고합니다. 자식 (git)에서 여러 가지 방법이 있습니다 : (1) rebase, (2) cherry-pick, 부드러운 재설정과 재시작. 이 작업을 수행하는 배관 공구가 더 많이 있습니다. 나는 JGit에 대해 어느 정도 익숙하지는 않지만 어떤 종류의 도구를 사용할 수 있는지에 관해 조언합니다. –

답변

3

나는 CherryPickCommandRebaseCommand을 사용하여 해결책을 찾았습니다. 위의 예제를 사용하여 지점을 Z으로 전환합니다.

A-----B------C------D------E------F------G------H 
\ 
    \ 
    Z 

그럼, 체리 C, DE 각 커밋에 대한 .include(RevCommit) 사용하여 RevCommits을 선택합니다. 그럼 아래 그림의 결과로, 나의 새로운 브랜치에 커밋을 추가 .call()를 사용

A-----B------C------D------E------F------G------H 
\ 
    \ 
    Z------C------D------E 

다음, 나는 하나에 C, DERebaseCommand와 커밋 스쿼시. 먼저, 상류 commi를 .setUpstream("HEAD~3")으로 설정하여 3 커밋을 되돌립니다. 그럼 아래와 같이 콜백 함수를 사용하여 대화 형 처리기를 실행

runInteractively(new InteractiveHandler() { 
        @Override 
        public String modifyCommitMessage(String commit) 
        { 
         return rebaseMessage; 
        } 
        @Override 
        public void prepareSteps(List<RebaseTodoLine> steps) 
        { 
         try 
         { 
          steps.get(0).setAction(RebaseTodoLine.Action.PICK); 
          for (int j = 1; j < steps.size(); j++) 
          { 
           RebaseTodoLine step = steps.get(j); 
           step.setAction(RebaseTodoLine.Action.SQUASH); 
          } 
         } 
         catch (IllegalTodoFileModification e) 
         { 
          System.out.println("Cannot prepare step: " + e); 
          e.printStackTrace(); 
         } 
        } 
       }); 

이 효과적으로 당신이 작업을 리베이스 정상 자식에서 볼 수있는 대화 형 명령 프롬프트에 대한 지침을 제공합니다.

A-----B------C------D------E------F------G------H 
\ 
    \ 
    Z------Y 

: 자, 다음과 같이 내 REPO 보인다

Y는 숙청이

를 C, D의 커밋 및 E입니다 그리고 바로 그거야!

예제를 마치려면 FG에 대해 동일한 작업을 수행합니다.

한 번의 이동으로 커밋을 추가하고 스쿼시하는 직접 방법이 있다면 매우 유용합니다.입니다. 현재로서는 이것이 작동하고 전체 지점의 중복을 방지합니다.

+0

커밋이 머리에있는 경우에만 작동합니다. 머리에없는 커밋을 스쿼시하려면 http://stackoverflow.com/questions/26029698/git-squashing-consecutive-commits-that-are-not-themost-recent-commits-and-do – modulitos

+0

을 참조하십시오. 나는 JGit을 모른다. 그러나 Git에서는 약간 더 멋지다 (C, D, E가 위치 한 후에) : git checkout Z; git merge --squash E; 자식 커밋; (최종 커밋은 Y가됩니다). –

관련 문제