2017-12-02 30 views
7

Tôi nghĩ rằng tôi hiểu git pull và đây là cách tôi giải thích nó trong, cái mà tôi gọi, "thuật ngữ đơn giản":Làm thế nào để giải thích "git pull --rebase" trong thuật ngữ đơn giản?

  1. Nói chung, git pull khoảng sáp nhập một "từ xa" chi nhánh thành một "địa phương" chi nhánh.
  2. Cụ thể hơn, git sử dụng nội dung của nhánh "từ xa" để "cập nhật"/"sửa đổi" nội dung của nhánh "cục bộ".
  3. Thậm chí chi tiết hơn, nếu một tệp đã được sửa đổi trong chi nhánh "cục bộ" nhưng không nằm trong nhánh "từ xa", sau đó sau khi hợp nhất, nội dung của tệp sẽ giống với nội dung trong "địa phương" " chi nhánh. Điều ngược lại cũng đúng. Nếu một tệp đã được sửa đổi trên nhánh "từ xa" nhưng không phải trong nhánh "cục bộ", nội dung sẽ được lấy từ nhánh "từ xa".
  4. Nếu một tệp đã được sửa đổi trong cả hai nhánh ("cục bộ" và "từ xa") so với git sẽ thử để sửa đổi từ cả hai nhánh. Nếu các thay đổi xảy ra ở các vị trí khác nhau của tệp, cả hai thay đổi sẽ được áp dụng và có mặt trong nội dung của tệp sau khi hợp nhất.
  5. Nếu những thay đổi xảy ra trên cùng một nơi, chúng tôi có những gì được biết là "xung đột hợp nhất" và tôi sẽ không liên lạc trường hợp này để đơn giản.
  6. Kết quả của việc hợp nhất, chúng tôi sửa đổi kho lưu trữ "cục bộ" và do đó chúng tôi cần phải "cam kết".

Bây giờ tôi muốn nhận được cùng một loại giải thích cho git pull --rebase. Tôi không muốn sử dụng các thuật ngữ như "head", "index", "fetch", "upstream" bởi vì các thuật ngữ/khái niệm này chỉ gây nhầm lẫn cho người mới bắt đầu như tôi. Tôi biết rằng tôi cần phải học những khái niệm "tiên tiến" này và tôi làm điều đó bằng cách đọc hướng dẫn nhưng bây giờ, là một phần của quá trình học tập của tôi, tôi muốn hiểu git pull --rebase.

THÊM

Tôi nghĩ rằng tại một số điểm tôi nghe lời giải thích sau. Bởi git pull --rebase. Khi chúng ta hợp nhất, chúng ta làm nó không theo cách "đối xứng", như được mô tả ở trên. Thay vào đó, trước tiên chúng ta "quên" những thay đổi trong kho lưu trữ "cục bộ" và chỉ áp dụng các thay đổi từ kho lưu trữ "từ xa". Bằng cách đó, chúng tôi về cơ bản "sao chép" kho lưu trữ từ xa. Sau đó, chúng tôi áp dụng các thay đổi từ kho lưu trữ "cục bộ" trên đầu trang. Tuy nhiên, nó vẫn không rõ ràng với tôi chính xác nó có nghĩa là gì. Đặc biệt, những gì "trên đầu" có nghĩa là.

+0

Lưu ý rằng git pull là git fetch, sau đó là git merge. Nó thực sự có thể giúp hiểu HEAD là gì, cùng với chỉ mục. Nếu không, bạn sẽ trúng một bãi cát nếu có thứ gì đó không được lên kế hoạch khá nhanh. – rubenvb

+0

Như tôi đã viết trong câu hỏi, tôi không biết những gì "lấy" có nghĩa là. – Roman

+1

@Roman, bạn làm bây giờ ... – alexis

Trả lời

6

Tôi thấy hai điều có thể được làm rõ: Bạn đang tập trung vào trạng thái của một tệp trong hai nhánh, nhưng cách tốt hơn để xem xét những gì đang xảy ra là về các thay đổi đã xảy ra. Vấn đề thứ hai là git pull là viết tắt của hai hoạt động: git fetchgit merge. Có, bạn viết rằng bạn "không muốn sử dụng các từ như fetch", nhưng đó không phải là "khái niệm nâng cao". Nếu bạn muốn hiểu những gì đang xảy ra, bạn cần phải bắt đầu ở đó.

  • git fetch yếu thông repo địa phương thay đổi mà nó không biết.

  • git merge hợp nhất các thay đổi mới được gửi với các thay đổi cục bộ của bạn.

