git log
명령은 ajryan/dev
에는 있지만 temp-a
에는없는 커밋을 표시합니다. rebase
명령은 temp-a
에있는 커밋을 리베이스하지만, ajryan/dev
에는 커밋되지 않은 커밋을 리베이스하라는 명령을 받았지만 커밋이없는 것으로 추정됩니다. 그림으로 :
... - o - o - o <-- HEAD=temp-a
\
o - o - o - * <-- ajryan/dev
따라서, 픽업하여이 나는 스타 *
표시 한 커밋에 리베이스 할 커밋이 없습니다. 따라서 rebase -i
은 단일 no-op 명령을 생성합니다.
당신은 어떤 조합이의 REBASE 작업이 *
를 저지하기 위해 temp-a
지점을해야하는 마지막이 *
이후에 추가 된 커밋을 가리 키도록 temp-a
를 이동하여 결론없는 것을 실행합니다. (그런 일이 발생하지 않으면 rebase
의 작은 버그입니다.) 아무 작업도 삭제하지 않으면 rebase 작업이 중단되고 temp-a
은 이동되지 않습니다. 당신 그랬다면은 당신이 그들을 리베이스, 또는 다른 지점을 리베이스 수 temp-a
에 다른 항목을 가지고
는
참고. 여기 ajryan/dev
에없는 거의 동일한 기본부터 시작하여 두 개 더 그림은,하지만 하나의 커밋으로 그 temp-a
에있다 :
이 경우
... - o - o - o - @ <-- HEAD=temp-a
\
o - o - o - * <-- ajryan/dev
, 당신은 @
이 다른 커밋의 상부에 커밋 넣을 수 있습니다 :
... - o - o - o
\ (illustration 1)
o - o - o - * - @
또는 다른 커밋 아래 바닥에
: 내가 레이블을 떠난
다음
... - o - o - o
\ (illustration 2)
@ - o - o - o - *
(및 ajryan/dev
). 이것은 의도적으로 : git에서, 브랜치 레이블은 쉽게 옮겨 질 수 있습니다 (실제로는 "forward"방식 인 한 이으로 이동해야합니다); 모든 실제 branch-iness는 커밋 자체에 저장됩니다. git rebase
이 실제로하는 일은 사본입니다. 오래된 것은 새로운 것으로 커밋되므로 부모의 연령 및/또는 콘텐츠를 변경할 수 있습니다.
일러스트레이션 # 1에서 우리는 @
커밋을 다시 적용했습니다 : 이제는 *
을 부모로 커밋했습니다. 다른 모든 커밋은 변경되지 않으므로 @
커밋 만 복사해야합니다.
그러나 일러스트레이션 # 2에서는 원래 ajryan/dev
에만 있었던 커밋 체인 전체를 다시 사용했습니다. Commit @
그 자체는 변경되지 않았지만 원래 o - o - o - *
커밋 4 개 모두를 복사해야했습니다. 첫 번째 o
을 복사하여 부모를 @
으로 설정했습니다. 이 새로운 커밋에는 새롭고 다른 SHA-1 ID가 있으므로 두 번째 o
을 복사하여 새 커밋의 ID를 부모로 사용합니다. 이 두 번째 사본은 강제로 세 번째 사본을 강제 실행 한 후 *
의 마지막 사본을 강제 실행합니다. 그것에 대해 나쁠 수있는 것에 관해서 다음 섹션을보십시오. 커밋의 두 개의 서로 다른 체인에 가입 자식에
, 당신은 일반적으로
git merge
을 사용합니다 : 여기
A - B
/ \
... - o M <-- HEAD=branch
\ /
C - D
는
M
이
o
으로부터 포크 두 체인
A - B
및
C - D
에 가입 커밋 병합합니다.
A
에서
D
까지 모두 존재하고 새로운 커밋
M
을 만들면
A
에서
D
까지 아무 일도 일어나지 않습니다. 이전과 여전히 동일합니다.
단순한 개발을 위해 C
과 D
을 A - B
의 "맨 위에"앉게 만드는 것이 더 일반적입니다. 하지만 당신은 을 복사해야합니다. 왜냐하면 git에서의 커밋은 영구적이고 변하지 않기 때문입니다. C
을 새 것으로 약간 다른 C'
으로 복사하고 으로 약간 다른 D
으로 복사합니다. REBASE 복사가 완료되면
A - B - C' - D' <-- HEAD=branch
/
... - o
\
C - D [abandoned]
, 당신을 : C'
다른 점 중요한 것은 부모가 B
하지 o
, 약 D'
부모가 C'
하지 C
점이다 다르다 중요한 것은 때문이다 단순히 이전 C
및 D
커밋을 포기하고 C'
척 시작하고 D'
원래 커밋했다 :
A - B - C - D <-- HEAD=branch
/
... - o
이제 우리는 더 긴하지 어 우리가 원래 C
및 D
에 대한 모든 잊어 버린 이후 그래프에서 약간의 꼬임을해야하고, 역사는 바로 다음과 같습니다
... - o - A - B - C - D <-- HEAD=branch
더러운 비밀 (그래서 비밀하지가 아니라 그 더러운)이라는 원래 C
과 D
은 여전히 입니다.은 (당신에게) 보이지 않습니다. 실제로 더럽혀지는 부분은 누군가 다른 사람은 원래 두 C
과 D
커밋을가집니다. Git 커밋 ID는 부모 SHA-1 ID를 포함하여 콘텐츠의 암호화 체크섬이므로 원래 C
및 D
은 여전히 존재하며 은 과 D
에서 다른과 다릅니다.
다른 사람으로부터 커밋을 가져올 때 이것은 중요합니다. 커밋을 작업에 리베이스하면 이으로 변경됩니다.새 사본을 만들 때 원본이 있다는 것을 잊어 버릴 수도 있지만 새 사본은 아직 알지 못하며 은은 원래 ID를 잊어 버리지 않았습니다.
나중에 커밋의 리베이스 복사본을 제시하면 커밋 복사본을 선택하고 수행 한 추가 작업을 이동해야합니다. 간단히 말해, 사전에 누군가와 계약을 맺지 않았다면 일러스트레이션 # 2에 표시된 것과 같은 rebase는 일반적으로 좋은 생각이 아닙니다.
"빨리 감기"는 어떤가요? 음, 일러스트레이션 # 1을 다시 한번 살펴 보겠습니다. o - o - o - @
체인이 다른 누군가 ("pull request")로부터 왔다고 가정하고, 자신의 작업을 리베이스하여 그 위에 *
커밋을 추가한다고 가정 해 봅시다. 또 하나 개의 꼬임을 추가의 너무 그래프를 다시 그려 보자, 다시 ajryan/dev
라벨을 넣어 :
... - o - o - o [your original '@' commit, before rebasing, was here]
\
o - o - o - * <-- ajryan/dev
\
@ <-- HEAD=(something, maybe "dev")
을 이제 더 그들은, 그들이 누구든지, 자신의 dev
분기에 o - o - o - *
순서를 가지고하지 않은 것으로 가정하자 어떤 추가 작업, 그들의 물건은 *
이라고 표시된 커밋에서 끝납니다. 이 커밋 시퀀스를 사용할 수있게되면 dev
레이블을 아래쪽 및 오른쪽으로 이동하여 @
레이블을 가리 키도록 dev
브랜치에 커밋 @
을 추가 할 수 있습니다. 이제 ajryan/dev
레이블을 지우고이 도면의 꼬임을 곧게 자르고 dev
레이블을 사용하십시오.
... - o - o - o - o - o - o - * - @ <-- HEAD=dev
이 그들이이있을 것이다 것입니다, 당신은 동기화 모두있어 일단 당신이,이 무슨 다음은 결과입니다. 실제 개발 과정에서 약간 벗어난 경우에도 매우 간단합니다. *
으로 끝나는 체인을 처음 보지 않고 커밋 @
을 작성했습니다. 그러나 이것은 개발 작업을 훨씬 쉽게 수행 할 수있게 해주는 일종의 "리베이스 (rebase)"이며 일반적으로 사람들이 원하는 일입니다.
레이블 "오른쪽으로"(위 그림과 같이 오른쪽 아래 또는 오른쪽 포함) 슬라이딩은 "빨리 감기"조작입니다. --ff-only
을 사용하여 git merge
을 실행하면 실제로 이러한 종류의 병합되지 않은 빨리 감기 인 경우에만 "병합"을 수행합니다.
결론 : 나는 당신이 @
이 ajryan/dev
작업에 커밋 리베이스 싶었지만, 그렇지 가@
이 리베이스 커밋해야했다 생각합니다. 그래서 rebase가 noop
을주었습니다. 이 경우 간단한 병합되지 않은 빨리 감기 git merge
만 있으면 레이블을 해당 레이블과 일치시킬 수 있습니다.
또한 이것에 대해 생각하는 가치 : 당신이 git log X..Y
을 할 때 내가 여기처럼 그래프를 그릴 자식을 요구하고 :
... - o - o - o <-- X
\
o - o - o <-- Y
X..Y
개념은 본질적으로 말한다 :이 그래프로 시작, 형광펜을 꺼내서 X
이 가리키는 커밋을 강조 표시하고 커밋을 모두 왼쪽에서 및/또는 위 또는 아래로 커밋합니다.그러면 3 개의 o
이 지정되고 Y
의 표시가 해제됩니다. 그런 다음 강조 표시되지 않은 Y
이 가리키는 모든 커밋을 찾아서 기록하십시오. 당신이 git log Y..X
에서와 X
및 Y
, 반대 경우
, 당신은 X
에만 두 o
유일의 잎 Y
로 표시 커밋에 "하이 라이터를 실행"을 자식에게, 그리고 모든 지적-에 커밋 로그 X
에 의해 강조 표시되어 있지 않습니다. 그래서 여기 X에서 두 개의 o
을 얻습니다.
만약'temp-a'가'ajryan/dev'의 조상이라면 나는 이것이 가능하다고 생각합니다. –