Sự khác biệt giữa 'git pull' và 'git fetch' là gì?


11916

Sự khác biệt giữa git pullvà là git fetchgì?


364
Tôi thấy bài viết này được viết tốt về git fetch và git pull nó đáng để đọc: longair.net/blog/2009/04/16/git-fetch-and-merge
Marcos Oliveira

51
Phương pháp thay thế của chúng tôi đã trở thành git fetch; git reset --hard origin/mastermột phần của quy trình làm việc của chúng tôi. Nó thổi bay những thay đổi cục bộ, giúp bạn cập nhật với BUT chính, đảm bảo bạn không chỉ cần thay đổi những thay đổi mới trên đầu trang về những thay đổi hiện tại và gây rối. Chúng tôi đã sử dụng nó trong một thời gian và về cơ bản nó cảm thấy an toàn hơn rất nhiều trong thực tế. Chỉ cần chắc chắn để thêm / cam kết / stash bất kỳ công việc đang tiến hành đầu tiên!
Michael Durrant

26
Hãy chắc chắn rằng bạn biết cách sử dụng git stash một cách chính xác. Nếu bạn đang hỏi về 'kéo' và 'tìm nạp' thì có lẽ 'stash' cũng sẽ cần giải thích ...
Henry Heleine

36
Rất nhiều người đến từ Mercurial tiếp tục sử dụng "git pull", nghĩ rằng nó tương đương với "hg pull". Mà không phải. Tương đương với "hg pull" của Git là "git fetch".
Serge Shultz

8
lệnh git fetch tìm nạp mã được cập nhật với nhánh và cũng sẽ nhận được các nhánh mới được thêm vào cục bộ của bạn, lệnh git pull chỉ tìm mã được cập nhật của nhánh hiện tại
Kartik Patel

Câu trả lời:


9918

Trong các điều khoản đơn giản nhất, git pullkhông git fetchtheo sau bởi a git merge.

Bạn có thể thực hiện git fetchbất cứ lúc nào để cập nhật các nhánh theo dõi từ xa của mình bên dưới refs/remotes/<remote>/.

Hoạt động này không bao giờ thay đổi bất kỳ chi nhánh địa phương nào của bạn refs/headsvà an toàn để thực hiện mà không thay đổi bản sao làm việc của bạn. Tôi thậm chí đã nghe nói về những người chạy git fetchđịnh kỳ trong một công việc định kỳ ở chế độ nền (mặc dù tôi không khuyên bạn nên làm điều này).

A git pulllà những gì bạn sẽ làm để đưa một chi nhánh địa phương cập nhật với phiên bản từ xa của nó, đồng thời cập nhật các chi nhánh theo dõi từ xa khác của bạn.

Tài liệu Git - git pull :

Trong chế độ mặc định của nó, git pulllà tốc ký cho git fetchtheo sau git merge FETCH_HEAD.


327
"" Git pull "là những gì bạn sẽ làm để cập nhật kho lưu trữ của mình" <- không phải là cập nhật kho lưu trữ đã được thực hiện bằng cách tìm nạp? không có nghĩa là nó mang lại cho các chi nhánh địa phương của bạn cập nhật với các chi nhánh từ xa? Để hợp nhất: Nó hợp nhất các nhánh từ xa với các bản sao cục bộ của các nhánh đó, hoặc chính xác nó hợp nhất ở đây là gì?
Albert

194
@Albert: Vâng, đó là từ kỳ lạ. git pullsẽ luôn hợp nhất vào chi nhánh hiện tại . Vì vậy, bạn chọn nhánh nào bạn muốn kéo từ đó và nó kéo nó vào nhánh hiện tại. Các từ chi nhánh có thể địa phương hoặc từ xa; nó thậm chí có thể là một nhánh từ xa không phải là một đăng ký git remote(có nghĩa là bạn truyền URL trên git pulldòng lệnh).
trực giác

129
@espertus: Không. Đẩy không bao giờ tự động hợp nhất. Người dùng dự kiến ​​sẽ kéo, giải quyết bất kỳ xung đột hợp nhất cục bộ nào, sau đó đẩy trở lại điều khiển từ xa.
Greg Hewgill

33
Nếu tôi đang ở /home/alice/và làm git fetch /home/bob, tôi nên chuyển tham số nào cho lần sau git merge?
ripper234

106
Lưu ý cho những người học Git: pullthực sự không thể được mô phỏng bằng dấu fetchcộng a merge. Tôi vừa lấy một thay đổi trong đó chỉ có một con trỏ nhánh từ xa thay đổi và mergetừ chối làm bất cứ điều gì. pullmặt khác, chuyển tiếp nhanh chi nhánh theo dõi của tôi.
Roman Starkov

2172
  • Khi bạn sử dụng pull, Git cố gắng tự động làm việc cho bạn. Nó rất nhạy cảm với bối cảnh , vì vậy Git sẽ hợp nhất bất kỳ cam kết đã kéo nào vào nhánh bạn hiện đang làm việc. pull Tự động hợp nhất các cam kết mà không cho phép bạn xem xét chúng trước . Nếu bạn không quản lý chặt chẽ các chi nhánh của mình, bạn có thể gặp phải những xung đột thường xuyên.

  • Khi bạn fetch, Git tập hợp bất kỳ cam kết nào từ nhánh mục tiêu không tồn tại trong nhánh hiện tại của bạn và lưu trữ chúng trong kho lưu trữ cục bộ của bạn . Tuy nhiên, nó không hợp nhất chúng với chi nhánh hiện tại của bạn . Điều này đặc biệt hữu ích nếu bạn cần cập nhật kho lưu trữ của mình, nhưng đang làm việc trên một cái gì đó có thể bị hỏng nếu bạn cập nhật các tệp của mình. Để tích hợp các xác nhận vào nhánh chính của bạn, bạn sử dụng merge.


34
Đồng ý, nhận xét tuyệt vời. Đó là lý do tại sao tôi ghét git kéo. Khi nào thì có nghĩa là để cho một công cụ sửa đổi thực hiện chỉnh sửa mã cho bạn? Và đó không phải là những gì hợp nhất hai tập tin đang làm? Điều gì sẽ xảy ra nếu hai chỉnh sửa đó được phân tách vật lý trong tệp, nhưng LOGICALLY ở tỷ lệ cược?
Lee Dixon

126
@elexhulk đặt ngắn, git fetchchỉ cập nhật .git/thư mục của bạn (AKA: kho lưu trữ cục bộ) và không có gì bên ngoài .git/(AKA: cây làm việc). Nó không thay đổi các chi nhánh địa phương của bạn và nó cũng không chạm mastervào. Nó chạm vào remotes/origin/mastermặc dù (xem git branch -avv). Nếu bạn có nhiều điều khiển từ xa, hãy thử git remote update. Đây là một git fetchcho tất cả các điều khiển từ xa trong một lệnh.
Tino

24
@Tino của bạn thực sự là điểm quan trọng nhất. Mọi người có thể không biết rằng các nhánh "từ xa" thực sự được lưu trữ dưới dạng một bó băm .git/refs/remotes/origin/.
Chris

13
Khi bạn tìm nạp, Git tập hợp bất kỳ cam kết nào từ nhánh mục tiêu không tồn tại trong nhánh hiện tại của bạn và lưu trữ chúng trong kho lưu trữ cục bộ của bạn - làm cách nào để xem những gì được mang từ xa và làm cách nào để hợp nhất nó vào các nhánh cục bộ của tôi?
ア レ ッ

13
@Tino Điều tôi vẫn không hiểu là ... quan điểm là gì? Tại sao sử dụng tìm nạp nếu nó chỉ cập nhật .git? Lợi ích dự định là gì và tôi phải làm gì sau đó?
BadHorsie

1210

Điều quan trọng là phải đối chiếu triết lý thiết kế của git với triết lý của một công cụ kiểm soát nguồn truyền thống hơn như SVN.

