(Câu trả lời này mất một lúc để viết và câu trả lời của codeWizard đúng về mục tiêu và bản chất, nhưng không hoàn toàn đầy đủ, vì vậy tôi sẽ đăng bài này.)
Không có thứ gọi là "thẻ Git từ xa". Chỉ có "thẻ". Tôi chỉ tất cả ra đây không phải là gàn dở, 1 nhưng bởi vì có rất nhiều nhầm lẫn về điều này với những người dùng Git giản dị, và các tài liệu Git không phải là rất hữu ích 2 để bắt đầu. (Không rõ liệu sự nhầm lẫn xuất hiện do tài liệu kém hay tài liệu kém xuất hiện vì điều này vốn đã hơi khó hiểu hoặc là gì.)
Có là "chi nhánh từ xa", gọi đúng hơn "chi nhánh từ xa theo dõi", nhưng nó đáng chú ý là thực tế đây là các đơn vị địa phương. Không có thẻ từ xa, mặc dù (trừ khi bạn (tái) phát minh ra chúng). Chỉ có các thẻ cục bộ, vì vậy bạn cần lấy thẻ cục bộ để sử dụng nó.
Biểu mẫu chung cho các tên cho các cam kết cụ thể mà Git gọi tham chiếu là bất kỳ chuỗi nào bắt đầu bằng refs/
. Một chuỗi bắt đầu bằng refs/heads/
tên một nhánh; một chuỗi bắt đầu bằng refs/remotes/
tên một nhánh theo dõi từ xa; và một chuỗi bắt đầu bằng refs/tags/
tên một thẻ. Tên refs/stash
là tham chiếu stash (như được sử dụng bởi git stash
; lưu ý thiếu dấu gạch chéo).
Có một số bất thường tên đặc biệt hợp cụ thể mà không bắt đầu bằng refs/
: HEAD
, ORIG_HEAD
, MERGE_HEAD
, và CHERRY_PICK_HEAD
đặc biệt là tất cả cũng tên có thể tham khảo các cam kết cụ thể (mặc dù HEAD
thường chứa tên của một chi nhánh, tức là chứa ). Nhưng nói chung, tài liệu tham khảo bắt đầu với .ref: refs/heads/branch
refs/
Một điều Git làm để làm cho điều này trở nên khó hiểu là nó cho phép bạn bỏ qua refs/
, và thường là từ sau refs/
. Chẳng hạn, bạn có thể bỏ qua refs/heads/
hoặc refs/tags/
khi đề cập đến một chi nhánh địa phương hoặc gắn thẻ và thực tế bạn phải bỏ qua refs/heads/
khi kiểm tra một chi nhánh địa phương! Bạn có thể làm điều này bất cứ khi nào kết quả không rõ ràng, hoặc vì chúng tôi chỉ lưu ý khi bạn phải làm điều đó (cho ).git checkout branch
Đúng là các tài liệu tham khảo không chỉ tồn tại trong kho lưu trữ của riêng bạn mà còn trong các kho lưu trữ từ xa. Tuy nhiên, Git cung cấp cho bạn quyền truy cập vào tài liệu tham khảo của kho lưu trữ từ xa vào những thời điểm rất cụ thể: cụ thể là, trong fetch
và push
hoạt động. Bạn cũng có thể sử dụng git ls-remote
hoặc git remote show
để nhìn thấy chúng, nhưng fetch
và push
là những điểm thú vị hơn tiếp xúc.
Giới thiệu
Trong fetch
và push
, Git sử dụng các chuỗi mà nó gọi là refspecs để chuyển các tham chiếu giữa kho lưu trữ cục bộ và từ xa. Do đó, chính tại thời điểm này và thông qua các refspec, hai kho Git có thể đồng bộ với nhau. Khi tên của bạn được đồng bộ hóa, bạn có thể sử dụng cùng tên mà một người có điều khiển từ xa sử dụng. Có một số phép thuật đặc biệt ở đây fetch
, mặc dù, và nó ảnh hưởng đến cả tên nhánh và tên thẻ.
Bạn nên nghĩ đến git fetch
việc chỉ đạo Git của bạn gọi lên (hoặc có thể là tin nhắn văn bản) một Git khác, "từ xa" và có một cuộc trò chuyện với nó. Đầu cuộc trò chuyện này, từ xa liệt kê tất cả các tài liệu tham khảo của nó: mọi thứ trong refs/heads/
và mọi thứ trong đó refs/tags/
, cùng với bất kỳ tài liệu tham khảo nào khác mà nó có. Git của bạn quét qua những thứ này và (dựa trên refspec tìm nạp thông thường) đổi tên các nhánh của chúng.
Chúng ta hãy xem các refspec bình thường cho điều khiển từ xa có tên origin
:
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$
Refspec này hướng dẫn Git của bạn lấy mọi tên trùng khớp refs/heads/*
vớiieie, mọi chi nhánh trên điều khiển từ xa và thay đổi tên của nó thành refs/remotes/origin/*
, giữ nguyên phần trùng khớp, thay đổi tên chi nhánh ( refs/heads/
) thành tên chi nhánh theo dõi từ xa ( refs/remotes/
cụ thể là , refs/remotes/origin/
)
Thông qua refspec này , origin
các nhánh của nó trở thành các nhánh theo dõi từ xa của bạn cho điều khiển từ xa origin
. Tên chi nhánh trở thành tên chi nhánh theo dõi từ xa, với tên của điều khiển từ xa, trong trường hợp này origin
, bao gồm. Dấu cộng +
ở phía trước của refspec đặt cờ "lực lượng", nghĩa là nhánh theo dõi từ xa của bạn sẽ được cập nhật để khớp với tên nhánh của điều khiển từ xa, bất kể nó cần gì để khớp với nó. (Nếu không có +
, cập nhật chi nhánh được giới hạn để "fast forward" thay đổi và cập nhật thẻ chỉ đơn giản là bỏ qua kể từ khi phiên bản Git 1.8.2 hoặc cái trước thì quy tắc tương tự nhanh về phía trước áp dụng.)
Thẻ
Nhưng những gì về thẻ? Không có refspec cho họ Ít nhất, không phải mặc định. Bạn có thể đặt một, trong trường hợp đó, hình thức của refspec tùy thuộc vào bạn; hoặc bạn có thể chạy git fetch --tags
. Việc sử dụng --tags
có tác dụng thêm refs/tags/*:refs/tags/*
vào refspec, nghĩa là, nó mang lại tất cả các thẻ ( nhưng không cập nhật thẻ của bạn nếu bạn đã có thẻ với tên đó, bất kể thẻ từ xa nói gì, Chỉnh sửa, tháng 1 năm 2017: kể từ Git 2.10 , kiểm tra cho thấy --tags
buộc phải cập nhật các thẻ của bạn từ các thẻ của điều khiển từ xa, như thể refspec đã đọc +refs/tags/*:refs/tags/*
, đây có thể là một sự khác biệt trong hành vi so với phiên bản Git trước đó).
Lưu ý rằng không có đổi tên ở đây: nếu điều khiển từ xa origin
có thẻ xyzzy
và bạn không, và bạn git fetch origin "refs/tags/*:refs/tags/*"
, bạn sẽ được refs/tags/xyzzy
thêm vào kho lưu trữ của mình (trỏ đến cùng một cam kết như trên điều khiển từ xa). Nếu bạn sử dụng +refs/tags/*:refs/tags/*
thì thẻ của bạn xyzzy
, nếu bạn có, được thay thế bằng thẻ từ origin
. Đó là, +
cờ lực trên một refspec có nghĩa là "thay thế giá trị tham chiếu của tôi bằng giá trị Git của tôi nhận được từ Git của họ".
Thẻ tự động trong quá trình tìm nạp
Vì lý do lịch sử, 3 nếu bạn sử dụng --tags
tùy chọn cũng không phải --no-tags
tùy chọn, git fetch
sẽ có hành động đặc biệt. Hãy nhớ rằng chúng tôi đã nói ở trên rằng điều khiển từ xa bắt đầu bằng cách hiển thị cho Git cục bộ của bạn tất cả các tham chiếu của nó, cho dù Git cục bộ của bạn có muốn xem chúng hay không. 4 Git của bạn ghi chú tất cả các thẻ mà nó nhìn thấy tại thời điểm này. Sau đó, khi nó bắt đầu tải xuống bất kỳ đối tượng cam kết nào, nó cần xử lý bất cứ thứ gì nó tìm nạp, nếu một trong những cam kết đó có cùng ID với bất kỳ thẻ nào, git sẽ thêm thẻ đó hoặc các thẻ đó, nếu nhiều thẻ có ID ID đó vào kho lưu trữ của bạn.
Chỉnh sửa, tháng 1 năm 2017: thử nghiệm cho thấy các hành vi trong Git 2.10 bây giờ là: Nếu Git của họ cung cấp một thẻ tên T , và bạn không có một thẻ tên T , và cam kết ID kết hợp với T là tổ tiên của một trong những chi nhánh của họ rằng bạn git fetch
đang kiểm tra, Git của bạn thêm T vào thẻ của bạn có hoặc không có --tags
. Việc thêm --tags
khiến Git của bạn có được tất cả các thẻ của họ và cũng buộc phải cập nhật.
Dòng dưới cùng
Bạn có thể phải sử dụng git fetch --tags
để có được thẻ của họ. Nếu tên thẻ của chúng xung đột với tên thẻ hiện tại của bạn, bạn có thể (tùy thuộc vào phiên bản Git) thậm chí phải xóa (hoặc đổi tên) một số thẻ của mình, sau đó chạy git fetch --tags
, để lấy thẻ của chúng. Vì các thẻ mà không giống như các chi nhánh từ xa, nên không có việc đổi tên tự động, tên thẻ của bạn phải khớp với tên thẻ của chúng, đó là lý do tại sao bạn có thể gặp sự cố với xung đột.
Tuy nhiên, trong hầu hết các trường hợp thông thường, một người đơn giản git fetch
sẽ thực hiện công việc, mang lại các cam kết và thẻ phù hợp của họ, và vì họ là bất cứ ai, họ sẽ gắn thẻ vào thời điểm họ công bố các cam kết đó, bạn sẽ theo kịp các thẻ của họ. Nếu bạn không tạo các thẻ của riêng mình, cũng không trộn lẫn kho lưu trữ của chúng và các kho lưu trữ khác (thông qua nhiều điều khiển từ xa), bạn sẽ không có bất kỳ xung đột tên thẻ nào, vì vậy bạn sẽ không phải loay hoay với việc xóa hoặc đổi tên thẻ để có được thẻ của họ.
Khi bạn cần tên đủ điều kiện
Tôi đã đề cập ở trên mà bạn có thể bỏ qua refs/
hầu như mọi khi, và refs/heads/
và refs/tags/
và vân vân hầu hết thời gian. Nhưng khi nào bạn không thể ?
Các (anyway hoặc gần như hoàn chỉnh) hoàn chỉnh câu trả lời là trong các gitrevisions
tài liệu hướng dẫn . Git sẽ phân giải tên thành ID cam kết bằng chuỗi sáu bước được đưa ra trong liên kết. Thật kỳ lạ, các thẻ ghi đè lên các nhánh: nếu có một thẻ xyzzy
và một nhánh xyzzy
và chúng trỏ đến các cam kết khác nhau, thì:
git rev-parse xyzzy
sẽ cung cấp cho bạn ID mà thẻ trỏ tới. Tuy nhiên, và đây là thứ còn thiếu gitrevisions
- git checkout
thích tên chi nhánh, vì vậy git checkout xyzzy
sẽ đưa bạn vào chi nhánh, bỏ qua thẻ.
Trong trường hợp không rõ ràng, bạn hầu như luôn có thể đánh vần tên ref bằng tên đầy đủ của nó, refs/heads/xyzzy
hoặc refs/tags/xyzzy
. (Lưu ý rằng điều này không làm việc với git checkout
, nhưng trong một cách có lẽ bất ngờ: git checkout refs/heads/xyzzy
làm một kiểm tra tách ra-HEAD chứ không phải là kiểm tra chi nhánh Đây là lý do tại sao bạn chỉ cần lưu ý đó. git checkout
Sẽ sử dụng tên viết tắt như một tên chi nhánh đầu tiên: đó là cách bạn kiểm tra chi nhánh xyzzy
ngay cả khi thẻ xyzzy
tồn tại. Nếu bạn muốn kiểm tra thẻ, bạn có thể sử dụng refs/tags/xyzzy
.)
Bởi vì (như gitrevisions
ghi chú) Git sẽ thử , bạn cũng có thể viết đơn giản để xác định cam kết được gắn thẻ . (Nếu ai đó đã cố gắng viết một tham chiếu hợp lệ tên vào , tuy nhiên, điều này sẽ giải quyết như . Nhưng thường chỉ khác nhau tên phải ở trong .)refs/name
tags/xyzzy
xyzzy
xyzzy
$GIT_DIR
$GIT_DIR/xyzzy
*HEAD
$GIT_DIR
1 Được rồi, được rồi, "không chỉ là phạm tội". :-)
2 Một số người sẽ nói "rất không hữu ích", và tôi thực sự có xu hướng đồng ý.
3 Về cơ bản, git fetch
và toàn bộ khái niệm từ xa và refspecs, là một chút bổ sung muộn cho Git, xảy ra vào khoảng thời gian của Git 1.5. Trước đó, chỉ có một số trường hợp đặc biệt đặc biệt, và tìm nạp thẻ là một trong số đó, vì vậy nó đã được mở rộng thông qua mã đặc biệt.
4 Nếu có ích, hãy nghĩ về Git từ xa như một flasher , theo nghĩa tiếng lóng.
git checkout A
. làA
gì Làm thế nào bạn tạo raA
?