Sự khác biệt giữa git pull và git pull --rebase


311

Thỉnh thoảng tôi bắt đầu sử dụng git và không hiểu hết những điều 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 a git pullgit pull --rebase, vì việc thêm --rebasetùy chọn dường như không làm điều gì đó rất khác: chỉ cần thực hiện một thao tác kéo.

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



3
Có thể trùng lặp git pull VS git fetch git rebase
TJ

Câu trả lời:


326

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

git pull --rebase= git fetch+ git rebasechố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 rebasekhác nhau, đọc này .


12
Điều đáng chú ý là nói git pull --rebasegiống như git fetchgit rebasevề cơ bản là như vậy, nhưng nó không hoàn toàn tương đương về mặt ngữ nghĩa. Có một số khác biệt, một số trong đó được giải thích ở đây. gitolite.com/git-pull--rebase
w0rp

8
Đó là những gì tôi sẽ gọi là "lời nói dối tiện lợi", để 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

Rất ngắn gọn. Tôi không thể hiểu sự khác biệt. Điều gì rất quan trọng về fetch?
Xanh

240

Đôi khi chúng ta có một dòng ngược dòng / khởi động lại một nhánh mà chúng ta 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 xuôi dòng.

Điều 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 ta sẽ sử dụng một nguồn gốc được gọi là từ xa và một nhánh được gọi là foo trong tất cả các ví dụ này):

# 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 thực hiện điều này:

git fetch origin
git rebase origin/foo

Nhưng điều đó sẽ không giúp ích gì nếu cuộc nổi loạn ngược dòng liên quan đến bất kỳ sự "đè bẹp" nào (có nghĩa là các bản vá lỗi của các xác nhận đã thay đổi, không chỉ là thứ tự của chúng).

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

Giả sử điểm xuất phát 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 "foo" của riêng bạn:

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

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

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

Một git kéo 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" ở bên kia, sẽ xung đột. (Và tương tự với d, e và d + e).

Có gì git pull --rebasekhông, trong trường hợp này, đó là:

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

Điều này mang lại cho bạn:

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

Bạn vẫn có thể có xung đột, nhưng chúng sẽ là xung đột thực sự (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.

Câu trả lời được lấy từ (và sửa đổi một chút):
http://gitolite.com/git-pull--rebase


9
Đây là câu trả lời tốt 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ì rebase thay đổi băm.
Bastien

22
Câu trả lời này đã được sao chép và dán nguyên văn từ gitolite.com/git-pull--rebase và nên bao gồm phân bổ theo giấy phép trên trang đó.
tự đại diện

Đây là một lời giải thích tuyệt vời. Nhưng tôi đã có một tình huống, nơi tôi đã cam kết A, và tôi đã gửi một PR cho repo ngược dòng được chấp nhận. Sau đó, khi tôi git pull --rebasechống lại repo ngược dòng, tôi đã không nhận được một A'cam kết mới trên đầu repo ngược dòng. Trong thực tế không A'tồn tại chút nào. Đây có phải là vì Ađã được sáp nhập vào hệ thống? Hay là bởi vì không có sự khác biệt giữa phiên bản ngược dòng và phiên bản nổi loạn của tôi?
CMCDragonkai

Tôi hiện đang xem hướng dẫn về Git và đang sử dụng phản hồi này để hiểu thêm về a git pull --rebase. Nhưng một điều khiến tôi bối rối trong tình huống giả định này là người duy trì thượng nguồn đã thay đổi lịch sử dự án đã bị kéo vào kho lưu trữ của nhà phát triển địa phương. Đây không phải là thực tế xấu nói chung? Nếu anh ta muốn xóa sổ cam kết / viết lại lịch sử, thì nó nên được thực hiện trước khi tích hợp nó vào kho lưu trữ trung tâm để tránh những xung đột kiểu này.
bmcentee148

44

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 khi "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

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

5
@prgmrDev Tại sao D và E sẽ được chèn trước F?
Jon

1
Nó không chính xác là những gì git rebasekhông? Nhưng chúng ta đang nói về git pull --rebase. Và chúng là những thứ khác nhau.
Xanh

10

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

  • với rebase: khởi động lại các cam kết cục bộ của bạn ontop của HEAD từ xa và không tạo ra một cam kết hợp nhất / hợp nhất
  • không có / bình thường: hợp nhất và tạo ra một cam kết hợp nhất

Xem thêm:

man git-pull

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

Xem thêm:
Khi nào tôi nên sử dụng 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 theo cách thủ công và sau đó - tiếp tục với rebase: git sdd modified-file; git rebase --continuehoặc merge: git add modified-file; git commit;đâu modified-filelà tệp cục bộ mà bạn đã sửa đổi bằng tay /
mergetool

Có gì đặc biệt fetch? Tại sao họ tạo ra hai rebasedòng chảy? 1) git rebasevà 2) git pull --rebase?
Xanh

7

Đối với điều này là quan trọng để hiểu sự khác biệt giữa Hợp nhất và Rebase.

Sự nổi loạn là cách các 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 chảy ngược lên trên.

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


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 rõ ràng trên phần còn lại của các câu trả lời ở trên. Cảm ơn.
Aaron C
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.