2013-09-21 54 views
213

Tôi bắt đầu sử dụng git đôi khi trở lại và không hoàn toàn hiểu được sự phức tạp. Câu hỏi cơ bản của tôi ở đây là tìm ra sự khác biệt giữa một số git pullgit pull --rebase, vì việc thêm tùy chọn --rebase dường như không làm điều gì đó rất khác nhau: chỉ cần thực hiện thao tác kéo.Sự khác biệt giữa git pull và git pull --rebase

Hãy giúp tôi hiểu sự khác biệt.

+6

Liên quan: [Khi nào tôi nên sử dụng git pull --rebase?] (Http://stackoverflow.com/q/2472254/456814). –

+2

Bản sao có thể có của [git pull VS git fetch git rebase] (http://stackoverflow.com/questions/3357122/git-pull-vs-git-fetch-git-rebase) –

+0

Liên kết hữu ích: https: // www. atlassian.com/git/tutorials/rewriting-history/git-rebase –

Trả lời

236

git pull = git fetch + git merge chống theo dõi chi nhánh thượng nguồn

git pull --rebase = git fetch + git rebase chống theo dõi chi nhánh thượng nguồn

Nếu bạn muốn biết làm thế nào git mergegit rebase khác nhau, read this.

+8

Cần lưu ý rằng 'git pull --rebase' giống với' git fetch' và 'git rebase' về cơ bản nó như thế nào , nhưng nó không * chính xác * tương đương ngữ nghĩa. Có một số khác biệt, một số được giải thích ở đây. http://gitolite.com/git-pull--rebase – w0rp

+4

Đó là những gì tôi sẽ gọi là "nói dối thuận tiện", để mượn một cụm từ từ Scott Meyers. Đó là một cách tốt để giải thích nó bất kể. – w0rp

9

Trong trường hợp rất nhất đơn giản không có va chạm

  • với rebase: rebases địa phương cam kết của bạn ontop TRỤ từ xa và làm không tạo ra một hợp nhất/hợp nhất cam kết
  • mà không/bình thường: hòa trộn và tạo ra một hợp nhất cam kết

Xem thêm:

man git-pull

Chính xác hơn, git pull chạy git fetch với tham số đã cho và gọi git merge để hợp nhất các nhánh nhánh đã truy cập vào chi nhánh hiện tại. Với --rebase, nó chạy git rebase thay vì git merge.

Xem thêm:
When should I use git pull --rebase?
http://git-scm.com/book/en/Git-Branching-Rebasing

+3

Và trong trường hợp va chạm? – Rndm

+1

Bạn sẽ được yêu cầu giải quyết chúng bằng tay và sau đó - tiếp tục với rebase: 'git sdd modified-file; git rebase --continue' hoặc merge: 'git add modified-file; git commit; 'where' modified-file' là tệp cục bộ của bạn mà bạn đã sửa đổi bằng tay/mergetool – drahnr

187

Thỉnh thoảng chúng tôi có một thượng nguồn đã khôi phục/tua lại nhánh mà chúng tôi đang phụ thuộc vào. Đây có thể là một vấn đề lớn - gây ra xung đột lộn xộn cho chúng ta nếu chúng ta hạ lưu.

Sự kỳ diệu là git pull --rebase

Một git pull bình thường là, nói một cách lỏng lẻo, một cái gì đó như thế này (chúng tôi sẽ sử dụng một từ xa gọi xuất xứ và một chi nhánh gọi là foo trong tất cả các ví dụ):

# assume current checked out branch is "foo" 
git fetch origin 
git merge origin/foo 

Thoạt nhìn, bạn có thể nghĩ rằng một git pull --rebase chỉ thực hiện điều này:

git fetch origin 
git rebase origin/foo 

Nhưng điều đó sẽ không giúp đỡ nếu rebase thượng nguồn liên quan đến bất kỳ "squashin g "(có nghĩa là các bản vá-id của các cam kết đã thay đổi, không chỉ là thứ tự của chúng).

Nghĩa là git pull --rebase phải làm nhiều hơn một chút. Đây là một giải thích về những gì nó làm và làm thế nào.

Hãy nói rằng điểm khởi đầu của bạn là thế này:

a---b---c---d---e (origin/foo) (also your local "foo") 

Thời gian trôi qua, và bạn đã thực hiện một số cam kết trên đầu trang của "foo" của riêng bạn:

a---b---c---d---e---p---q---r (foo) 

Trong khi đó, trong một cơn chống lại cơn thịnh nộ xã hội, người duy trì thượng lưu đã không chỉ rebased "foo" của mình, ông thậm chí còn sử dụng một squash hoặc hai. Chuỗi cam kết của anh bây giờ trông giống như sau:

a---b+c---d+e---f (origin/foo) 

Việc kéo git vào thời điểm này sẽ dẫn đến hỗn loạn. Ngay cả một git lấy; git rebase origin/foo sẽ không cắt nó, bởi vì cam kết "b" và "c" ở một bên, và cam kết "b + c" trên cái kia, sẽ xung đột. (Và tương tự với d, e, và d + e).

git pull --rebase không, trong trường hợp này, là:

git fetch origin 
git rebase --onto origin/foo e foo 

này mang đến cho bạn:

a---b+c---d+e---f---p'---q'---r' (foo) 

Bạn vẫn có thể nhận được các cuộc xung đột, nhưng họ sẽ có những xung đột chính hãng (giữa p/q/r và a/b + c/d + e/f) và không xung đột do b/c xung đột với b + c, v.v.

trả lời lấy từ (và một chút thay đổi):
http://gitolite.com/git-pull--rebase

+6

Đây là câu trả lời hay nhất. Bạn có thể muốn thay đổi kết quả cuối cùng thành 'a --- b + c --- d + e --- f --- p '--- q' --- r '(foo)' vì các thay đổi rebase băm . – Bastien

+1

Đã thay đổi, cảm ơn bạn đã chỉ ra @Bastien –

+9

Câu trả lời này đã được sao chép và dán nguyên văn từ http://gitolite.com/git-pull--rebase và phải bao gồm thuộc tính cho mỗi giấy phép trên trang đó. – Wildcard

5

Đối với điều này là quan trọng để hiểu sự khác biệt giữa Merge và rebase.

Rebases là những thay đổi sẽ chuyển từ đầu phân cấp xuống dưới và hợp nhất là cách chúng chuyển ngược lên trên.

Để biết chi tiết tham khảo - http://www.derekgourlay.com/archives/428

+0

Tôi nghĩ rằng câu trả lời của bạn cung cấp một lời giải thích đơn giản hơn nhiều mà không phải là rõ ràng trên phần còn lại của câu trả lời ở trên. Cảm ơn. –

+0

Chào mừng @Aron C –

30

Giả sử bạn có hai cam kết trong chi nhánh địa phương:

 D---E master 
    /
A---B---C---F origin/master 

Sau "git pull", sẽ là:

 D--------E 
    /  \ 
A---B---C---F----G master, origin/master 

Sau "git pull --rebase ", sẽ không có điểm hợp nhất G. Lưu ý rằng D và E trở thành các cam kết khác nhau:

A---B---C---F---D'---E' master, origin/master 
+0

phải không A --- B --- C --- D '--- E' - F? – prgmrDev

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