Việc nắm bắt được rằng nếu mọi thứ đã được diễn ra trên cả hai Repos mà không đồng bộ, có thể họ đã tách ra:

... b--o--o--o--o (remote) 
    \ 
     x--x--x  (local) 

ở trên cho thấy thời gian trái sang phải; điểm tận cùng bên phải là điểm gần nhất. Vì vậy, những thay đổi mới đến là những sửa đổi đối với trạng thái cũ hơn của các tệp, tệp được đánh dấu là "b".

  • git pull, ví dụ: đồng bằng git merge, sẽ hợp nhất trạng thái gần đây nhất của hai chi nhánh là tốt nhất vì nó có thể.

  • git pull --rebase sẽ giả vờ rằng các thay đổi của bạn không được thực hiện đối với trạng thái được đánh dấu "b", nhưng là trạng thái từ xa mới nhất. Nói cách khác, nó sẽ cố gắng viết lại lịch sử để nó trông như thế này:

    ... b--o--o--o--o    (remote) 
           \ 
            x--x--x  (local) 
    

Đó là sự khác biệt. Một hậu quả là nếu bạn không rebase, lịch sử repo của bạn có chứa một số trạng thái (bạn có thể tua lại trong tương lai, nếu bạn muốn) trong đó thay đổi "x" được áp dụng nhưng thay đổi "o" không có. Sau khi rebasing, không có vị trí nào trong kho lưu trữ.

+0

cảm ơn bạn vì câu trả lời rất rõ ràng. Tôi đã hiểu tất cả những gì bạn đã viết và tôi đã học những gì 'fetch' và' rebase' có nghĩa là gì. Điều duy nhất mà tôi đang thiếu là biết liệu nội dung của chi nhánh địa phương của tôi sẽ khác nhau tùy thuộc vào những gì tôi làm 'git pull' hoặc' git pull --rebase'.Nói cách khác, có thể làm 'o-o-o' và' x-x-x' song song và sau đó hợp nhất cho kết quả (nội dung) khác với nội dung chúng ta nhận được khi chúng ta làm 'o-o-o' trước và sau đó là' x-x-x'. Nói cách khác, là các hoạt động giao hoán 'o-o-o' và' x-x-x'? – Roman

+0

@Roman: thực sự, có những trường hợp mà * không * cư xử tốt và bạn có được kết quả khác nhau. Chúng không phải là siêu phổ biến, nhưng chúng tồn tại. Tôi khuyên người mới đến Git tránh 'git pull' hoàn toàn: chạy' git fetch' trước, sau đó chạy 'git merge' nếu bạn muốn hợp nhất, hoặc' git rebase' nếu bạn muốn rebase. Việc chia đôi cho bạn cơ hội chạy 'git log' ở giữa, để đưa ra quyết định, cũng như cho bạn một bức tranh rõ ràng hơn về những gì đang diễn ra. – torek

1

Đơn giản: miễn là tác phẩm của bạn là địa phương (có nghĩa là nó chưa được đẩy), một git pull --rebase sẽ phân phối để phát lại tác phẩm địa phương của bạn trên lịch sử được cập nhật.

git fetch sẽ cập nhật lịch sử đã nói với các cam kết mới nhất của repo từ xa (ví dụ: origin/master).
Sau đó, công việc của bạn (các cam kết địa phương của bạn trong chi nhánh master) sẽ được phát lại từng cái một (đây là điều mà một lần rebase thực hiện) trên lịch sử được cập nhật đó.

Ý tưởng là, khi bạn muốn đẩy, việc đẩy sẽ rất đơn giản và sẽ không cần hợp nhất vì cam kết của bạn chỉ đơn giản là cam kết mới được thực hiện trên đầu trang origin/master.

Lưu ý rằng bạn có thể ẩn một phần rebase hoàn toàn since Git 2.6:

git config pull.rebase true 
git config rebase.autoStash true 

Và thậm chí nếu rebase không suôn sẻ và bạn phải hủy bỏ, Git sẽ khôi phục lại công việc hiện tại cất giấu cho bạn since Git 2.10.

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