Câu hỏi Làm thế nào để git xử lý các liên kết tượng trưng?


Nếu tôi có một tập tin hoặc thư mục đó là một liên kết tượng trưng và tôi cam kết nó để một repo git những gì xảy ra với nó?

Tôi sẽ giả định rằng nó rời khỏi nó như là một liên kết tượng trưng cho đến khi tập tin bị xóa và sau đó nếu bạn kéo tập tin trở lại từ một phiên bản cũ nó chỉ tạo ra một tập tin bình thường.

Nó làm gì khi tôi xóa các tập tin nó tham khảo? Nó chỉ cam kết liên kết lơ lửng?


1316
2018-06-05 06:53


gốc


.gitignore thấy liên kết tượng trưng dưới dạng tệp không phải thư mục. - 0xcaff
Vâng, rõ ràng là có nhiều câu hỏi hơn là câu trả lời ngụ ý. Ví dụ, tôi tự hỏi sau đây: nếu tôi tạo một liên kết sym trong kho lưu trữ của tôi đến một số tệp lớn trong kho lưu trữ đó, hãy đẩy các thay đổi và sau đó kéo những thay đổi đó sang máy khác, điều gì sẽ xảy ra? Tệp lớn sẽ được lưu trữ dưới dạng tệp lớn ở cả hai vị trí hay liên kết sym được giữ nguyên, chẳng hạn trên máy mới, tệp liên kết sẽ trỏ đến tệp lớn gốc? - jvriesem
Đây là một chủ đề cũ nhưng nhận xét này vẫn có thể hữu ích. Để trả lời jviesem, một liên kết mềm về cơ bản là một tệp có tên của một tệp khác. Vì vậy, một khi bạn kéo nó đến một máy khác, liên kết sẽ được tải xuống và nó sẽ có tên của tập tin lớn trên hệ thống tập tin gốc. Nếu trên máy mới tên không hợp lệ, sau đó liên kết sẽ có tên không hợp lệ. Tệp lớn sẽ không được tải xuống máy mới. - lasaro
@lasaro, cách để tránh các liên kết bị hỏng trong repo git là luôn sử dụng các đường dẫn tương đối khi tạo các liên kết tượng trưng, ​​sử dụng ../.. khi cần thiết. - Wildcard
Lưu ý rằng trong hầu hết các phiên bản của Windows, bạn cần có quyền nâng cao để tạo một liên kết tượng trưng. Nếu bạn đang sử dụng Windows và git pull tạo một tệp thay vì liên kết tượng trưng, ​​hãy thử chạy cho bạn ứng dụng khách Git làm quản trị viên. - asmironov


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


git chỉ lưu trữ nội dung của liên kết (tức là đường dẫn của đối tượng hệ thống tệp mà nó liên kết đến) trong một 'blob' giống như một tệp bình thường. Sau đó lưu trữ tên, chế độ và loại (bao gồm cả thực tế là nó là một liên kết tượng trưng) trong đối tượng cây đại diện cho thư mục chứa của nó.

Khi bạn kiểm tra một cây có chứa liên kết, nó khôi phục đối tượng dưới dạng một liên kết tượng trưng bất kể đối tượng hệ thống tập tin đích có tồn tại hay không.

Nếu bạn xóa các tập tin mà các liên kết tượng trưng tham chiếu nó không ảnh hưởng đến git kiểm soát liên kết tượng trưng trong bất kỳ cách nào. Bạn sẽ có một tham chiếu lơ lửng. Người dùng có thể xóa hoặc thay đổi liên kết để trỏ đến nội dung nào đó hợp lệ nếu cần.


1097
2018-06-05 07:01



BTW. Nếu bạn đang sử dụng hệ thống tệp như FAT không hỗ trợ liên kết tượng trưng và kho lưu trữ của bạn sử dụng chúng, bạn có thể đặt core.symlinks biến cấu hình thành false và các liên kết tượng trưng sẽ được kiểm tra dưới dạng các tệp văn bản thuần túy có chứa văn bản liên kết. - Jakub Narębski
@ JakubNarębski Tôi đã thấy điều này trước đây. Có một tập tin văn bản trong repo của chúng tôi với một dòng, một đường dẫn đến một thư viện chúng tôi sử dụng. Không thể tìm ra mục đích của nó là gì. Tôi biết bây giờ chuyện gì đã xảy ra. - Matt K
Tôi ngần ngại bình luận về câu trả lời được đánh giá cao nhưng tôi nghĩ rằng cách nói "giống như một tập tin bình thường" có thể gây nhầm lẫn cho người mới đến. - Matthew Hannigan
(hết thời gian chỉnh sửa) Nó giống như một tập tin bình thường trong đó nội dung nằm trong một đốm màu. Sự khác biệt quan trọng là đối với một tệp bình thường, blob là nội dung tệp nhưng đối với một liên kết tượng trưng, ​​blob có tên đường dẫn của tệp mà nó liên kết đến. @ JakubNarębski Về "các tập tin văn bản nhỏ" .. Bạn sẽ hy vọng chúng nhỏ và văn bản nhưng tất nhiên một đốm màu là một đốm màu và có khả năng có thể lớn và nhị phân. Xem stackoverflow.com/questions/18411200/… khi tệp bị nhập sai dưới dạng liên kết tượng trưng. - Matthew Hannigan
Hãy chắc chắn kiểm tra cài đặt toàn cầu của bạn cho các liên kết tượng trưng và cài đặt cục bộ cho các liên kết tượng trưng. Nếu cài đặt được sao chép từ TortiseGit hoặc cửa sổ, thì bạn có thể có symlinks = false rối tung với họ. - phyatt


