Cập nhật: kể từ Git 2.5 (giữa năm 2015 trở lên), máy chủ hiện tại có thể hiển thị băm thô. Đây là một mục cấu hình phía máy chủ. Bạn phải có đủ quyền kiểm soát trên máy chủ để đặt nó và bạn nên xem xét các vấn đề bảo mật tiềm ẩn trước khi bạn đặt nó. Xem this answer đến Retrieve specific commit from a remote Git repository để biết chi tiết. (Câu trả lời gốc, áp dụng cho pre-2,5 hoặc nếu núm cấu hình không được thiết lập, dưới đây.)
Lệnh git fetch
cung cấp tài liệu tham khảo (tên, không thô cam-ID) để điều khiển từ xa, nhiều hoặc ít hơn. (Cụ thể hơn, sử dụng git ls-remote remotename
để xem điều khiển từ xa sẵn sàng cung cấp cho bạn về tên. Điều này tạo danh sách SHA-1 ở bên trái có tên bên phải và điều duy nhất mà bạn fetch
có thể yêu cầu là các tên-on-the-right. Tại thời điểm đó bạn sẽ nhận được ID-on-the-left nếu tên trên điều khiển từ xa vẫn trỏ đến ID đó, do đó phụ thuộc vào mức độ cập nhật của từ xa.) Có thể, theo nhiều cách khác nhau, để cung cấp ID cam kết thô cho điều khiển từ xa và yêu cầu điều khiển từ xa hiển thị bắt đầu từ điểm đó và đôi khi cũng hoạt động ngược lại thông qua lịch sử, nhưng không qua git fetch
. (Bạn có thể sử dụng git archive
nhưng điều khiển từ xa có thể quyết định có cho phép bạn truy cập thông qua các ID cam kết thô hay không. cam kết, và sử dụng điều đó để "khoan xuống", như họ nói, với các phần khác nhau. Nhưng đó là một cách rất chậm để làm điều đó.)
Nếu bạn muốn sử dụng git fetch
để nhận một số cam kết cụ thể, có lẽ cách dễ nhất để làm điều đó là để ai đó có quyền truy cập vào điều khiển từ xa gắn một tên - rất có thể là một thẻ - với ID cam kết đó. Sau đó, bạn có thể có git fetch
của bạn mang lại cho rằng refspec, và đặt nó dưới bất kỳ refspec khác mà bạn thích.Ví dụ, giả sử bạn có thể ssh trực tiếp đến bất cứ điều gì host origin
:
$ ssh our.origin.host 'cd /repos/repo.git; git tag temporary f1e32e1'
[enter password, etc; observe tag created]
$ git fetch origin refs/tags/temporary:refs/heads/newbranch
[observe fetch happen; now you have local branch 'newbranch']
$ ssh our.origin.host 'cd /repos/repo.git; git tag -d temporary'
Lưu ý rằng tên không cần phải là một chi nhánh, nó cần chỉ là một tài liệu tham khảo bạn có thể kéo qua với git fetch
và xem với git ls-remote
. Sau đó, bạn sử dụng tên sẽ khớp với tên đó ở phía bên trái của refspec của bạn khi tìm nạp. Tên được tạo trong repo của bạn được kiểm soát bởi phía bên tay phải của refspec (refs/heads/newbranch
trong ví dụ ở trên).
Đây cũng là câu trả lời cho câu hỏi đoạn cuối của bạn: bạn chỉ có thể đặt tên cho những thứ có tên trên điều khiển từ xa (phần này nhằm tránh "rò rỉ" các cam kết chưa đặt tên vẫn còn trong kho trước khi thu gom rác, vì vậy được coi là một tính năng chứ không phải là một lỗi). Những tên này đi trên LHS của refspec. Tên của bạn đi bên phải.
Tên của bạn ở bên phải được giả định là một chi nhánh hoặc thẻ tên (dựa trên những gì tên trên các trận đấu trái, mặc dù bạn có thể rõ ràng giải thích rõ ràng refs/heads/
hoặc refs/tags/
để ghi đè lên nó), vì vậy mặc dù f1e32e1...
là hợp lệ SHA-1, tên được coi là tên chi nhánh ở đây — tên còn thiếu ở bên trái được dịch thành HEAD
, vì tên thiếu hầu như luôn hoạt động — và git fetch
tạo một chi nhánh có tên gây phiền toái SHA-1-ish. (Ngẫu nhiên tôi đã từng tạo ra một tên chi nhánh trông giống như một SHA-1, và sau đó tự nhầm lẫn. Tôi quên chính xác tên đó là gì, một cái gì đó giống như de-bead
mà không có dấu gạch nối. 't có nghĩa là một cam kết nguyên ID! :-))
"cam kết đơn với lịch sử" nghĩa là gì? Các cam kết khác là lịch sử ... – Ryan
Tôi chỉ có nghĩa là hành vi git thông thường, không có gì đặc biệt. Tôi muốn lấy một cam kết cụ thể và tôi hiểu rằng git cũng sẽ tìm nạp các cam kết cấu thành lịch sử cho cam kết mà tôi chỉ định. –
Vâng, nó sẽ không xảy ra nếu bạn sử dụng 'git fetch --depth = 1' (và điều đó xảy ra để làm việc, vì f1e32e18a90e10c150221af55c69aeafaa42c57a là mẹo hiện tại cho ví dụ của bạn, nhưng đó không phải là câu hỏi đúng không?). – Ryan