Subversion được thiết kế và xây dựng với mô hình máy khách / máy chủ. Có một kho lưu trữ duy nhất là máy chủ và một số khách hàng có thể tìm nạp mã từ máy chủ, làm việc trên đó, sau đó đưa nó trở lại máy chủ. Giả định là máy khách luôn có thể liên hệ với máy chủ khi cần thực hiện thao tác.

Git được thiết kế để hỗ trợ một mô hình phân tán hơn mà không cần kho lưu trữ trung tâm (mặc dù bạn chắc chắn có thể sử dụng một mô hình nếu bạn muốn). Ngoài ra git được thiết kế sao cho máy khách và "máy chủ" không cần trực tuyến cùng một lúc. Git được thiết kế để mọi người trên một liên kết không đáng tin cậy có thể trao đổi mã qua email, thậm chí. Có thể làm việc hoàn toàn ngắt kết nối và ghi đĩa CD để trao đổi mã qua git.

Để hỗ trợ mô hình này, git duy trì một kho lưu trữ cục bộ với mã của bạn và cũng là một kho lưu trữ cục bộ bổ sung phản ánh trạng thái của kho lưu trữ từ xa. Bằng cách giữ một bản sao của kho lưu trữ từ xa cục bộ, git có thể tìm ra những thay đổi cần thiết ngay cả khi không thể truy cập kho lưu trữ từ xa. Sau này khi bạn cần gửi các thay đổi cho người khác, git có thể chuyển chúng dưới dạng một tập hợp các thay đổi từ một thời điểm được biết đến với kho lưu trữ từ xa.

  • git fetch là lệnh "cập nhật bản sao cục bộ của kho lưu trữ từ xa."

  • git pull nói "mang những thay đổi trong kho lưu trữ từ xa đến nơi tôi giữ mã của riêng mình."

Thông thường git pullthực hiện điều này bằng cách thực hiện git fetchđể cập nhật bản sao cục bộ của kho lưu trữ từ xa, sau đó hợp nhất các thay đổi vào kho lưu trữ mã của riêng bạn và có thể là bản sao làm việc của bạn.

Việc bỏ đi là hãy nhớ rằng thường có ít nhất ba bản sao của một dự án trên máy trạm của bạn. Một bản sao là kho lưu trữ của riêng bạn với lịch sử cam kết của riêng bạn. Bản sao thứ hai là bản sao làm việc của bạn nơi bạn đang chỉnh sửa và xây dựng. Bản sao thứ ba là bản sao "lưu trữ" cục bộ của một kho lưu trữ từ xa.


75
Về mặt kỹ thuật, các kho lưu trữ cục bộ và từ xa thực sự là một và giống nhau. Trong Git, kho lưu trữ là một DAG của các xác nhận trỏ đến cha mẹ của chúng. Các chi nhánh, về mặt kỹ thuật, không có gì nhiều hơn các tên cam kết có ý nghĩa. Sự khác biệt duy nhất giữa các nhánh cục bộ và từ xa là các nhánh từ xa có tiền tố remoteName/ Git từ đầu trở lên là một bài đọc rất tốt. Một khi bạn hiểu được cách Git hoạt động - và nó thực sự đơn giản - mọi thứ thật có ý nghĩa.
Emil Lundberg

13
Cảm ơn rất nhiều vì lời giải thích. Tôi đã không thực sự hiểu cho đến bây giờ rằng Git đã được thiết kế để bạn không phải có một kho lưu trữ trung tâm. Mọi người luôn nói "DVCS" khi mô tả Git, nhưng là một lập trình viên tương đối mới, điều đó không có nghĩa gì với tôi. tôi chưa bao giờ thấy CVCS và tôi cũng chưa bao giờ làm việc với kho lưu trữ từ xa thông thường khi cộng tác với người khác (ví dụ như Github), vì vậy cho đến bây giờ tôi vẫn chưa hiểu điều gì làm cho Git trở nên đặc biệt.
Brian Peterson

7
Vì vậy, dựa trên điều này, tại sao chúng ta không nên tìm kiếm với một công việc định kỳ? Luôn luôn giữ một bản sao của điều khiển từ xa mà bạn đang làm việc trên máy cục bộ của bạn có vẻ là một ý tưởng hay. Trên thực tế, tôi cảm thấy muốn viết một kịch bản kiểm tra xem liệu tôi đã cập nhật điều khiển từ xa trong 24 giờ qua và liên kết nó với một móc nối udev để kết nối internet.
Brian Peterson

24
Một lý do tại sao đó không phải là một ý tưởng tốt để có một công việc định kỳ: thường khi làm việc với một vé mới hoặc trên các bản cập nhật cho một chi nhánh, tôi muốn thấy những thay đổi được tìm nạp. Nếu những thay đổi không xảy ra trong quá trình tìm nạp, tôi sẽ tự tin hơn khi hỏi lập trình viên đồng nghiệp của mình 'bạn đã thúc đẩy chưa?'. Tôi cũng có cảm giác bao nhiêu 'churn' trong kho lưu trữ kể từ khi tôi tìm nạp lần cuối. Điều này cũng giúp tôi hiểu về số lượng và tốc độ thay đổi hiện đang được thực hiện cho kho lưu trữ này.
Michael Durrant

5
@Nabheet Điều đó là, Git là định hướng nội dung. Nó chỉ lưu trữ dữ liệu một lần và trỏ đến nó nhiều lần. Đó là lý do tại sao trong Git, thậm chí nhiều lần xác nhận trên bản gốc không ảnh hưởng nhiều đến kích thước của repo, vì hầu hết các đối tượng đều giống nhau.
cst1992

889

Dưới đây là hình ảnh của Oliver Steele về cách tất cả mọi thứ khớp với nhau :

nhập mô tả hình ảnh ở đây

Nếu có đủ sự quan tâm, tôi cho rằng tôi có thể cập nhật hình ảnh để thêm git clonegit merge...


156
Một hình ảnh cập nhật với git clonegit mergesẽ rất hữu ích!
MEMark

20
Có, vui lòng thêm git merge- nó sẽ hiển thị rõ ràng rằng mergegọi riêng biệt KHÔNG giống như gọi pullpullchỉ hợp nhất từ ​​xa và bỏ qua các cam kết cục bộ của bạn trong chi nhánh địa phương đang theo dõi chi nhánh từ xa được kéo từ đó.
JustAMartin

12
Một bưc tranh đang gia ngan lơi noi! Là hình ảnh cập nhật với dòng dữ liệu nhân bản và hợp nhất đã sẵn sàng ở đâu đó? Bất kỳ luồng dữ liệu nào khác ngoài những gì đã có trong sơ đồ?
shikhanshu

10
@Contango vui lòng thêm bản sao và hợp nhất. Sẽ hữu ích cho những người mới như tôi.
thuê

11
Có hai sơ đồ hiển thị bản sao và hợp nhất trong các câu trả lời khác (bên dưới) của th3sly và thedarkpasbah.
intotecho

488

Một trường hợp sử dụng git fetchlà sau đây sẽ cho bạn biết bất kỳ thay đổi nào trong nhánh từ xa kể từ lần kéo cuối cùng của bạn ... vì vậy bạn có thể kiểm tra trước khi thực hiện thao tác kéo thực tế, có thể thay đổi các tệp trong nhánh hiện tại và bản sao làm việc của bạn.

git fetch
git diff ...origin

Xem: https://git-scm.com/docs/git-diff về cú pháp hai và ba dấu chấm trong lệnh diff


9
tại sao không git diff ..origin?
Erik Kaplun

3
git diff origin và git diff ..origin dường như hoạt động nhưng không phải thứ ... lạ này
Marc