TL; DR: Dữ liệu được tham chiếu bởi liên kết tượng trưng không được lưu trữ trong kho lưu trữ.


Bạn có thể tìm hiểu những gì Git làm với một tập tin bằng cách nhìn thấy những gì nó làm khi bạn thêm nó vào chỉ mục. Chỉ mục giống như một cam kết trước. Với chỉ số đã cam kết, bạn có thể sử dụng git checkout để mang mọi thứ trong chỉ mục trở lại thư mục làm việc. Vì vậy, Git làm gì khi bạn thêm một liên kết tượng trưng vào chỉ mục?

Để tìm hiểu, trước tiên, hãy tạo liên kết tượng trưng:

$ ln -s /Path/referenced/by/symlink symlink

Git chưa biết về tệp này. git ls-files cho phép bạn kiểm tra chỉ mục của mình (-s bản in statgiống như đầu ra):

$ git ls-files -s ./symlink
$

Bây giờ, thêm nội dung của liên kết tượng trưng vào kho lưu trữ đối tượng Git bằng cách thêm nó vào chỉ mục. Khi bạn thêm một tệp vào chỉ mục, Git lưu trữ nội dung của nó trong kho lưu trữ đối tượng Git.

$ git add ./symlink

Vì vậy, những gì đã được thêm vào?

$ git ls-files -s ./symlink
120000 1596f9db1b9610f238b78dd168ae33faa2dec15c 0       symlink
$

Hàm băm là một tham chiếu đến đối tượng được đóng gói đã được tạo trong kho đối tượng Git. Bạn có thể kiểm tra đối tượng này nếu bạn nhìn vào .git/objects/15/96f9db1b9610f238b78dd168ae33faa2dec15c.

Các 120000 là chế độ tệp. Nó sẽ giống như 100644 cho một tệp thông thường và là chế độ đặc biệt cho các liên kết. Từ man git-config:

core.symlinks

Nếu sai, các liên kết tượng trưng được kiểm tra dưới dạng các tệp đơn giản có chứa văn bản liên kết. git-update-index (1) và git-add (1) sẽ không thay đổi loại được ghi thành tệp thông thường.

Sử dụng git cat-file -p để in đẹp nội dung:

$ git cat-file -p 1596f9db1
/Path/referenced/by/symlink

Vì vậy, đó là những gì Git thực hiện với một liên kết tượng trưng: khi bạn git checkout liên kết tượng trưng, ​​bạn sẽ nhận được một tệp văn bản có tham chiếu đến đường dẫn hệ thống tệp đầy đủ hoặc một liên kết tượng trưng, ​​tùy thuộc vào cấu hình. Dữ liệu được tham chiếu bởi liên kết tượng trưng không được lưu trữ trong kho lưu trữ.


152
2017-09-13 17:06





Thư mục được liên kết với nhau:

Điều quan trọng cần lưu ý những gì xảy ra khi có một thư mục là một liên kết mềm. Bất kỳ lệnh git pull nào có bản cập nhật sẽ xóa liên kết và làm cho nó trở thành một thư mục bình thường. Đây là những gì tôi học được một cách khó khăn. Một số thông tin chi tiết đây và đây.

Thí dụ

Trước

 ls -l
 lrwxrwxrwx 1 admin adm   29 Sep 30 15:28 src/somedir -> /mnt/somedir

git add / commit / push

It remains the same

Sau khi git pull AND tìm thấy một số cập nhật

 drwxrwsr-x 2 admin adm 4096 Oct  2 05:54 src/somedir

140
2017-10-02 06:16



Cần lưu ý rằng những cảnh báo này về các thư mục được liên kết với nhau đừng áp dụng cho các liên kết mềm được phiên bản. Trường hợp cạnh chính trong câu hỏi là của folks symlinking một số hoặc tất cả các cây làm việc vào một con đường khác nhau (nói lên một phân vùng khác với không gian đĩa nhiều hơn) và mong git để kiểm tra mã thông qua các liên kết hiện có. Tức là, nếu bạn có một dự án có chứa các liên kết đã được phiên bản cho các tệp hoặc thư mục, hành vi bình thường của symlink-as-blob sẽ giữ lại các liên kết tượng trưng, ​​thay đổi phiên bản chính xác thành các liên kết đó và hoạt động như mong đợi. - John Whitley
Các hành vi trên được thử nghiệm với git 1.6.5.6; nhưng tôi mạnh mẽ nghi ngờ rằng hành vi phiên bản đã đúng trong git trong một thời gian khá dài. - John Whitley
Hành vi này có xuất hiện trên tất cả các phiên bản của git hay không? - jbotnik
Dường như hành vi này đã được khắc phục ngay bây giờ, hãy xem: stackoverflow.com/a/1943656/1334781 - Ron Wertlen
Shekar: Bạn sẽ chỉnh sửa câu trả lời của mình để phản ánh những thay đổi trong git trong những năm gần đây? - einpoklum