a

Câu hỏi Sự khác biệt giữa 'git pull' và 'git fetch' là gì?


Ghi chú của người kiểm duyệt: Cho rằng câu hỏi này đã có sáu mươi bốn câu trả lời đăng lên đó, hãy cân nhắc xem bạn có góp phần mới trước khi đăng một số khác.

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


10149
2017-11-15 09:51


gốc


Tôi tìm thấy bài viết này cũng viết về git fetch và git kéo nó có giá trị đọc: longair.net/blog/2009/04/16/git-fetch-and-merge - Marcos Oliveira
Cách tiếp cận thay thế của chúng tôi đã trở thành git fetch; git reset --hard origin/master như là một phần của quy trình làm việc của chúng tôi. Nó thổi đi những thay đổi cục bộ, giữ cho bạn cập nhật với BUT chủ đảm bảo bạn không chỉ kéo những thay đổi mới lên trên những thay đổi hiện tại và tạo ra một mớ hỗn độn. 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 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 trong tiến trình đầu tiên! - Michael Durrant
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à 'lấy' thì có lẽ 'stash' cũng sẽ cần giải thích ... - Henry Heleine
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à nó không phải. Git tương đương với "hg pull" là "git fetch". - Serge Shultz
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 trong lệnh git pull cục bộ của bạn, chỉ tìm nạp mã cập nhật của nhánh hiện tại - Kartik Patel


Các câu trả lời:


Theo thuật ngữ đơn giản nhất, git pull làm một git fetch Theo sau là một git merge.

Bạn có thể làm một git fetch bất cứ lúc nào để cập nhật các chi nhánh theo dõi từ xa của bạn theo 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 theo 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í còn nghe nói về những người đang chạy git fetch định kỳ trong một công việc cron trong nền (mặc dù tôi sẽ không khuyên bạn nên làm điều này).

A git pull là những gì bạn sẽ làm để đưa chi nhánh địa phương cập nhật lên phiên bản từ xa, đồ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


8470
2017-11-15 09:52



"A" git pull "là những gì bạn sẽ làm để mang kho lưu trữ của bạn cập nhật" <- không phải là bản cập nhật kho lưu trữ đã được thực hiện bằng cách lấy? bạn không có nghĩa là nó mang đến cho các chi nhánh địa phương của bạn up-to-date với các chi nhánh từ xa? Để hợp nhất: Nó kết hợp 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? - Albert
@Albert: Vâng, nó được diễn đạt một cách kỳ lạ. git pull sẽ luôn hợp nhất vào chi nhánh hiện tại. Vì vậy, bạn chọn nhánh bạn muốn kéo từvà nó kéo nó vào nhánh hiện tại. Các từ nhánh có thể là cục bộ hoặc từ xa; nó thậm chí có thể là một nhánh từ xa không được đăng ký git remote (nghĩa là bạn chuyển URL trên git pull dòng lệnh). - intuited
@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 mọi xung đột hợp nhất cục bộ, sau đó đẩy trở lại điều khiển từ xa. - Greg Hewgill
Nếu tôi ở /home/alice/ và làm git fetch /home/bob, những thông số nào tôi nên chuyển sang phần tiếp theo git merge ? - ripper234
Lưu ý cho những người học Git: pull thực sự không thể được mô phỏng bởi fetch cộng với một merge. Tôi chỉ lấy một thay đổi mà chỉ có một con trỏ nhánh từ xa thay đổi, và merge từ chối làm bất cứ điều gì. pull, mặt khác, chuyển tiếp nhanh nhánh theo dõi của tôi. - Roman Starkov


  • Khi bạn sử dụng pull, Git cố gắng tự động thực hiện công việc của bạn cho bạn. Đó là bối cảnh nhạy cảm, vì vậy Git sẽ hợp nhất bất kỳ cam kết nào được ké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 các xung đột thường xuyên.

  • Khi bạn fetch, Git thu thậ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 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 bạn, nhưng đang làm việc trên thứ 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 cam kết vào nhánh chính của bạn, bạn sử dụng merge.