19
@Compustretch Không có chỗ trống. git diff ...origintương đương với git diff $(git-merge-base HEAD origin) origin(xem git diff [--options] <commit>...<commit> [--] [<path>…]phần kernel.org/pub/software/scm/git/docs/git-diff.html#_description ), khác với git diff origin; git diff ...originvề mặt khái niệm là những thay đổi được thực hiện originkể từ khi nhánh hiện tại được phân nhánh từ origin, trong khi git diff originbao gồm cả sự thay đổi ngược lại của những thay đổi được thực hiện trong nhánh hiện tại kể từ khi nó phân nhánh origin.
Max Nanasy

2
không có lệnh nào trong số đó hoạt động với tôi (trên Windows), nhưng git diff origin/masterhoạt động, như được đề cập dưới đây
Brian Burns

tương tự ở đây bằng cách sử dụng git 2.0.0 trên OSX. Không có lệnh nào trong số này hoạt động. Họ đã bị phản đối?
K.-Michael Aye

373

Tôi mất một ít chi phí để hiểu sự khác biệt là gì, nhưng đây là một lời giải thích đơn giản. mastertrong localhost của bạn là một chi nhánh.

Khi bạn sao chép một kho lưu trữ, bạn tìm nạp toàn bộ kho lưu trữ đến máy chủ cục bộ. Điều này có nghĩa là tại thời điểm đó, bạn có một con trỏ gốc / chính và con trỏ trỏ đến HEADcùngHEAD .

Khi bạn bắt đầu làm việc và thực hiện cam kết, bạn tiến con trỏ chính tới HEAD + các cam kết của bạn. Nhưng con trỏ gốc / chủ vẫn đang chỉ vào nó khi bạn nhân bản.

Vì vậy, sự khác biệt sẽ là:

  • Nếu bạn thực hiện, git fetchnó sẽ chỉ tìm nạp tất cả các thay đổi trong kho lưu trữ từ xa ( GitHub ) và di chuyển con trỏ gốc / chủ sangHEAD . Trong khi đó, chủ chi nhánh địa phương của bạn sẽ tiếp tục chỉ đến nơi nó có.
  • Nếu bạn làm một git pull, về cơ bản nó sẽ tìm nạp (như đã giải thích trước đó) và hợp nhất bất kỳ thay đổi mới nào với nhánh chính của bạn và di chuyển con trỏ đến HEAD.

14
nguồn gốc / chủ là một chi nhánh địa phương là một bản sao của chủ bản gốc. Khi bạn tìm nạp, bạn cập nhật cục bộ: / origin / master. Một khi bạn thực sự hiểu rằng mọi thứ trong git là một nhánh, điều này rất có ý nghĩa và là một cách rất mạnh mẽ để duy trì các thay đổi khác nhau, tạo các nhánh cục bộ nhanh chóng, hợp nhất và rebase, và thường nhận được nhiều giá trị từ việc phân nhánh giá rẻ mô hình.
cam8001

3
Vẫn khó hiểu. Tôi nghĩ git fetchlà tải xuống các thay đổi trên repo từ xa vào repo cục bộ của bạn, nhưng KHÔNG cam kết chúng - nghĩa là, chúng vẫn cần được thêm / cam kết vào repo cục bộ của bạn.
krb686

3
chỉ tìm nạp từ remote / origin (github) đến nguồn gốc địa phương của bạn. Nhưng nó không hợp nhất nó với các tập tin làm việc thực tế của bạn. nếu bạn thực hiện thao tác kéo, nó sẽ tìm nạp và hợp nhất vào các tệp đang hoạt động hiện tại của bạn
Gerardo

223

Đôi khi một đại diện trực quan giúp.

nhập mô tả hình ảnh ở đây


18
Tôi nghĩ rằng hình ảnh đã cho thấy rằng nó cũng ảnh hưởng đến repo địa phương. Đó là, Git pull là sự kết hợp ảnh hưởng đến repo cục bộ và bản sao làm việc. Ngay bây giờ có vẻ như nó chỉ ảnh hưởng đến bản sao làm việc.
cực tính

10
@ 太極 者 無極 生 Đồng ý - hình ảnh này khá sai lệch, bởi vì nó làm cho nó trông giống như git pullđang bỏ qua phần tìm nạp, tất nhiên là không chính xác.
forresthopkinsa

9
có gì khác biệt giữa 'Kho lưu trữ cục bộ' và 'Bản sao làm việc'? Cả hai đều không phải là máy tính cục bộ?
theITideo

1
Sử dụng git fetch là gì? Làm thế nào để xem có sự khác biệt nào trong kho lưu trữ cục bộ và bản sao làm việc?
Vikash

2
@theITideo Không, không phải vậy. Kho lưu trữ cục bộ là nơi mã của bạn đi (từ kho lưu trữ đang hoạt động) khi bạn cam kết. (Nó đi đến repo từ xa khi bạn đẩy).
Vikash

219

Tóm tắt

git fetchtương tự pullnhưng không hợp nhất. tức là nó tìm nạp các bản cập nhật từ xa ( refsobjects) nhưng cục bộ của bạn vẫn giữ nguyên (tức là origin/masterđược cập nhật nhưng mastervẫn giữ nguyên).

git pull kéo xuống từ xa và hợp nhất ngay lập tức.

Hơn

git clone nhân bản một repo.

git rebaselưu nội dung từ chi nhánh hiện tại của bạn không ở chi nhánh thượng nguồn vào khu vực tạm thời. Chi nhánh của bạn bây giờ giống như trước khi bạn bắt đầu thay đổi. Vì thế,git pull -rebase sẽ kéo xuống các thay đổi từ xa, tua lại chi nhánh địa phương của bạn, phát lại các thay đổi của bạn qua đầu chi nhánh hiện tại của bạn từng cái một cho đến khi bạn cập nhật.

Ngoài ra, git branch -asẽ cho bạn thấy chính xác những gì đang diễn ra với tất cả các chi nhánh của bạn - địa phương và từ xa.

Bài đăng trên blog này rất hữu ích:

Sự khác biệt giữa git pull, git fetch và git clone (và git rebase) - Mike Pearce

và bìa git pull, git fetch, git clonegit rebase.

====

CẬP NHẬT

Tôi nghĩ rằng tôi sẽ cập nhật điều này để cho thấy cách bạn thực sự sử dụng điều này trong thực tế.

  1. Cập nhật repo cục bộ của bạn từ xa (nhưng không hợp nhất):

    git fetch 
    
  2. Sau khi tải xuống các bản cập nhật, hãy xem sự khác biệt:

    git diff master origin/master 
    
  3. Nếu bạn hài lòng với những cập nhật đó, thì hãy hợp nhất:

    git pull
    

Ghi chú:

Ở bước 2: Để biết thêm về sự khác biệt giữa cục bộ và điều khiển từ xa, hãy xem: Làm thế nào để so sánh một nhánh git cục bộ với nhánh từ xa của nó?

Ở bước 3: Có lẽ chính xác hơn (ví dụ về repo thay đổi nhanh) để thực hiện git rebase origintại đây. Xem bình luận @Justin Ohms trong một câu trả lời khác.

Xem thêm: http://longair.net/blog/2009/04/16/git-fetch-and-merge/


1
Âm thanh với tôi như nếu ai đó chỉ muốn mã địa phương phản ánh "mẹo", họ nên sử dụng git clone. Tôi đặt mẹo trong dấu ngoặc kép, vì tôi cho rằng nó có nghĩa là bất kể chủ nhân là gì và ai đó sẽ "Tải xuống dưới dạng zip" từ github.com
Chris K

3
Điều gì xảy ra nếu bạn không hài lòng với những thay đổi sau khi bạn tải xuống? phải làm gì tiếp theo?
Kugutsum

Đoạn văn của bạn về rebase chỉ là những gì tôi đang tìm kiếm. Toàn bộ ý tưởng về việc loại bỏ tất cả mọi thứ, cập nhật từ xa, sau đó phát lại các thay đổi của bạn trên đầu trang của các cam kết trước đó đã xảy ra trong khi bạn đang làm việc. Giải thích hoàn hảo cho rằng nó đúng. ;)
coblr

