힘내

2017-04-06 2 views
3

을 리베이스 변경 전 3 개 지점을 가지고힘내

나는 버그 수정

내 기능을 테스트하기 위해 "자식 버그 수정 기능을 리베이스"않았다
4-5-6(feature) 
    | 
1-2-3(master) 
    | 
    7(bugfix) 

1-2-3(master) 
     | 
     7(bugfix)-4-5-6(feature) 

는 지금은 버그 수정없이 제 기능을 지점에 대한 끌어 오기 요청을 만들 리베이스해야하는, 그래서 "자식 마스터 기능을 리베이스"를 기대했다 :

1-2-3(master)-4-5-6(feature) 
    | 
    7(bugfix) 

대신 기능이 master로 최신이라고 말합니다. 그건 사실이지만 거기에 커밋 7을 병합하고 싶지는 않습니다. 대화 형 리베이스를 수행하고 커밋을 제거 할 수 있지만이를 수행하는 더 좋은 방법이 있는지 알고 싶습니다. rebase는 하나의 브랜치에있는 커밋을 다른 브랜치에만 전달한다고 생각했지만 그렇지 않은 것처럼 보입니다.

답변

2

리던던시가 히스토리를 재 작성하거나 커밋을 이동하지 않는다는 사실을 깨닫게되면 힘내에서 커밋을 변경할 수 없습니다. 대신, 그것은 새로운 역사를 창조하고 그것이 그 길을 따라 갔다고 말합니다. 예를 들어, 시작 때

4-5-6(feature) 
    | 
1-2-3(master) 
    | 
    7(bugfix) 

그리고 git rebase bugfix feature 정말로 일이 이것이다 :

4-5-6 
    | 
1-2-3(master) 
    | 
    7(bugfix)-4A-5A-6A(feature) 

세 가지 새로운 커밋, 4A, 5A 및 6A를 만들어집니다. 원래의 커밋은 여전히 ​​존재하지만 아무것도 가리 키지 않습니다. 그들은 결국 정리 될 것이지만, 그들은 며칠 동안 거기 머무를 것입니다.

즉, 사용자가하려는 작업 인 rebase를 실행 취소 할 수 있습니다. rebase 바로 앞에 feature이 어디에 있는지 찾아야합니다. 그것은 HEAD이 움직일 때마다 추적하는 git reflog으로 수행 할 수 있습니다. 이는 checkout, commit, resetrebase으로 발생합니다. git reflog 일 수 있습니다 뭔가 같은 : a9fd2f1 그것이으로 업데이트되기 전에 마지막으로이 기능을 저지했다 알려줍니다

65e93ca (HEAD -> feature) [email protected]{0}: rebase finished: returning to refs/heads/feature 
65e93ca (HEAD -> feature) [email protected]{1}: rebase: 3 feature 
6d539a3 [email protected]{2}: rebase: 2 feature 
3cd634f [email protected]{3}: rebase: 1 feature 
b84924b (bugfix) [email protected]{4}: rebase: checkout bugfix 
a9fd2f1 [email protected]{5}: commit: 3 feature 
29136bc [email protected]{6}: commit: 2 feature 
60543b0 [email protected]{7}: commit: 1 feature 
c487530 (master) [email protected]{8}: checkout: moving from master to feature 

. 리베이스를 재실행하는 대신, 필자는 단지 기능을 되돌릴 수 있습니다. 당신이 REBASE을하기 전에 기능의 원래 위치를 git tag 경우 향후

git checkout feature 
git reset --hard a9fd2f1 

는 이런 종류의 물건이 훨씬 쉬워졌다. 그런 다음 reflog를 검색 할 필요없이 git reset을 해당 태그로 되돌릴 수 있습니다. 당신이 git rebase master feature을 물어 보면

6A [feature] 
| 
5A 
| 
4A 
| 
7 [bugfix] 
| 
3 [master] 
| 
2 
| 
1 

이 망할 놈의 마스터가 이미 기능의 조상이며 않는다는 것을 노트 : 특정 문제에 관해서는


는 문제는 REBASE 후 저장소가 지금과 같은 것입니다 아무것도. bugfix가 중간에있는 것은 중요하지 않습니다.

대신, 당신은 단지 4A, 5A, 6A를 rebase하고 7을 무시하고 싶다는 것을 Git에게 알려줘야합니다. 이것은 --onto 구문을 사용하여 이루어졌습니다.

git rebase --onto master bugfix feature 

마스터에 기능을 버그 수정하지 않고 포함시키지 않는 것이 있습니다.