1850
2017-08-18 08:53



Đồng ý, bình luận tuyệt vời. Đó là lý do tại sao tôi ghét git kéo. Khi nào nó sẽ có ý nghĩa để 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ì sáp nhập hai tập tin đang làm gì? Điều gì sẽ xảy ra nếu hai chỉnh sửa đó được tách riêng về mặt vật lý trong tệp, nhưng LOGICALLY có tỷ lệ cược? - Lee Dixon
@elexhobby đặt ngắn gọn, git fetch chỉ cập nhật .git/ thư mục (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 chi nhánh địa phương của bạn, và nó không chạm vào master hoặc. Nó chạm vào remotes/origin/master mặc dù (xem git branch -avv). Nếu bạn có nhiều điều khiển từ xa hơn, hãy thử git remote update. Đây là một git fetch cho tất cả điều khiển từ xa trong một lệnh. - 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 loạt các băm .git/refs/remotes/origin/. - Chris
Khi bạn tìm nạp, Git thu thập bất kỳ cam kết nào từ nhánh đích 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 thế nào để tôi thấy những gì được mang từ xa và làm cách nào để kết hợp nó vào các chi nhánh địa phương của tôi? - アレックス
@Tino Những gì tôi vẫn không hiểu là ... đ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


Đ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 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ố máy khách có thể lấy mã từ máy chủ, làm việc trên nó, sau đó cam kết nó trở lại máy chủ. Giả định là máy khách luôn có thể liên lạc với máy chủ khi nó cần thực hiện một 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 một kho lưu trữ trung tâm (mặc dù bạn chắc chắn có thể sử dụng một kho nếu muốn). Ngoài ra git được thiết kế để khách hàng và "máy chủ" không cần phải 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í. Nó có thể làm việc hoàn toàn bị ngắt kết nối và ghi một đĩa CD để trao đổi mã thông 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 kho lưu trữ từ xa không thể truy cập được. Sau đó khi bạn cần gửi các thay đổi cho người khác, git có thể chuyển chúng thành 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 fetchlà lệnh cho biết "mang bản sao cục bộ của kho lưu trữ từ xa của tôi đến nay".

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

Thông thường git pull thực hiện điều này bằng cách thực hiện git fetch để mang bản sao cục bộ của kho lưu trữ từ xa được cập nhật, 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 lấy đi là để ghi nhớ rằng thường có ít nhất ba bản 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 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 cục bộ "được lưu trong bộ nhớ cache" của một kho lưu trữ từ xa.


1008
2018-03-31 18:43



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, một kho lưu trữ là một DAG các cam kết chỉ cho cha mẹ của họ. Các chi nhánh, về mặt kỹ thuật, không có gì hơn các tên có ý nghĩa của các cam kết. Sự khác biệt duy nhất giữa các nhánh địa phương và từ xa là các nhánh từ xa được bắt đầu bằng remoteName/  Git từ mặt đất lên là một đọc rất tốt. Một khi bạn hiểu được cách Git hoạt động - và nó đẹp đơn giản, thực sự - mọi thứ chỉ có ý nghĩa. - Emil Lundberg
Cảm ơn nhiều vì lời giải thích. Tôi đã không thực sự hiểu cho đến bây giờ mà Git được thiết kế để bạn không cần 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 đó có nghĩa là không có gì với tôi. tôi chưa bao giờ đã xem CVCS và tôi cũng chưa bao giờ không làm việc với kho lưu trữ từ xa của cha mẹ khi cộng tác với những người khác (tức là 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
Vì vậy, dựa trên điều này, tại sao KHÔNG phải là một ý tưởng tốt để git-fetch với một công việc cron? 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ẻ như là một ý tưởng hay. Trong thực tế, tôi cảm thấy như viết một kịch bản để kiểm tra xem tôi đã cập nhật từ xa của tôi trong 24 giờ qua và liên kết nó với một móc udev cho kết nối internet. - Brian Peterson
Một lý do tại sao nó KHÔNG phải là một ý tưởng tốt để có một công việc cron: thường khi làm việc trên một vé mới, hoặc cập nhật cho một chi nhánh, tôi muốn thấy những thay đổi được lấy. Nếu những thay đổi không đến trong quá trình tìm nạp, tôi sẽ tự tin hơn khi yêu cầu lập trình viên đồng nghiệp của tôi 'hey bạn đã đẩy?'. Tôi cũng có được một cảm giác bao nhiêu 'churn' trong kho kể từ lần cuối tôi tìm nạp. Đ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
@Nabheet Thing là, Git là hướng nội dung. Nó lưu trữ dữ liệu chỉ một lần, và trỏ đến nó nhiều lần. Đó là lý do tại sao trong Git, ngay cả nhiều cam kết trên đầu trang của một bản gốc không ảnh hưởng đến kích thước của repo nhiều, vì hầu hết các đối tượng là như nhau. - cst1992


Đây là Hình ảnh của Oliver Steele về cách tất cả chúng khớp với nhau:

enter image description here

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 clone và git merge...


664
2018-06-09 13:30



Hình ảnh được cập nhật với git clone và git merge sẽ rất hữu ích! - MEMark
Có, vui lòng thêm git merge - nó sẽ cho thấy rõ ràng rằng merge gọi riêng là KHÔNG giống như gọi pull bởi vì pull là hợp nhất từ ​​xa chỉ và bỏ qua các cam kết cục bộ của bạn trong chi nhánh địa phương của bạn mà là theo dõi các chi nhánh từ xa được kéo từ. - JustAMartin
Một bưc tranh đang gia ngan lơi noi! Hình ảnh được cập nhật có sao chép và hợp nhất luồng dữ liệu sẵn sàng ở đâu đó không? Bất kỳ luồng dữ liệu nào khác ngoài những gì đã có trong sơ đồ? - shikhanshu
@Contango hãy thêm bản sao và hợp nhất. Sẽ hữu ích cho những người mới như tôi. - rents
Có hai sơ đồ hiển thị bản sao và hợp nhất trong các câu trả lời khác (dưới đây) bởi th3sly và thedarkpassenger. - intotecho


Một trường hợp sử dụng git fetch là 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 có thể thay đổi các tệp trong nhánh hiện tại của bạn và bản sao làm việc.

git fetch
git diff ...origin

428
2018-05-07 19:23



Bổ sung tuyệt vời! Tôi đã bị nhầm lẫn bởi các dấu chấm, phải không: git diff origin - harm
tại sao không git diff ..origin? - Erik Allik
nguồn gốc git diff và git diff ..origin dường như hoạt động nhưng không phải thứ lạ ... - Marc
@Compustretch Không có nghĩa vụ phải là một không gian. git diff ...origin tương đương với git diff $(git-merge-base HEAD origin) origin (xem git diff [--options] <commit>...<commit> [--] [<path>…] phần của kernel.org/pub/software/scm/git/docs/git-diff.html#_description), khác với git diff origin; git diff ...origin về mặt khái niệm là những thay đổi được thực hiện trong origin kể từ khi nhánh hiện tại phân nhánh từ origin, trong khi git diff origin cũng bao gồm đảo ngược các thay đổi được thực hiện trong nhánh hiện tại vì nó được phân nhánh từ origin. - Max Nanasy
không có lệnh nào trong số các lệnh .. làm việc cho tôi (trên Windows), nhưng git diff origin/master hoạt động như đã đề cập bên dưới - Brian Burns


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

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

khi bạn bắt đầu làm việc và cam kết bạn nâng cao con trỏ chính thành HEAD + các cam kết của bạn. Nhưng con trỏ gốc / chủ vẫn trỏ đến những gì nó đã được khi bạn nhân bản.

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

  • Nếu bạn làm một git fetch nó sẽ chỉ lấy tất cả các thay đổi trong kho lưu trữ từ xa (GitHub) và di chuyển con trỏ gốc / chủ đến HEAD. Trong khi đó, chủ chi nhánh địa phương của bạn sẽ tiếp tục trỏ đến vị trí của nó.
  • Nếu bạn làm một git pull, nó sẽ làm về cơ bản 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.

342
2018-05-11 18:37



origin / master là một nhánh địa phương là COPY của master trên origin. Khi bạn tìm nạp, bạn cập nhật local: / origin / master. Một khi bạn thực sự grok rằng tất cả mọi thứ trong git là một nhánh, điều này làm cho rất nhiều ý nghĩa và là một cách rất mạnh mẽ để duy trì các thay đổi khác nhau, làm cho các chi nhánh địa phương nhanh chóng, hợp nhất và rebase, và thường nhận được rất nhiều giá trị ra khỏi phân nhánh giá rẻ mô hình. - cam8001
Vẫn còn khó hiểu. tôi đã nghĩ git fetch là theo nghĩa đen tải xuống các thay đổi trên repo từ xa vào repo địa phương của bạn, nhưng KHÔNG cam kết chúng - tức là, chúng vẫn cần được thêm / cam kết vào repo địa phương của bạn. - krb686
chỉ tìm nạp từ xa / nguồn gốc (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 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


Đôi khi một biểu diễn trực quan giúp ích.

enter image description here


180
2018-01-25 17:28



Tôi nghĩ bức tranh đã cho thấy nó ả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. - 太極者無極而生
@ 太極 者 無極 而 生 Đồng ý - hình ảnh này là khá gây hiểu lầm, bởi vì nó làm cho nó trông giống như git pull Là bỏ qua tìm nạp, tất nhiên là không chính xác. - forresthopkinsa
@thedarkpassenger Tại sao bạn không cập nhật hình ảnh của mình. Sau đó, nó sẽ là ảnh chụp tốt nhất cho người mới. ^^ - cmcromance
whats một sự khác biệt giữa một 'Local Repository' và 'Working Copy'? Không phải là cả hai địa phương trên máy tính? - theITvideos


Ngắn gọn

git fetch tương tự như pull như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 (refs và objects) nhưng địa phương của bạn vẫn giữ nguyên (tức là origin/master được cập nhật nhưng master vẫn như nhau) .

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

Hơn

git clone sao chép một repo.

git rebase lưu các nội dung từ nhánh hiện tại của bạn không nằm trong nhánh ngược dòng vào vùng 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 các thay đổi từ xa, tua lại nhánh địa phương của bạn, phát lại các thay đổi của bạn trên đầu 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.

Cũng thế, git branch -a sẽ cho bạn thấy chính xác những gì đang xảy 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 hữu ích:

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

và bao gồm git pull, git fetch, git clone và git rebase.

====

CẬP NHẬT

Tôi nghĩ tôi sẽ cập nhật điều này để cho thấy bạn thực sự sử dụng điều này như thế nào 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 đó, 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: so sánh chi nhánh git địa phương với nhánh từ xa?

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

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


166
2018-04-13 17:31



Âm thanh với tôi như thể ai đó chỉ muốn mã cục bộ phản ánh "mẹo", họ nên sử dụng git clone. Tôi đặt tip trong dấu ngoặc kép, như tôi giả định nó sẽ có nghĩa là bất cứ điều gì là chủ và những gì một người nào đó sẽ "Tải về như zip" từ github.com - Chris K
nếu bạn không hài lòng với những thay đổi sau khi bạn tìm kiếm thì sao? phải làm gì tiếp theo? - Kugutsumen
Đoạ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ề zeroing ra khỏi mọi thứ, cập nhật từ xa, sau đó phát lại các thay đổi của bạn trên các cam kết trước đó đã xảy ra trong khi bạn đang làm việc. Lời giải thích hoàn hảo cho rằng nó đúng. ;) - coblr