Как git обрабатывает символические ссылки?

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

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

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

3 ответов


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

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

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


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


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

чтобы узнать, во-первых, сделать символическая ссылка:

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

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

$ git ls-files -s ./symlink
$

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

$ git add ./symlink

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

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

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

на 120000 режим файл. Это было бы что-то вроде 100644 для обычного файла и является специальным режимом для ссылок. От man git-config:

ядра.симлинки

если false, символические ссылки проверяются как небольшие простые файлы, содержащие текст ссылки. git-update-index (1) и git-add (1) не изменят записанный тип на обычный файл.

использовать git cat-file -p для pretty-распечатать содержимое:

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

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


каталоги с символическими ссылками:

важно отметить, что происходит, когда есть каталог, который является мягкий ссылке. Любой 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