178
git-pull - Tìm nạp và hợp nhất với một kho lưu trữ khác hoặc một nhánh cục bộ
TÓM TẮC

kéo git
SỰ MIÊU TẢ

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

Lưu ý rằng bạn có thể sử dụng. (thư mục hiện tại) là <repository> để kéo
từ kho lưu trữ cục bộ - điều này rất hữu ích khi hợp nhất các nhánh cục bộ 
vào chi nhánh hiện tại.

Cũng lưu ý rằng các tùy chọn có nghĩa là cho git-pull chính nó và git-merge bên dưới 
phải được đưa ra trước các tùy chọn dành cho git-fetch.

Bạn sẽ kéo nếu bạn muốn lịch sử được hợp nhất, bạn sẽ tìm nạp nếu bạn chỉ "muốn codez" vì một số người đã gắn thẻ một số bài viết quanh đây.


5
Rất thú vị, nhưng tôi thực sự không thể thấy trường hợp sử dụng mà bạn muốn "chỉ là mã". Et những gì xảy ra với mã của bạn khi bạn tìm nạp? Có bị xóa không? Điều gì xảy ra với những thay đổi từ xa? Làm thế nào nó đi vào trong repo của bạn mà không xóa mã của bạn nếu bạn không hợp nhất?
e-satis

11
@ e-satis: Chi nhánh từ xa cũng được lưu trữ cục bộ trên máy của bạn. Vì vậy, khi bạn thực hiện, git fetchnó tìm nạp các thay đổi từ kho lưu trữ và cập nhật chi nhánh từ xa cục bộ của bạn. Nó không ảnh hưởng đến chi nhánh địa phương của bạn theo dõi chi nhánh từ xa cục bộ, do đó không ảnh hưởng đến bản sao làm việc của bạn. Bây giờ, khi bạn thực hiện, mergenó sẽ hợp nhất các thay đổi được tìm nạp với chi nhánh địa phương của bạn.
jeffreyveon

Trường hợp sử dụng đơn giản cho lệnh tìm nạp: thực hiện các hoạt động tiêu tốn thời gian liên quan đến các cam kết gần đây của người khác, chẳng hạn như hợp nhất hoặc đánh giá mã, chỉ truy cập kho lưu trữ cục bộ cập nhật của bạn mà không yêu cầu kết nối mạng, bởi vì trước đây bạn đã sử dụng để tải xuống mọi thứ bạn cần một cách nhanh chóng (ví dụ: trong khi bạn đang truy cập một số nhà phát triển khác và được kết nối với mạng của một số kho lưu trữ khác). Lệnh pull sẽ tải xuống các cam kết tương tự, nhưng việc hợp nhất nó thực hiện có thể là không mong muốn.
Lorenzo Gatti

163

Bạn có thể tìm nạp từ một kho lưu trữ từ xa, xem sự khác biệt và sau đó kéo hoặc hợp nhất.

Đây là một ví dụ cho một kho lưu trữ từ xa được gọi originvà một nhánh được gọi là mastertheo dõi nhánh từ xa origin/master:

git checkout master                                                  
git fetch                                        
git diff origin/master
git rebase origin master

35
Bạn có thể muốn bỏ qua việc kéo và chỉ thực hiện "git rebase origin" là bước cuối cùng vì bạn đã tìm nạp các thay đổi. Lý do là ai đó có thể đã thúc đẩy các thay đổi trong thời gian kể từ khi bạn thực hiện tìm nạp và những điều này sẽ không được tìm nạp mà bạn đã thực hiện đánh giá khác.
Justin Ohms

158

Câu trả lời ngắn gọn và dễ dàng git pulllà chỉ đơn giản git fetchlà theo sau git merge.

Điều rất quan trọng cần lưu ý là git pullsẽ tự động hợp nhất cho dù bạn có thích hay không . Tất nhiên, điều này có thể dẫn đến xung đột hợp nhất. Giả sử điều khiển từ xa origincủa bạn và chi nhánh của bạn là master. Nếu bạn git diff origin/mastertrước khi kéo, bạn nên có một số ý tưởng về xung đột hợp nhất tiềm năng và có thể chuẩn bị chi nhánh địa phương của bạn phù hợp.

Ngoài việc kéo và đẩy, một số quy trình công việc liên quan git rebase, chẳng hạn như quy trình này, mà tôi diễn giải từ bài viết được liên kết:

git pull origin master
git checkout foo-branch
git rebase master
git push origin foo-branch

Nếu bạn thấy mình trong tình huống như vậy, bạn có thể bị cám dỗ git pull --rebase. Trừ khi bạn thực sự, thực sự biết những gì bạn đang làm, tôi sẽ khuyên bạn chống lại điều đó. Cảnh báo này là từ mantrang cho git-pull, phiên bản 2.3.5:

Đây là một chế độ hoạt động nguy hiểm tiềm tàng. Nó viết lại lịch sử, điều đó không tốt cho lắm khi bạn đã xuất bản lịch sử đó. Không sử dụng tùy chọn này trừ khi bạn đã đọc git-rebase (1) một cách cẩn thận.


2
@JustinOhms Nếu git pull --rebasekhông phải là điều đúng trong tình huống đã cho, liệu có đúng nếu nó được thực hiện theo hai bước? Nếu đó là điều đúng đắn, thì lợi ích gì khi thực hiện nó theo hai bước?
Kaz

@Kaz - vì rebase không tự động. Tìm nạp các thay đổi trước cho phép bạn thực hiện cuộc gọi phán xét. Nó không khắc phục vấn đề với lịch sử khởi động lại mà bạn đã đẩy. Nó sẽ cho phép bạn xem liệu có an toàn để chống lại những thay đổi mà bạn chưa thúc đẩy hay không.
Justin Ohms

2
@JustinOhms Làm thế nào bạn sẽ quyết định liệu có an toàn để bắt đầu thay đổi không? Tôi sẽ chỉ thử git rebase và quay lại nếu nó tạo ra một mớ hỗn độn, trong trường hợp đó tôi cũng có thể thực hiện git pull --rebase. Nhưng có lẽ bạn có một số cách khác?
Kaz

3
@KaZ gitk cho phép bạn nhìn thấy cấu trúc chi nhánh một cách trực quan. Nó sẽ hiển thị vị trí của người đứng đầu địa phương, điều khiển từ xa và cấu trúc chi nhánh của bạn liên quan đến những gì bạn đã tìm nạp. Bằng cách này, bạn có thể đảm bảo rằng bạn không từ chối các thay đổi được tìm nạp dựa trên tổ tiên trước những gì bạn đã đẩy đến (các) điều khiển từ xa.
Justin Ohms

Sử dụng rebasekhi bạn đang làm việc trên một chi nhánh địa phương chưa được đẩy. Nếu bạn đang làm việc trên một nhánh tồn tại trong điều khiển từ xa, rebasecó thể dẫn đến một số vấn đề khó chịu vì vậy bạn nên thích thường xuyên hơn merge.
Justus Romijn

151

OK , đây là một số thông tin về git pullgit fetch, do đó bạn có thể hiểu được sự khác biệt thực tế ... trong vài từ đơn giản, lấy được các dữ liệu mới nhất, nhưng không phải là thay đổi mã và không sẽ gặp rắc rối với mã chi nhánh địa phương hiện tại của bạn, nhưng kéo get mã thay đổi và hợp nhất nó với chi nhánh địa phương của bạn, đọc tiếp để biết thêm chi tiết về từng loại:

git lấy

Nó sẽ tải tất cả các refđối tượng và bất kỳ chi nhánh mới nào vào Kho lưu trữ cục bộ của bạn ...

