2012-02-11 10 views
150

git pull --help nói:FETCH_HEAD trong Git có nghĩa là gì?

Trong chế độ mặc định của nó, git pull là viết tắt cho git fetch tiếp theo git merge FETCH_HEAD.

Đây là gì FETCH_HEAD và những gì thực sự được hợp nhất trong git pull?

+2

Lưu ý: từ git 1.8.4 (tháng 8 năm 2013), 'git fetch origin master' sẽ cập nhật' origin/master', không chỉ 'FETCH_HEAD'. Xem http://stackoverflow.com/a/20967347/6309 – VonC

+0

Để biết thêm về 'git merge FETCH_HEAD' (kể từ Git 2.5, Q2 2015), hãy xem http://stackoverflow.com/a/30425991/6309 – VonC

Trả lời

150

FETCH_HEAD là phần giới thiệu ngắn ngủi, để theo dõi những gì vừa được tìm nạp từ kho lưu trữ từ xa. git pull đầu tiên gọi git fetch, trong trường hợp bình thường tìm nạp nhánh từ xa; FETCH_HEAD trỏ đến đầu của nhánh này (nó lưu trữ SHA1 của cam kết, giống như các nhánh). git pull sau đó gọi git merge, hợp nhất FETCH_HEAD vào chi nhánh hiện tại.

Kết quả là chính xác những gì bạn mong đợi: cam kết ở đầu của nhánh từ xa thích hợp được hợp nhất vào cam kết ở đầu nhánh hiện tại của bạn.

Đây là một chút như làm git fetch không có đối số (hoặc git remote update), cập nhật tất cả các chi nhánh từ xa của bạn, sau đó chạy git merge origin/<branch>, nhưng sử dụng FETCH_HEAD nội bộ thay vì đề cập đến bất cứ điều gì ref đơn đã được tìm nạp thay vì cần phải đặt tên cho mọi thứ.

+1

Kéo có thể làm một rebase thay vì hợp nhất nếu bạn cấu hình nó theo cách đó. –

+0

@AdamDymitruk: Chắc chắn rồi. Tôi mô tả hành vi mặc định, cho rằng nếu ai đó sửa đổi nó, họ sẽ biết họ đã sửa đổi nó. (Để hoàn thành, hành vi giống hệt nhau, thay thế 'hợp nhất FETCH_HEAD' bằng' rebase FETCH_HEAD'). – Cascabel

+5

@ Jefromi: xin lỗi, tôi nghĩ rằng bạn sai: theo như tôi hiểu, 'git fetch' cập nhật (kết hợp) tất cả dữ liệu đối tượng từ bộ nhớ từ xa, không chỉ ** một bữa nửa buổi **. Vì vậy, tôi không hiểu từ câu trả lời của bạn như thế nào git quyết định tip của chi nhánh để trỏ 'FETCH_HEAD'. Tôi cũng không thể tìm thấy 'FETCH_HEAD' trong tài liệu git (định nghĩa, không phải ví dụ). Sự tồn tại của 'FETCH_HEAD' trông giống như một cách giải quyết khác, để làm cho' git pull' work _somehow_. – Alexey

1

git pull là kết hợp của tìm nạp được theo sau là hợp nhất. Khi git fetch xảy ra, nó ghi chú commit đầu của những gì nó tìm nạp trong FETCH_HEAD (chỉ là một tệp theo tên đó trong .git) Và các commit này sau đó được hợp nhất vào thư mục làm việc của bạn.

+3

@manjolds, bạn có ý nghĩa gì bởi "_head commit_ của những gì nó đã tìm nạp"? Git tìm nạp mọi thứ bằng tìm nạp. – Alexey

+0

@Alexey từ hướng dẫn sử dụng git: https://git-scm.com/docs/git-fetch: * Tên của các tham chiếu được tìm nạp, cùng với tên đối tượng mà chúng trỏ đến, được ghi vào .git/FETCH_HEAD * –

10

FETCH_HEAD là tham chiếu đến đầu của lần tìm nạp cuối cùng, cho dù tìm nạp đó được bắt đầu trực tiếp bằng lệnh tìm nạp hay là một phần của lệnh kéo. Giá trị hiện tại của FETCH_HEAD được lưu trữ trong thư mục .git trong một tệp có tên, bạn đã đoán nó, FETCH_HEAD.

Vì vậy, nếu tôi phát hành:

git fetch https://github.com/ryanmaxwell/Fragaria 

