2014-09-12 17 views
5

Tôi muốn tìm nạp một cam kết đơn lẻ (với lịch sử, tất nhiên) của một kho lưu trữ từ xa vào một kho lưu trữ cục bộ. Một số phản ứng Stack Overflow gợi ý rằng sau đây nên làm việc, nhưng nó không:Git tìm nạp một cam kết đơn

md foo 
cd foo 
git init 
git fetch https://github.com/ld4apps/lda-serverlib.git f1e32e18a90e10c150221af55c69aeafaa42c57a 

này tạo ra các lỗi sau:

error: no such remote ref f1e32e18a90e10c150221af55c69aeafaa42c57a

Đáng ngạc nhiên (với tôi) sau không (loại) công việc:

git fetch https://github.com/ld4apps/lda-serverlib.git :f1e32e18a90e10c150221af55c69aeafaa42c57a 

này tạo ra một chi nhánh địa phương mới gọi là f1e32e18a90e10c150221af55c69aeafaa42c57a (mà tôi không muốn), nhưng ít nhất các chi nhánh mới gồm những nội dung tôi đã cố gắng để lấy. Tôi có thể dự đoán rằng lệnh sau đây sẽ làm điều tương tự, nhưng nó được lỗi tương tự như ví dụ đầu tiên:

git fetch https://github.com/ld4apps/lda-serverlib.git f1e32e18a90e10c150221af55c69aeafaa42c57a:f1e32e18a90e10c150221af55c69aeafaa42c57a 

Tôi cố gắng này trên Windows và Linux với một vài phiên bản git khác nhau và thấy giống nhau hành vi.

Có ai có thể giải thích những gì đang xảy ra ở đây không? Tôi không hiểu gì về Git, fetch và refspec? Điều tôi thực sự muốn là một lệnh git fetch duy nhất mà tôi có thể cung cấp id của một chi nhánh hoặc thẻ từ xa hoặc một thẻ cam kết và nó sẽ tìm nạp commit tương ứng.

+0

"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

+0

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. –

+0

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

Trả lời

5

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! :-))

+0

Cảm ơn, Torek, đó là hữu ích và dường như giải thích hầu hết những gì tôi nhìn thấy. Tôi không thấy điều đó giải thích tại sao/cách git fetch https://github.com/ld4apps/lda-serverlib.git :f1e32e18a90e10c150221af55c69aeafaa42c57a hoạt động. chuyện gì đang xảy ra ở đó vậy? –

+0

Đã thêm đoạn cuối cùng có "mục đích". Sẽ xem liệu tôi có thể làm rõ việc tạo chi nhánh ... – torek

+0

Có lẽ tôi đang buồn tẻ ở đây. Tôi hiểu rằng RHS kiểm soát tên của chính tôi, vì vậy tôi không ngạc nhiên khi 'git fetch repo: f1e32e18a90e10c150221af55c69aeafaa42c57a' tạo một chi nhánh địa phương có tên f1e32e18a90e10c150221af55c69aeafaa42c57a. Điều gì làm tôi ngạc nhiên là nó cũng lấy được cam kết của cùng một id trên điều khiển từ xa, mặc dù cam kết đó không phải là địa chỉ khi tôi đặt nó trên LHS. –

Các vấn đề liên quan