Lấy các nhánh và / hoặc thẻ (gọi chung là "refs") từ một hoặc nhiều kho lưu trữ khác, cùng với các đối tượng cần thiết để hoàn thành lịch sử của chúng. Các nhánh theo dõi từ xa được cập nhật (xem mô tả bên dưới để biết cách kiểm soát hành vi này).

Theo mặc định, bất kỳ thẻ nào trỏ vào lịch sử đang được tìm nạp cũng được tìm nạp; hiệu quả là tìm nạp các thẻ trỏ đến các nhánh mà bạn quan tâm. Hành vi mặc định này có thể được thay đổi bằng cách sử dụng các tùy chọn --tags hoặc --no-tags hoặc bằng cách định cấu hình từ xa..tagOpt. Bằng cách sử dụng một refspec tìm nạp các thẻ một cách rõ ràng, bạn có thể tìm nạp các thẻ không trỏ đến các nhánh mà bạn quan tâm.

git fetch có thể tìm nạp từ một kho lưu trữ hoặc URL có tên duy nhất hoặc từ một số kho lưu trữ cùng một lúc nếu được đưa ra và có một điều khiển từ xa. mục trong tập tin cấu hình. (Xem git-config 1 ).

Khi không có điều khiển từ xa được chỉ định, theo mặc định, điều khiển từ xa gốc sẽ được sử dụng, trừ khi có một nhánh ngược dòng được cấu hình cho nhánh hiện tại.

Tên của các ref được tìm nạp, cùng với các tên đối tượng mà chúng trỏ tới, được ghi vào .git / FETCH_HEAD. Thông tin này có thể được sử dụng bởi các tập lệnh hoặc các lệnh git khác, chẳng hạn như git-pull.


kéo git

Nó sẽ áp dụng các thay đổi từ xa đến chi nhánh hiện tại ở địa phương ...

Kết hợp các thay đổi từ một kho lưu trữ từ xa vào chi nhánh hiện tại. Trong chế độ mặc định của nó, git pull là tốc ký cho git fetch theo sau là git merge FETCH_HEAD.

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.

phải là tên của một kho lưu trữ từ xa được chuyển đến git-fetch 1 . có thể đặt tên cho một ref từ xa tùy ý (ví dụ: tên của thẻ) hoặc thậm chí là một tập hợp các ref với các nhánh theo dõi từ xa tương ứng (ví dụ: refs / Heads / : refs / remote / origin / ), nhưng thường thì đó là tên của một nhánh trong kho lưu trữ từ xa.

Các giá trị mặc định cho và được đọc từ cấu hình "từ xa" và "hợp nhất" cho nhánh hiện tại như được đặt bởi git-Branch --track.


Tôi cũng tạo ra hình ảnh dưới đây để cho bạn thấy cách làm việc git fetchgit pulllàm việc cùng nhau ...

git kéo và git lấy


10
Nếu bạn thích hình ảnh thì hãy xem bảng git cheat, đây là loại tương tự cho tất cả các lệnh git ... ndpsoftware.com/git-chcoateet.html
Tom

3
Không sao chép cũng ảnh hưởng đến kho lưu trữ cục bộ (sao chép tất cả lịch sử từ xa)?
Tom Loredo

135

nhập mô tả hình ảnh ở đây

Biểu diễn đồ họa tương tác này rất hữu ích trong việc khai thác git: http://ndpsoftware.com/git-chcoateet.html

git fetchchỉ "tải xuống" các thay đổi từ điều khiển từ xa vào kho lưu trữ cục bộ của bạn. git pulltải về các thay đổi và hợp nhất chúng vào chi nhánh hiện tại của bạn. "Trong chế độ mặc định của nó, git pulllà tốc ký để git fetchtheo sau git merge FETCH_HEAD."


18
Mọi người, nhấp vào liên kết để tương tác với các cột khác nhau. Chiếc áo này là tài nguyên tốt nhất tôi từng thấy để hiểu đầy đủ về sự khác biệt giữa mỗi lệnh.
M. Luisa Carrión

Câu trả lời này phải được đưa lên hàng đầu
Tessaracter

126

Tặng kem:

Khi nói về pull & fetch trong các câu trả lời trên, tôi muốn chia sẻ một mẹo thú vị,

git pull --rebase

Lệnh trên là lệnh hữu ích nhất trong cuộc sống git của tôi giúp tiết kiệm rất nhiều thời gian.

Trước khi đẩy các cam kết mới của bạn đến máy chủ, hãy thử lệnh này và nó sẽ tự động đồng bộ các thay đổi máy chủ mới nhất (với fetch + merge) và sẽ đặt cam kết của bạn ở đầu trong nhật ký git. Không cần phải lo lắng về việc kéo / hợp nhất thủ công.

Tìm thông tin chi tiết tại: http://gitolite.com/git-pull--rebase


4
Mẹo hay, mặc dù đáng để đề cập đến người dùng git mới mà rebase sửa đổi băm cam kết (tôi thấy rằng đáng ngạc nhiên đến từ lật đổ).
AlexMA

1
Bạn có thể giải thích sự khác biệt giữa git pullgit pull --rebase?
shaijut

2
Xem cảnh báo nghiêm

118

Tôi muốn có một số đại diện trực quan của tình huống để nắm bắt những điều này. Có lẽ các nhà phát triển khác cũng muốn thấy nó, vì vậy đây là sự bổ sung của tôi. Tôi không hoàn toàn chắc chắn rằng tất cả đều đúng, vì vậy hãy bình luận nếu bạn tìm thấy bất kỳ sai lầm nào.

                                         LOCAL SYSTEM
                  . =====================================================    
================= . =================  ===================  =============
REMOTE REPOSITORY . REMOTE REPOSITORY  LOCAL REPOSITORY     WORKING COPY
(ORIGIN)          . (CACHED)           
for example,      . mirror of the      
a github repo.    . remote repo
Can also be       .
multiple repo's   .
                  .
                  .