rebase를 다시 시도하는 대신 git reset을 사용하는 것이 좋습니다. 특히 충돌이있는 경우 두 번째 rebase가 동일하게 나올 것이라는 보장은 없습니다. git reset을 사용하는 경우 명시 적으로 저장소의 이전 상태로 다시 이동합니다.

+0

감사합니다! git rebase --onto는 내가 필요한 것입니다. bugfix에 rebase 한 후에 변경하지 않은 경우 git reflog가 작동합니다. – chohocvo

2

rebase는 하나의 브랜치에서만 커밋을 수행하지만 그렇지 않은 것처럼 보일 것이라고 생각했습니다.

가 핵심이다 : 당신의 이 지점 feature에서 당신의 그림에 7을 커밋합니다. 또한 지사 bugfix에 있습니다. 커밋 1-2-3세 가지 모두 가지입니다.

힘내는 다른 대부분의 버전 제어 시스템과 매우 다릅니다. 브랜치는 브랜치 이름이 가리키는 커밋에서 커밋에 "도달"할 수있는 경우에만 커밋을 "포함"합니다. master, bugfixfeature과 같은 분기 이름은 중 하나를 가리키며, 커밋 중 하나입니다. Git은 분기의 을 호출합니다. 그것은 각각의 커밋이 전임자에게 "되돌아 가도록"함으로써 체인을 형성하는 커밋 자체입니다. 이 때문에

, git rebase 실제로 복사 커밋 :

 4--5--6 <-- feature 
    /
1--2--3  <-- master 
     \ 
     7  <-- bugfix 

에 : 당신의 간 D 원래 4사본입니다

 4--5--6 [abandoned - used to be feature] 
    /
1--2--3  <-- master 
     \ 
     7  <-- bugfix 
     \ 
      D--E--F <-- feature 

, E5F 사본은 6 (I us 4 번째, 5 번째, 6 번째 글자를 편집하여 예를 들어 G을 7로 복사 할 수 있습니다. 원한다면이 기술은 거의 사용되지 않습니다.

그래도 원하는 것을 얻을 수 있습니다. 사본을D-E-F 다시 입력해야합니다. 또는이 특정 사례의 경우 더 좋을 것입니다. 그냥 원래의 4-5-6으로 돌아갑니다.

git rebase을 사용하여 커밋을 복사하면 원본이 계속 붙습니다. 찾을 수있는 이름은 두 가지가 있습니다. ORIG_HEADreflog입니다. 이름 ORIG_HEAD는 다양한 다른 명령을 덮어 씁니다,하지만 당신은 여전히 ​​6를 저지를 가리키는 것 있는지 확인할 수 있습니다 :

git log ORIG_HEAD 

당신은 아마 당신의 원본을 인식합니다.

reflog 이름의 형식은 name@{number}입니다 (예 : [email protected]{1}).number 일부 단위는 커밋 변경할 때마다하는에 name 부품 점, 힘내 단순히 나머지 모든 최대 노치를 밀어 reflog에 name의 현재 값을 저장한다. 따라서

:

git log [email protected]{1} 

은 (시간이 지남에 아마, 등등 [email protected]{2}, [email protected]{3}, 그리고이되는) 당신의 주위에 이상 해당 [email protected]{1} 스틱을 제외하고 git log ORIG_HEAD 같은 커밋을 표시해야합니다. 기본적으로 각 이름의 이전 값은 30 일 이상 저장되므로 다시 가져올 충분한 시간이어야합니다. 아직 확인하지만 (

git reset --hard [email protected]{1} 

또는 숫자가 무엇이든 :

feature ( git checkout feature)에 동안 실행 한 후 @{...} 부분에 가서 어떤 수를 볼 수 git reflog feature를 사용하여, 그것을 다시 얻으려면 다시 git log 처음으로 좋은 생각입니다).

은 (git reset --hard가 지워 버리고 없습니다 아직 확인 된 인덱스와 작업 트리의 변화 때문에, 당신은 git status 모든 것이 깨끗 말한다 즉 것을, 체크인 아무것도하지 않는 가정합니다.)

+0

1 차 리베이스 이후에 변경 한 경우에는 작동하지 않습니다. 예. D - E - F - 8 <- 특징. 이것을 취소하지 않으면 8을 수행 할 수 없으며 체리로 선택해야합니다. – chohocvo

+0

맞습니다. 또는 rebase의 * target *을 분리 할 수있는'git rebase --onto'를 사용하여 다시 rebase 할 수 있습니다. 즉, 복사본을 어디에 둘 것인지 "를 결정합니다. 일반적으로 단일 분기 이름으로 지정됩니다. – torek