FETCH_HEAD có thể chứa

3cfda7cfdcf9fb78b44d991f8470df56723658d3  https://github.com/ryanmaxwell/Fragaria 

Nếu tôi có repo từ xa cấu hình như một chi nhánh theo dõi từ xa sau đó tôi có thể làm theo tôi lấy với một hợp nhất của việc theo dõi chi nhánh. Nếu tôi không, tôi có thể hợp nhất đầu tìm nạp cuối cùng trực tiếp bằng FETCH_HEAD.

git merge FETCH_HEAD 
4

Tôi vừa phát hiện và sử dụng FETCH_HEAD. Tôi muốn có một bản sao cục bộ của một số phần mềm từ một máy chủ và tôi đã làm

git fetch gitserver release_1 

gitserver là tên của máy tính của tôi mà các cửa hàng kho git. release_1 là thẻ cho phiên bản phần mềm. Trước sự ngạc nhiên của tôi, release_1 sau đó không được tìm thấy trên máy cục bộ của tôi. Tôi đã phải gõ

git tag release_1 FETCH_HEAD 

để hoàn thành bản sao của chuỗi tagged các cam kết (release_1) từ kho lưu trữ từ xa đến một địa phương.Tìm nạp đã tìm thấy thẻ từ xa, sao chép cam kết vào máy cục bộ của tôi, không phải là đã tạo thẻ cục bộ, nhưng đã đặt FETCH_HEAD thành giá trị của cam kết, để tôi có thể tìm và sử dụng nó. Sau đó tôi đã sử dụng FETCH_HEAD để tạo thẻ cục bộ khớp với thẻ trên điều khiển từ xa. Đó là một minh họa thực tế về những gì FETCH_HEAD là và làm thế nào nó có thể được sử dụng, và có thể hữu ích cho người khác tự hỏi tại sao git fetch không làm những gì bạn sẽ ngây thơ mong đợi.

Theo tôi nó tốt nhất là tránh cho rằng mục đích và là một cách tốt hơn để đạt được những gì tôi đang cố gắng làm là

git fetch gitserver release_1:release_1 

ví dụ: để lấy release_1 và gọi nó là release_1 tại địa phương. (Đó là nguồn: dest, xem https://git-scm.com/book/en/v2/Git-Internals-The-Refspec, chỉ cần trong trường hợp bạn muốn cung cấp cho nó một cái tên khác nhau!)

Bạn có thể muốn sử dụng FETCH_HEAD vào những thời điểm mặc dù: -

git fetch gitserver bugfix1234 
git cherry-pick FETCH_HEAD 

có thể là một cách tốt nhất để sử dụng số sửa lỗi 1234 từ máy chủ Git của bạn và để bộ sưu tập rác của Git vứt bỏ bản sao từ máy chủ sau khi sửa chữa đã được chọn vào nhánh hiện tại của bạn. (Tôi giả định rằng có một cam kết được gắn thẻ sạch đẹp chứa toàn bộ sửa lỗi trên máy chủ!)

+0

Phản hồi thú vị. +1 – VonC

+0

Cảm ơn. Tôi đã chỉnh sửa bài viết gốc của mình, được viết khi lần đầu tiên phát hiện FETCH_HEAD một vài năm trước, vì nó dường như khuyến khích sao chép thẻ bằng FETCH_HEAD thay vì cú pháp nguồn: dest cho refspecs. Hy vọng rằng bây giờ tôi đã đưa ra một ví dụ tốt hơn về cách FETCH_HEAD có thể được sử dụng. – user3070485

3

Như đã đề cập trong Jonathan's answer, FETCH_HEAD tương ứng với tệp .git/FETCH_HEAD. Thông thường, tệp sẽ trông giống như sau:

71f026561ddb57063681109aadd0de5bac26ada9      branch 'some-branch' of <remote URL> 
669980e32769626587c5f3c45334fb81e5f44c34  not-for-merge branch 'some-other-branch' of <remote URL> 
b858c89278ab1469c71340eef8cf38cc4ef03fed  not-for-merge branch 'yet-some-other-branch' of <remote URL> 

Lưu ý cách tất cả các nhánh nhưng một được đánh dấu not-for-merge. Cái lẻ ra là nhánh đã được kiểm tra trước khi lấy. Tóm lại: FETCH_HEAD về cơ bản tương ứng với phiên bản từ xa của chi nhánh hiện đã được kiểm tra.