Hãy bỏ qua --onto
ngay bây giờ. upstream
và branch
khá cơ bản, và thực sự sắp xếp bắt chước checkout
và branch
- đối số thứ hai là tùy chọn:
git branch <newbranch>
git branch <newbranch> <base>
git checkout -b <newbranch>
git checkout -b <newbranch> <base>
git rebase <upstream>
git rebase <upstream> <branch>
(Ngoài ra, tên của các đối số này trong rebase
"thượng nguồn" và "nhánh" không phải là IMO mô tả. Tôi thường nghĩ về chúng như Peachoftree, <start>
và <end>
, đó là cách tôi sẽ sử dụng chúng git rebase <start> <end>
:)
Khi nhánh thứ hai bị bỏ qua, kết quả gần giống như lần đầu tiên kiểm tra nhánh đó và sau đó thực hiện nó như thể bạn chưa chỉ định nhánh đó. Ngoại lệ là branch
không thay đổi chi nhánh hiện tại của bạn:
git checkout <base> && git branch <newbranch> && git checkout <previous_branch>
git checkout <base> && git checkout -b <newbranch>
git checkout <end> && git rebase <start>
Để hiểu những gì rebase
khi được gọi, đầu tiên tôi bắt đầu bằng cách nghĩ về nó như một kiểu hợp nhất đặc biệt. Nó không thực sự, nhưng nó đã giúp khi lần đầu tiên bắt đầu hiểu về rebase. Để mượn ví dụ của Peachoftree:
A--B--F--G master
\
C--D--E feature
Một git merge master
kết quả trong việc này:
A--B--F-----G master
\ \
C--D--E--H feature
Trong khi một git rebase master
(trong khi trên nhánh feature
!) Kết quả trong việc này:
A--B--F--G master
\
C'--D'--E' feature
Trong cả hai trường hợp, feature
bây giờ chứa mã từ cả hai master
và feature
. Nếu bạn không bật feature
, đối số thứ hai có thể được sử dụng để chuyển sang đối số dưới dạng phím tắt: git rebase master feature
sẽ thực hiện tương tự như trên.
Bây giờ, cho đặc biệt --onto
. Phần quan trọng cần nhớ với điều này là nó mặc định <start>
nếu không được chỉ định. Vì vậy, ở trên, nếu tôi chỉ định --onto
cụ thể, điều này sẽ dẫn đến cùng:
git rebase --onto master master
git rebase --onto master master feature
(Tôi không sử dụng --onto
mà không chỉ định <end>
đơn giản vì dễ phân tích tâm lý hơn, thậm chí còn nghĩ hai cái đó giống nhau nếu đã bật feature
.)
Để xem tại sao --onto
hữu ích, đây là một ví dụ khác. Giả sử tôi đã gặp phải feature
và nhận thấy một lỗi, sau đó tôi đã bắt đầu sửa lỗi - nhưng đã phân nhánh feature
thay vì master
nhầm lẫn:
A--B--F--G master
\
C--D--E feature
\
H--I bugfix
Điều tôi muốn là "di chuyển" những cam kết này bugfix
để chúng không còn phụ thuộc vào feature
. Như vậy, bất kỳ loại hợp nhất hoặc rebase nào được hiển thị ở trên trong câu trả lời này sẽ có ba feature
cam kết cùng với hai bugfix
cam kết.
Ví dụ, git rebase master bugfix
là sai. Phạm vi <start>
để <end>
xảy ra để bao gồm tất cả các cam kết từ feature
, được tái hiện lại trên đầu trang của master
:
A--B--F--G master
\ \
\ C'--D'--E'--H'--I' bugfix
\
C--D--E feature
Những gì chúng ta thực sự muốn là một loạt các cam kết từ feature
để bugfix
được tái hiện lại trên đầu trang của master
. Đó là những gì --onto
dành cho - chỉ định mục tiêu "phát lại" khác với nhánh "bắt đầu":
git rebase --onto master feature bugfix
A--B--F--G master
\ \
\ H'--I' bugfix
\
C--D--E feature