FETCH  *------------------>*
Your local cache of the remote is updated with the origin (or multiple
external sources, that is git's distributed nature)
                  .
PULL   *-------------------------------------------------------->*
changes are merged directly into your local copy. when conflicts occur, 
you are asked for decisions.
                  .
COMMIT            .                             *<---------------*
When coming from, for example, subversion, you might think that a commit
will update the origin. In git, a commit is only done to your local repo.
                  .
PUSH   *<---------------------------------------*
Synchronizes your changes back into the origin.

Một số lợi thế chính để có một chiếc gương lấy từ xa là:

  • Hiệu suất (cuộn qua tất cả các cam kết và tin nhắn mà không cố gắng ép nó qua mạng)
  • Phản hồi về trạng thái của repo địa phương của bạn (ví dụ: tôi sử dụng SourceTree của Atlassian, nó sẽ cho tôi một bóng đèn cho biết nếu tôi cam kết trước hoặc sau so với nguồn gốc. Thông tin này có thể được cập nhật với GIT FETCH).

Không phải git pullcũng thực hiện hợp nhất, tức là đi tất cả các bản sao làm việc?
Kamiel Wanrooij

Điểm hay, vâng, nó sẽ đặt tất cả các thay đổi trong bản sao làm việc của bạn, và sau đó bạn có thể tự cam kết nó vào repo địa phương. Tôi sẽ cập nhật hình ảnh.
Justus Romijn

@JustusRomijn Không phải kéo cũng cập nhật kho lưu trữ cục bộ sao? Không nên có một dấu sao giữa nguồn gốc và dấu sao làm việc sao?
dùng764754

2
@ user764754 Khi bạn kéo, bản sao làm việc của bạn nhận được các thay đổi (cũng có thể có một số xung đột mà bạn có thể cần phải giải quyết). Bạn vẫn phải cam kết nó vào kho lưu trữ cục bộ của bạn.
Justus Romijn

@JustusRomijn: Cảm ơn bạn đã minh họa. Thật tuyệt vời nếu bạn có thể làm cho sơ đồ toàn diện hơn bằng cách minh họa các hiệu ứng của các hoạt động như đặt lại, chọn cherry trên trạng thái kho lưu trữ.
jith912

106

Tôi đã đấu tranh với điều này là tốt. Trong thực tế, tôi đã đến đây với một tìm kiếm google với cùng một câu hỏi. Đọc tất cả những câu trả lời này cuối cùng đã vẽ một bức tranh trong đầu tôi và tôi quyết định thử đưa nó xuống nhìn vào trạng thái của 2 kho lưu trữ và 1 hộp cát và các hành động được thực hiện theo thời gian trong khi xem phiên bản của chúng. Vì vậy, đây là những gì tôi đã đưa ra. Xin hãy sửa tôi nếu tôi nhắn tin ở bất cứ đâu.

Ba repos với một tìm nạp:

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - fetch               -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     -                     -
- @ R01             -     - @ R01+              -     - @R01+               -
---------------------     -----------------------     -----------------------

Ba repos với một kéo

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - pull                -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     - merged with R02     -
- @ R01             -     - @ R01+              -     - @R02+               -
---------------------     -----------------------     -----------------------

Điều này giúp tôi hiểu lý do tại sao một tìm nạp là khá quan trọng.


Không khó đọc: các hộp biểu thị trạng thái của một repo, rằng trong mỗi hàng thay đổi theo thời gian từ trái sang phải sau thao tác được báo cáo trong hàng 2 của hộp. Các nhãn R0n là các thẻ trong git và một thẻ có dấu + vẫn chưa được sử dụng. Sanbox được sử dụng cho thư mục làm việc của bạn, khác với thư mục repo, nơi lưu trữ nội dung được cam kết.
user1708042

96

Sự khác biệt giữa FIT FetchGIT Pull có thể được giải thích với kịch bản sau: (Hãy nhớ rằng hình ảnh nói lớn hơn lời nói!, Tôi đã cung cấp hình ảnh đại diện)

Hãy lấy một ví dụ rằng bạn đang thực hiện một dự án với các thành viên trong nhóm của bạn. Vì vậy, họ sẽ là một Chi nhánh chính của dự án và tất cả những người đóng góp phải phân nhánh nó vào kho lưu trữ cục bộ của riêng họ và sau đó làm việc trên nhánh cục bộ này để sửa đổi / Thêm mô-đun sau đó đẩy trở lại nhánh chính.

Vì vậy, Nhà nước ban đầu của hai chi nhánh khi bạn chia hai dự án chính về kho địa phương của bạn sẽ như thế nào this- ( A, BCđược Modules đã hoàn thành của dự án)

nhập mô tả hình ảnh ở đây

Bây giờ, bạn đã bắt đầu làm việc trên các module mới (giả sử D) và khi bạn đã hoàn thành các Dmodule bạn muốn đẩy nó đến chi nhánh chính, Nhưng bên cạnh đó những gì xảy ra là một trong những đồng đội của bạn đã phát triển mới Mô-đun E, Fvà sửa đổi C.
Vì vậy, bây giờ điều đã xảy ra là kho lưu trữ cục bộ của bạn thiếu tiến độ ban đầu của dự án và do đó việc đẩy các thay đổi của bạn sang nhánh chính có thể dẫn đến xung đột và có thể khiến Mô-đun của bạn Dgặp trục trặc.

nhập mô tả hình ảnh ở đây

Để tránh những vấn đề như vậy và để làm việc song song với tiến độ ban đầu của dự án, có hai cách:

1. Git Fetch- Điều này sẽ Tải xuống tất cả các thay đổi đã được thực hiện cho dự án gốc / chi nhánh chính không có trong chi nhánh địa phương của bạn. Và sẽ chờ lệnh Git Merge áp dụng các thay đổi đã được tìm nạp vào Kho lưu trữ hoặc chi nhánh của bạn.

nhập mô tả hình ảnh ở đây

Vì vậy, bây giờ Bạn có thể theo dõi cẩn thận các tập tin trước khi hợp nhất nó vào kho lưu trữ của bạn. Và bạn cũng có thể sửa đổi Dnếu cần vì đã sửa đổi C.

nhập mô tả hình ảnh ở đây

2. Git Pull- Điều này sẽ cập nhật nhánh cục bộ của bạn với nhánh gốc / nhánh chính tức là những gì nó thực hiện là sự kết hợp giữa Git Fetch và Git hợp nhất lần lượt. Nhưng điều này có thể gây ra Xung đột xảy ra, vì vậy nên sử dụng Git Pull với một bản sao sạch.

nhập mô tả hình ảnh ở đây


1
nếu bạn có thể thay đổi 'Chi nhánh chính' thành 'Repo từ xa', đó sẽ là một câu trả lời tuyệt vời.
Qibiron Ai là

87

Chúng tôi chỉ đơn giản nói:

git pull == git fetch + git merge

Nếu bạn chạy git pull, bạn không cần hợp nhất dữ liệu thành cục bộ. Nếu bạn chạy git fetch, điều đó có nghĩa là bạn phải chạy git mergeđể nhận mã mới nhất đến máy cục bộ của mình. Nếu không, mã máy cục bộ sẽ không được thay đổi nếu không hợp nhất.

Vì vậy, trong Git Gui, khi bạn tìm nạp, bạn phải hợp nhất dữ liệu. Tự tìm nạp sẽ không làm thay đổi mã tại địa phương của bạn. Bạn có thể kiểm tra xem khi bạn cập nhật mã bằng cách tìm nạp một lần tìm nạp và xem; mã nó sẽ không thay đổi. Sau đó, bạn hợp nhất ... Bạn sẽ thấy mã đã thay đổi.


3
Tôi muốn nói hơn git pull == git fetch + git merge:)
melvynkim

2
Nhưnggit pull --rebase = git fetch + git rebase
Tino

83

git fetchkéo mã từ máy chủ từ xa xuống các nhánh theo dõi trong kho lưu trữ cục bộ của bạn. Nếu điều khiển từ xa được đặt tên origin(mặc định), sau đó các chi nhánh sẽ được trong vòng origin/, ví dụ origin/master, origin/mybranch-123vv Đây không phải là chi nhánh hiện tại của bạn, họ là địa phương bản sao của những chi nhánh từ máy chủ.

git pullthực hiện git fetchnhưng sau đó cũng hợp nhất mã từ nhánh theo dõi vào phiên bản cục bộ hiện tại của nhánh đó. Nếu bạn chưa sẵn sàng cho những thay đổi đó, chỉ cần git fetchđầu tiên.


78

git fetchsẽ lấy các nhánh từ xa để bạn có thể git diffhoặc git mergechúng với nhánh hiện tại.git pullsẽ chạy tìm nạp trên brach từ xa được theo dõi bởi nhánh hiện tại và sau đó hợp nhất kết quả. Bạn có thể sử dụng git fetchđể xem nếu có bất kỳ cập nhật nào cho chi nhánh từ xa mà không cần hợp nhất chúng với chi nhánh địa phương của bạn.


73

Lấy Git

Bạn tải xuống các thay đổi cho chi nhánh địa phương của bạn từ nguồn gốc thông qua tìm nạp. Tìm nạp yêu cầu repo từ xa cho tất cả các cam kết mà người khác đã thực hiện nhưng bạn không có trên repo địa phương của bạn. Tìm nạp tải xuống các cam kết này và thêm chúng vào kho lưu trữ cục bộ.

Hợp nhất Git

Bạn có thể áp dụng các thay đổi được tải xuống thông qua tìm nạp bằng lệnh hợp nhất. Hợp nhất sẽ lấy các xác nhận được lấy từ tìm nạp và cố gắng thêm chúng vào chi nhánh địa phương của bạn. Hợp nhất sẽ giữ lịch sử cam kết của các thay đổi cục bộ của bạn để khi bạn chia sẻ chi nhánh của mình với đẩy, Git sẽ biết cách người khác có thể hợp nhất các thay đổi của bạn.

