2012-07-19 24 views
28

Tôi đã bắt đầu sử dụng git rebase gần đây và không chắc chắn 100% tôi đang làm đúng. Vì lợi ích của câu hỏi, có hai chi nhánh xuất xứ, masternext, được phân nhánh từ master.Thông tin cơ bản về rebit git

Kể từ khi đồng bộ cuối cùng giữa hai, master có 2 cam kết và next 6:

$ git log --oneline origin/next..origin/master 
59b5552 master commit #2 
485a811 master commit #1 

$ git log --oneline origin/master..origin/next 
4ebf401 next commit #6 
e9b6586 next commit #5 
197ada0 next commit #4 
4a2c3c6 next commit #3 
040a055 next commit #2 
84537bf next commit #1 

Khi tôi kiểm next và thực hiện git rebase -i origin/master, tôi nhận được như sau:

$ git status 
# On branch next 
# Your branch and 'origin/next' have diverged, 
# and have 8 and 6 different commits each, respectively. 

Và cuối cùng sau khi làm git pull --rebase, hai cam kết từ master nằm trong next:

$ git log --oneline origin/next..next 
8741d09 master commit #2 
485a811 master commit #1 

Câu hỏi:

  1. là cách tiếp cận đúng này?
  2. Tại sao có 8 and 6 các cam kết khác nhau cho đến khi pull --rebase được chạy?
  3. Có thể đơn giản hóa luồng không?

nhiều nghĩa vụ :)

+1

Hi David, bạn đã có nghĩa là 'git pull --rebase' thay vì 'git rebase --pull'? – MikeSep

+0

@MikeSep bạn chính xác, cố định, cảm ơn bạn. –

Trả lời

39

Hãy bắt đầu ngay từ đầu. Dưới đây là một sơ đồ của tình trạng ban đầu của bạn:

 
A-B-C (master, origin/master) 
\ 
    D-E-F-G-H-I (next, origin/next) 

Khi bạn kiểm tra ra next và rebased next vào origin/master, nó tạo ra 6 cam kết mới sau khi hai đã có trên origin/master. Những cam kết mới này có "master commit # 2" (C trong sơ đồ của tôi) như tổ tiên của chúng, không phải tổ tiên ban đầu của chúng, trong đó origin/masterorigin/next được phân tách (A trong sơ đồ), do đó băm của chúng sẽ khác nhau. Tôi tin rằng đây là lý do tại sao bạn sẽ thấy rằng next có 8 cam kết khác nhau từ origin/next: số 2 từ origin/master và cam kết 6 "đã được khôi phục" nằm trên origin/next.

Sau git checkout next ; git rebase -i origin/master, bạn nên có điều này:

 
A-B-C (master, origin/master) 
\ \ 
    \ D'-E'-F'-G'-H'-I' (next) 
    \ 
    D-E-F-G-H-I (origin/next) 

Bạn có thể thấy rằng không có next 8 cam kết mà không phải là trên origin/next, và origin/next không có 6 cam kết mà không phải là trên next. Cấp này chỉ là theo các băm SHA-1 của các cam kết. Nội dung thực tế phải khớp rất chặt chẽ nếu bạn git diff origin/next next - khác biệt sẽ chỉ hiển thị các thay đổi từ BC (như được gắn nhãn trong biểu đồ).

Khi bạn làm git pull --rebase trong khi vẫn còn trên next, rồi nó lấy thay đổi từ nguồn (điều khiển từ xa origin/next) và rebases chi nhánh hiện tại (next) vào từ xa mà. Điều này gây ra những thay đổi nằm trong số next nhưng không phải trong origin/next để xuất hiện sau origin/next trên chi nhánh next mới.Nó sẽ giống như sau:

 
A-B-C (master, origin/master) 
\ 
    D-E-F-G-H-I (origin/next) 
      \ 
       B'-C' (next) 

