3 Вопрос: Как Git обрабатывает символические ссылки?

вопрос создан в Sat, Oct 27, 2018 12:00 AM

Если у меня есть файл или каталог, который является символической ссылкой, и я фиксирую его в репозитории Git, что с ним происходит?

Я бы предположил, что он оставляет его как символическую ссылку до тех пор, пока файл не будет удален, а затем, если вы извлекаете файл из старой версии, он просто создает обычный файл.

Что он делает, когда я удаляю файл, на который ссылается? Это просто фиксирует висячую ссылку?

    
1460
  1. .gitignore видит символическую ссылку как файл, а не папку.
    2014-02-03 15: 34: 14Z
  2. Что ж, очевидно, в этом вопросе есть нечто большее, чем этот ответ. Например, мне интересно следующее: если я создам ссылку sym в своем репозитории на какой-то большой файл в этом репозитории, перенесу изменения, а затем перенесу эти изменения на другой компьютер, что произойдет? Будет ли большой файл храниться как большой файл в обоих местах или будет сохранена ссылка sym, чтобы на новом компьютере файл ссылки указывал на исходный большой файл?
    2014-06-13 00: 06: 34Z
  3. Это старая ветка, но этот комментарий все еще может быть полезен. В ответ на jviesem, мягкая ссылка - это файл с именем другого файла. Поэтому, как только вы перетащите его на другой компьютер, ссылка будет загружена, и она будет иметь имя большого файла в исходной файловой системе. Если на новом компьютере имя недействительно, то ссылка будет иметь недопустимое имя. Большой файл не будет загружен на новую машину.
    2015-11-19 18: 29: 11Z
  4. @ lasaro, способ избежать неработающих ссылок в git-репо - всегда использовать относительные пути при создании символических ссылок, используя при необходимости ../...
    2016-01-22 23: 57: 19Z
  5. Обратите внимание, что в большинстве версий Windows вам необходимы повышенные разрешения для создания символической ссылки. Если вы работаете в Windows и git pull создает файл вместо символической ссылки, попробуйте запустить клиент Git от имени администратора.
    2017-05-30 11: 04: 14Z
3 ответа                              3                         

Git просто хранит содержимое ссылки (то есть путь к объекту файловой системы, на которую он ссылается) в «BLOB-объекте», как это делается для обычного файла. Затем он сохраняет имя, режим и тип (включая тот факт, что это символическая ссылка) в объекте дерева, который представляет его содержащий каталог.

Когда вы извлекаете дерево, содержащее ссылку, он восстанавливает объект как символическую ссылку независимо от того, существует целевой объект файловой системы или нет.

Если вы удалите файл, на который ссылается символическая ссылка, он никак не повлияет на управляемую Git символическую ссылку. У вас будет свисающая ссылка. Пользователь может либо удалить, либо изменить ссылку, чтобы она указывала на что-то действительное, если это необходимо.

    
1220
2018-10-27 10: 02: 04Z
  1. Кстати. Если вы находитесь в файловой системе, такой как FAT, которая не поддерживает символические ссылки, и ваш репозиторий использует их, вы можете установить для переменной конфигурации core.symlinks значение false, и символические ссылки будут извлечены в виде небольших текстовых файлов, содержащих текст ссылки.
    2009-06-05 09: 42: 21Z
  2. @ JakubNarębski Я видел это раньше. В нашем репо был текстовый файл с одной строкой, путь к библиотеке, которую мы используем. Не могу понять, какова была цель этого. Теперь я знаю, что случилось.
    2014-04-10 14: 40: 09Z
  3. Я не решаюсь прокомментировать высоко голосованный ответ, но я думаю, что формулировка "так же, как этобудет для обычного файла "может вводить в заблуждение для новичков.
    2014-10-25 02: 55: 16Z
  4. (истекло время редактирования) Это похоже на обычный файл только в том, что содержимое находится в BLOB-объекте. Критическим отличием является то, что для обычного файла большой двоичный объект является содержимым файла, но для символической ссылки большой двоичный объект имеет путь к файлу, на который он ссылается. @ JakubNarębski Относительно "небольших текстовых файлов" .. Вы могли бы надеяться, что они маленькие и текстовые, но, конечно, большой двоичный объект - это большой двоичный объект, который потенциально может быть большим и двоичным. См. stackoverflow.com/questions/18411200/… для случая, когда файл был напечатан как символическая ссылка.
    2014-10-25 03:15: 26Z
  5. Обязательно проверьте свои глобальные настройки для символических ссылок и локальные настройки для символических ссылок. Если настройки были скопированы из TortiseGit или из окон, то вы можете связываться с ними symlinks = false.
    2017-12-12 17: 05: 16Z