Kéo Git

Tìm nạp và hợp nhất chạy với nhau thường xuyên đủ để một lệnh kết hợp cả hai, kéo, được tạo. Pull thực hiện tìm nạp và sau đó hợp nhất để thêm các cam kết đã tải xuống vào chi nhánh địa phương của bạn.


51

Sự khác biệt duy nhất giữa git pullgit fetchlà:

git pull kéo từ một chi nhánh từ xa và hợp nhất nó.

git fetch chỉ tìm nạp từ nhánh từ xa nhưng nó không hợp nhất

tức là git pull = git fetch + git merge ...


1
Và cũng chẳng ích gì nếu git nghĩ rằng bạn đứng sau các cam kết và có thể "tiến nhanh", điều mà sau đó tôi đã kết thúc rm -rfmọi việc và bắt đầu lại từ đầu. Git ngu ngốc, làm ơn chỉ cho tôi hiện tại để tôi có thể quay lại làm việc?
Chris K

47

Nói một cách đơn giản, nếu bạn chuẩn bị lên máy bay mà không có kết nối Internet ... trước khi khởi hành, bạn có thể làm git fetch origin <master> . Nó sẽ tìm nạp tất cả các thay đổi vào máy tính của bạn, nhưng tách biệt nó khỏi không gian làm việc / phát triển cục bộ của bạn.

Trên máy bay, bạn có thể thực hiện các thay đổi đối với không gian làm việc cục bộ của mình và sau đó hợp nhất nó với những gì bạn đã tìm nạp và giải quyết xung đột hợp nhất tiềm năng mà không cần kết nối với Internet. Và trừ khi ai đó đã thực hiện các thay đổi xung đột mới đối với kho lưu trữ từ xa thì một khi bạn đến đích bạn sẽ làm git push origin <branch>và đi lấy cà phê.


Từ hướng dẫn tuyệt vời này của Atlassian :

Các git fetchlệnh tải cam kết, tập tin, và refs từ một kho lưu trữ từ xa vào kho lưu trữ tại địa phương.

Tìm nạp là những gì bạn làm khi bạn muốn xem những gì mọi người đang làm việc. Nó tương tự như bản cập nhật SVN ở chỗ nó cho phép bạn xem lịch sử trung tâm đã tiến triển như thế nào, nhưng nó không buộc bạn phải thực sự hợp nhất các thay đổi vào kho lưu trữ của mình. Git cô lập nội dung được tìm nạp như một nội dung hiện có , nó hoàn toàn không ảnh hưởng đến công việc phát triển địa phương của bạn . Nội dung tìm nạp phải được kiểm tra rõ ràng bằng cách sử dụnggit checkout lệnh. Điều này làm cho việc tìm nạp một cách an toàn để xem xét các cam kết trước khi tích hợp chúng với kho lưu trữ cục bộ của bạn.

Khi tải xuống nội dung từ một kho lưu trữ từ xa git pullgit fetchcác lệnh có sẵn để hoàn thành nhiệm vụ. Bạn có thể xem xét git fetchphiên bản 'an toàn' của hai lệnh. Nó sẽ tải xuống nội dung từ xa, nhưng không cập nhật trạng thái làm việc của kho lưu trữ cục bộ của bạn, giữ nguyên công việc hiện tại của bạn. git pulllà sự thay thế tích cực hơn, nó sẽ tải xuống nội dung từ xa cho nhánh cục bộ đang hoạt động và ngay lập tức thực thi git mergeđể tạo một cam kết hợp nhất cho nội dung từ xa mới. Nếu bạn có các thay đổi đang chờ xử lý, điều này sẽ gây ra xung đột và khởi động luồng giải quyết xung đột hợp nhất.


Với git pull:

  • Bạn không nhận được bất kỳ sự cô lập.
  • Nó ảnh hưởng đến sự phát triển địa phương của bạn.
  • Nó không cần phải được kiểm tra rõ ràng. Bởi vì nó mặc nhiên làm mộtgit merge .
  • Về cơ bản nó KHÔNG an toàn. Nó hung hăng.
  • Không giống như git fetchnơi nó chỉ ảnh hưởng đến bạn .git/refs/remotes, git pull sẽ ảnh hưởng đến cả bạn .git/refs/remotes .git/refs/heads/

Hmmm ... vậy nếu tôi không cập nhật bản sao làm việc git fetch, vậy tôi sẽ thay đổi ở đâu? Trường hợp Git tìm nạp các cam kết mới?

Câu hỏi tuyệt vời. Nó đặt nó ở một nơi nào đó tách biệt với bản sao làm việc của bạn. Nhưng lại ở đâu? Hãy cùng tìm hiểu.

Trong thư mục dự án của bạn (tức là nơi bạn thực hiện các gitlệnh của mình ) làm:

  1. ls. Điều này sẽ hiển thị các tập tin và thư mục. Không có gì mát mẻ, tôi biết.

  2. Bây giờ làm ls -a. Điều này sẽ hiển thị các tệp chấm , tức là các tệp bắt đầu bằng .Bạn sau đó sẽ có thể thấy một thư mục có tên : .git.

  3. Làm cd .git. Điều này rõ ràng sẽ thay đổi thư mục của bạn.
  4. Bây giờ đến phần thú vị; làm ls. Bạn sẽ thấy một danh sách các thư mục. Chúng tôi đang tìm kiếm refs. Làm cd refs.
  5. Thật thú vị khi xem những gì bên trong tất cả các thư mục, nhưng hãy tập trung vào hai trong số chúng. headsremotes. Sử dụng cdđể kiểm tra bên trong chúng quá.
  6. Bất cứ git fetch điều gì bạn làm sẽ cập nhật các mục trong /.git/refs/remotesthư mục. Nó sẽ không cập nhật bất cứ điều gì trong /.git/refs/headsthư mục.
  7. Bất kỳ git pull đầu tiên sẽ làm git fetch, cập nhật các mục trong /.git/refs/remotesthư mục, sau đó hợp nhất với cục bộ của bạn và sau đó thay đổi đầu trong /.git/refs/headsthư mục.

Một câu trả lời liên quan rất tốt cũng có thể được tìm thấy ở đâu 'git fetch' tự đặt nó ở đâu? .

Ngoài ra, hãy tìm "Ký hiệu gạch chéo" từ bài đăng quy ước đặt tên nhánh Git . Nó giúp bạn hiểu rõ hơn về cách Git đặt mọi thứ trong các thư mục khác nhau.


Để thấy sự khác biệt thực tế

Cứ làm đi:

git fetch origin master
git checkout master

Nếu chủ từ xa được cập nhật, bạn sẽ nhận được một tin nhắn như thế này:

Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Nếu bạn không fetchvà chỉ cần làm git checkout masterthì git địa phương của bạn sẽ không biết rằng có 2 cam kết được thêm vào. Và nó sẽ chỉ nói:

Already on 'master'
Your branch is up to date with 'origin/master'.

Nhưng điều đó đã lỗi thời và không chính xác. Đó là bởi vì git sẽ cung cấp cho bạn thông tin phản hồi chỉ dựa trên những gì nó biết. Nó không biết gì về những cam kết mới mà nó chưa bị kéo xuống ...


Có cách nào để xem những thay đổi mới được thực hiện từ xa trong khi làm việc trên nhánh cục bộ không?

Một số IDE (ví dụ Xcode) siêu thông minh và sử dụng kết quả của a git fetchvà có thể chú thích các dòng mã đã được thay đổi trong nhánh từ xa của nhánh làm việc hiện tại của bạn. Nếu dòng đó đã được thay đổi bởi cả thay đổi cục bộ và nhánh từ xa, thì dòng đó sẽ được chú thích bằng màu đỏ. Đây không phải là một cuộc xung đột hợp nhất. Đó là một xung đột hợp nhất tiềm năng . Đó là một headup mà bạn có thể sử dụng để giải quyết xung đột hợp nhất trong tương lai trước khi thực hiện git pulltừ chi nhánh từ xa.