Nếu đây là thứ bạn muốn biểu đồ lịch sử trông như thế thì bạn đã thành công. Tuy nhiên, tôi nghi ngờ bạn thực sự muốn mọi thứ trông giống như sơ đồ giữa, đặc biệt là nếu next là một nhánh tính năng mà bạn đang làm việc trên mảnh tiếp theo của dự án và master là để sửa mã và sửa lỗi nhỏ. Nếu vậy, thì bạn nên thực hiện git push thay vì git pull --rebase để làm cho điều khiển từ xa phản ánh phiên bản lịch sử của bạn thay vì theo cách khác.

+0

Tôi giả sử 'git rebase --pull' giống như' git pull --rebase'.Nó thực hiện tìm nạp và sau đó là 'git rebase @ {u}' Vâng, đó là một lời nói dối, nhưng nó là một cách dễ dàng để suy nghĩ về nó. Nhưng vấn đề là chi nhánh địa phương của bạn được đặt lại thành @ {u} và sau đó tất cả các cam kết cục bộ trên chi nhánh cũ của bạn trước khi thiết lập lại được phát lại trên đầu những gì mà thượng nguồn có. Điều này cho phép đẩy nhanh dễ dàng. –

+0

Giả sử 'git rebase --pull' là lỗi đánh máy và phải là' git pull --rebase', thì tôi nghĩ rằng sẽ sắp xếp lại 'next' thành' D'-E'-F'-G'-H'- I'-B'-C''. Điều đó có đúng không? Nếu có, tôi sẽ chỉnh sửa câu trả lời của tôi cho phù hợp. – MikeSep

+1

Sau khi 'git pull --rebase' bạn sẽ nhận được A-D-E-F-G-H-I-B'-C '. G-p-r sẽ luôn buộc nhánh địa phương của bạn (tiếp theo) chứa tất cả các cam kết trên @ {u} (nguồn gốc/tiếp theo) và sau đó bất kỳ thứ gì duy nhất cho tiếp theo sẽ được phát lại (có thể là hoa anh đào) trên đầu trang. Xin chúc mừng git cho đủ thông minh để không cố gắng tạo D "-E" -F "-G" -H "-I" –

0

Bắt đầu với các bước rất đơn giản để rebasing chi nhánh của bạn với master; Tên;

git-rebase 

Tóm tắt;

git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>] 
     [<upstream>] [<branch>] 
git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>] 
     --root [<branch>] 
git rebase --continue | --skip | --abort | --edit-todo 

Mô tả; Giả sử lịch sử sau đây tồn tại và các chi nhánh hiện nay là "mẫu":

A---B---C sample 
     /
    D---E---F---G master 

Từ thời điểm này, kết quả của một trong các lệnh sau:

git rebase master 
git rebase master sample 

sẽ là:

A'--B'--C' sample 
       /
    D---E---F---G master 

LƯU Ý: Biểu mẫu thứ hai chỉ ngắn gọn là git checkout sample, tiếp theo là git rebase master. Khi rebase thoát khỏi mẫu sẽ vẫn là chi nhánh đã thanh toán.

Nếu nhánh thượng nguồn đã có thay đổi bạn đã thực hiện (ví dụ: vì bạn đã gửi một bản vá đã được áp dụng ở phía trên), thì cam kết đó sẽ bị bỏ qua. Ví dụ, chạy 'git rebase master` về lịch sử sau đây (trong đó A' và A giới thiệu cùng một bộ thay đổi, nhưng có thông tin committer khác nhau):

A---B---C sample 
     /
    D---E---A'---F master 

sẽ cho kết quả:

B'---C' sample 
      /
D---E---A'---F master 

Tất cả những điều này là sự hiểu biết sơ đồ về quá trình rebase. Khi bạn giải quyết các xung đột được tìm thấy sau khi nhập git rebase master giải quyết xung đột và nhập git add -u để thêm các mã đã thay đổi vào kho lưu trữ. sau khi thực hiện lệnh git rebase --continue và tiếp tục giải quyết xung đột và lặp lại lệnh;

git add -u 

git rebase --continue 

cho đến khi không có xung đột được tìm thấy. Cuối cùng lệnh cuối cùng sẽ được,

git push --force origin sample(your branch name) 
+0

để tham khảo bên ngoài theo https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html –

Các vấn đề liên quan