TL; DR: данные, на которые ссылается символическая ссылка, не хранятся в хранилище.

Вы можете узнать, что Git делает с файлом, посмотрев, что он делает, когда вы добавляете его в индекс. Индекс похож на предварительную фиксацию. После фиксации индекса вы можете использовать git checkout, чтобы вернуть все, что было в индексе, обратно в рабочий каталог. Итак, что делает Git, когда вы добавляете символическую ссылку в индекс?

Чтобы узнать, сначала создайте символическую ссылку:

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

Git еще не знает об этом файле. git ls-files позволяет проверять ваш индекс (-s печатает stat-подобные выходные данные):

$ git ls-files -s ./symlink
[nothing]

Теперь добавьте содержимое символической ссылки в хранилище объектов Git, добавив его в индекс. Когда вы добавляете файл в индекс, Git сохраняет его содержимое в хранилище объектов Git.

$ git add ./symlink

Итак, что было добавлено?

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

Хеш - это ссылка на упакованный объект, который был создан в хранилище объектов Git. Вы можете проверить этот объект, если вы посмотрите в .git/objects/15/96f9db1b9610f238b78dd168ae33faa2dec15c в корне вашего хранилища. Это файл, который Git хранит в репозитории, который вы сможете позже проверить. Если вы посмотрите на этот файл, вы увидите, что он очень маленький. Он не хранит содержимое связанного файла.

(Примечание 120000 - это режим, указанный в выводе ls-files. Это будет что-то вроде 100644 для обычного файла.)

Но что Git делает с этим объектом, когда вы извлекаете его из хранилища и в свою файловую систему? Это зависит от конфигурации core.symlinks. Из man git-config :

  

core.symlinks р>      

Если false, символические ссылки извлекаются как небольшие простые файлы, содержащие текст ссылки.

Таким образом, при наличии символической ссылки в хранилище при извлечении вы получаете либо текстовый файл со ссылкой на полный путь к файловой системе, либо правильную символическую ссылку в зависимости от значения конфигурации core.symlinks.

В любом случае данные, на которые ссылается символическая ссылка, не сохраняются в хранилище.

    
207
2019-06-21 11: 41: 23Z
  

Примечание "редактора". Это сообщение может содержать устаревшую информацию. Пожалуйста, смотрите комментарии и этот вопрос об изменениях в Git с версии 1.6 0,1.

Связанные каталоги:

Важно отметить, что происходит, когда существует каталог, который является мягкой ссылкой. Любое Git pull с обновлением удаляет ссылку и делает ее нормальной директорией. Это то, чему я научился трудным путем. Некоторые идеи здесь и здесь.

Пример сильный> р>

Перед

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

git add/commit/push

It remains the same

После git pull И найдено несколько обновлений

 drwxrwsr-x 2 admin adm 4096 Oct  2 05:54 src/somedir
    
145
2018-10-27 10: 03: 27Z
  1. Стоит отметить, что эти предупреждения о символьных каталогах не применяются к версионным символическим ссылкам. Основным вопросом, о котором идет речь, было то, что люди символически связывали некоторые или все рабочее дерево по другому пути (скажем, в другой раздел с большим дисковым пространством) и ожидали, что git проверит код через существующую символическую ссылку. То есть, если у вас есть проект, который содержит версионные символические ссылки на файлы или каталоги, обычное поведение symlink-as-blob будет сохранять символические ссылки, правильно изменять версии этих символических ссылок и в противном случае работать должным образом.
    2009-12-22 01: 18: 30Z
  2. Вышеуказанное поведение протестировано с помощью git 1.6.5.6; но я сильно подозреваю, что версионное поведение в git уже довольно давно.
    2009-12-22 01: 18: 30Z
  3. Это поведение присутствует во всех версиях git или оно было исправлено с помощью?
    2011-06-09 20: 28: 03Z
  4. Кажется, что это поведение теперь исправлено, см .: stackoverflow.com/а /1943656/1334781
    2014-09-25 08: 15: 14Z
  5. Shekar: Вы разместите редактировать свой ответ, чтобы отразить изменения в git за последние годы?
    2017-06-22 18: 46: 17Z
источник размещен Вот
Другие вопросы
8
Как построить кривую ROC в Python
спросил 3 года назад
2
JCIFS SmbException
спросил 7 лет назад