nhập mô tả hình ảnh ở đây


Mẹo thú vị:

Nếu bạn đã tìm nạp một nhánh từ xa, ví dụ:

git fetch origin feature/123

Sau đó, điều này sẽ đi vào thư mục điều khiển từ xa của bạn. Nó vẫn không có sẵn cho thư mục địa phương của bạn. Tuy nhiên, nó đơn giản hóa việc thanh toán của bạn đến chi nhánh từ xa đó bằng DWIM (Làm theo ý tôi):

git checkout feature/123

bạn không còn cần phải làm:

git checkout -b feature/123 origin/feature/123

Để biết thêm về điều đó đọc ở đây


1
Tôi thích câu trả lời này
Kid_Learning_C

44

Git cho phép các cam kết cũ hơn theo thời gian được áp dụng sau các cam kết mới hơn. Do đó, hành động chuyển giao cam kết giữa các kho được chia thành hai bước:

  1. Sao chép các cam kết mới từ chi nhánh từ xa sang sao chép chi nhánh từ xa này bên trong repo cục bộ.

    (repo để hoạt động repo) master@remote >> remote/origin/master@local

  2. Tích hợp các cam kết mới cho chi nhánh địa phương

    (hoạt động bên trong repo) remote/origin/master@local >> master@local

Có hai cách thực hiện bước 2. Bạn có thể:

  1. Ngã ba nhánh cục bộ sau tổ tiên chung cuối cùng và thêm các xác nhận mới song song với các xác nhận duy nhất cho kho lưu trữ cục bộ, được hoàn thành bằng cách hợp nhất cam kết, đóng ngã ba.
  2. Chèn các xác nhận mới sau khi tổ tiên chung cuối cùng và áp dụng lại cam kết duy nhất cho kho lưu trữ cục bộ.

Trong gitthuật ngữ, bước 1 là git fetch, bước 2 là git mergehoặcgit rebase

git pullgit fetchgit merge


37

Git có được nhánh của phiên bản mới nhất từ ​​điều khiển từ xa đến cục bộ bằng hai lệnh:

  1. git fetch: Git sẽ có phiên bản mới nhất từ ​​xa đến cục bộ, nhưng nó không tự động hợp nhất.      git fetch origin master git log -p master..origin/master git merge origin/master

         Các lệnh trên có nghĩa là tải xuống phiên bản mới nhất của nhánh chính từ gốc từ xa đến gốc nhánh gốc. Và sau đó so sánh chi nhánh chủ địa phương và chi nhánh gốc. Cuối cùng, hợp nhất.

  2. git pull: Git sẽ lấy phiên bản mới nhất từ ​​xa và hợp nhất vào cục bộ.

        git pull origin master

         Lệnh trên tương đương với git fetchgit merge. Trong thực tế, git fetchcó thể an toàn hơn vì trước khi hợp nhất, chúng ta có thể thấy các thay đổi và quyết định có hợp nhất hay không.


37

Sự khác biệt giữa git pullvà là git fetchgì?

Để hiểu điều này, trước tiên bạn cần hiểu rằng git cục bộ của bạn không chỉ duy trì kho lưu trữ cục bộ của bạn mà còn duy trì một bản sao cục bộ của kho lưu trữ từ xa.

git fetchmang đến bản sao cục bộ của kho lưu trữ từ xa cập nhật. Ví dụ: nếu kho lưu trữ từ xa của bạn là GitHub - bạn có thể muốn tìm nạp bất kỳ thay đổi nào được thực hiện trong kho lưu trữ từ xa sang bản sao cục bộ của kho lưu trữ từ xa. Điều này sẽ cho phép bạn thực hiện các hoạt động như so sánh hoặc hợp nhất.

git pullmặt khác sẽ đưa các thay đổi trong kho lưu trữ từ xa đến nơi bạn giữ mã của riêng mình. Thông thường, git pullsẽ thực hiện git fetchlần đầu tiên để cập nhật bản sao cục bộ của kho lưu trữ từ xa và sau đó nó sẽ hợp nhất các thay đổi vào kho lưu trữ mã của riêng bạn và có thể là bản sao làm việc của bạn.


35

git pull == (git fetch + git merge)

git fetch không thay đổi cho các chi nhánh địa phương.

Nếu bạn đã có một kho lưu trữ cục bộ với một điều khiển từ xa được thiết lập cho dự án mong muốn, bạn có thể lấy tất cả các nhánh và thẻ cho điều khiển từ xa hiện có bằng cách sử dụng git fetch. ... Fetch không thực hiện bất kỳ thay đổi nào đối với các nhánh cục bộ, vì vậy bạn sẽ cần hợp nhất một nhánh từ xa với một nhánh cục bộ được ghép nối để kết hợp các thay đổi mới tìm nạp. từ github


34

Cố gắng rõ ràng và đơn giản.

Các git pull lệnh thực sự là một shortcutcho git fetch tiếp theo là merge git hoặc git rebase lệnh tùy thuộc vào cấu hình của bạn. Bạn có thể định cấu hình kho lưu trữ Git của mình để git pull là một lần tìm nạp theo sau là một rebase.


33

Một đại diện đồ họa đơn giản cho người mới bắt đầu,

nhập mô tả hình ảnh ở đây

đây,

git pull  

sẽ tìm nạp mã từ kho lưu trữ và rebase với cục bộ của bạn ... trong git pull có khả năng các xác nhận mới được tạo.

nhưng trong

git lấy

sẽ tìm nạp mã từ kho lưu trữ và chúng tôi cần khởi động lại thủ công bằng cách sử dụng git rebase

ví dụ: tôi sẽ tìm nạp từ chủ máy chủ và khởi động lại nó trong chủ địa phương.

1) git pull (rebase sẽ tự động thực hiện):

git pull origin master

nguồn gốc ở đây là chủ repo từ xa của bạn là chi nhánh của bạn

2) git fetch (cần rebase thủ công):

git fetch origin master

nó sẽ lấy các thay đổi máy chủ từ nguồn gốc. và nó sẽ ở địa phương của bạn cho đến khi bạn tự mình khởi động lại nó. chúng ta cần sửa các xung đột bằng tay bằng cách kiểm tra mã.

git rebase origin/master

điều này sẽ rebase mã vào địa phương. trước đó đảm bảo bạn ở đúng chi nhánh.


Biểu đồ đẹp, nhưng bạn có thể muốn giải thích lý do tại sao bạn sử dụng "rebase" khi biểu đồ nói "hợp nhất".
Guntram Blohm hỗ trợ Monica

2
hợp nhất sẽ đại diện cho một cam kết chi nhánh khác và tạo ra cam kết mới có chứa các cam kết làm tham chiếu. nhưng rebase sẽ sao chép các cam kết từ một nhánh khác, nó sẽ không tạo ra các cam kết mới hơn là sao chép
Mohideen bin Mohammed

33

Trên thực tế, Git duy trì một bản sao mã của riêng bạn và kho lưu trữ từ xa.

Lệnh git fetchlàm cho bản sao cục bộ của bạn được cập nhật bằng cách lấy dữ liệu từ kho lưu trữ từ xa. Lý do chúng tôi cần điều này là vì ai đó có thể đã thực hiện một số thay đổi đối với mã và bạn muốn tự cập nhật.

Lệnh git pullmang các thay đổi trong kho lưu trữ từ xa đến nơi bạn giữ mã của riêng mình. Thông thường, git pullthực hiện điều này bằng cách thực hiện 'git fetch' trước tiên để đưa bản sao cục bộ của kho lưu trữ từ xa cập nhật và sau đó nó hợp nhất các thay đổi vào kho lưu trữ mã của riêng bạn và có thể là bản sao làm việc của bạn.

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.