Как я могу заставить Git переходить по символическим ссылкам?

StackOverflow https://stackoverflow.com/questions/86402

  •  01-07-2019
  •  | 
  •  

Вопрос

Моим лучшим вариантом будет сценарий оболочки, который заменяет символические ссылки копиями, или есть другой способ сообщить Git, чтобы он следовал символическим ссылкам?

PS:Я знаю, что это не очень безопасно, но я хочу сделать это только в нескольких конкретных случаях.

Это было полезно?

Решение

ПРИМЕЧАНИЕ: Согласно комментарию, этот совет устарел начиная с Git 1.6.1.Git раньше вел себя подобным образом, но больше не ведет.


Git по умолчанию пытается сохранить символические ссылки вместо того, чтобы следовать им (для компактности, и это, как правило, то, чего хотят люди).

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

То есть.:

  /foo/
  /foo/baz
  /bar/foo --> /foo
  /bar/foo/baz

делая

 git add /bar/foo/baz

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

Другие советы

Что я сделал, чтобы добавить, чтобы получить файлы внутри символической ссылки в Git (я не использовал символическую ссылку, но):

sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY

Выполните эту команду в каталоге, управляемом Git. TARGETDIRECTORY должен быть создан до того, как SOURCEDIRECTORY вмонтирован в него.

Это прекрасно работает в Linux, но не в OS X!Этот трюк помог мне и с Subversion.Я использую его для включения файлов из аккаунта Dropbox, где веб-дизайнер делает свои вещи.

Почему бы не создавать символические ссылки наоборот?Это означает, что вместо ссылки из репозитория Git на каталог приложения, просто сделайте ссылку наоборот.

Например, допустим, я настраиваю приложение, установленное в ~/application для этого нужен файл конфигурации config.conf:

  • Я добавляю config.conf в мой репозиторий Git, например, по адресу ~/repos/application/config.conf.
  • Затем я создаю символическую ссылку из ~/application запустив ln -s ~/repos/application/config.conf.

Возможно, такой подход не всегда срабатывает, но пока у меня он работал хорошо.

Вместо этого используйте жесткие ссылки.Это отличается от программной (символической) ссылки.Все программы, включая git будет обрабатывать файл как обычный.Обратите внимание, что содержимое может быть изменено путем изменения либо источник или пункт назначения.

На macOS (до версии 10.13 High Sierra)

Если у вас уже установлены git и Xcode, установить жесткую ссылку.Это микроскопический инструмент для создания жестких ссылок.

Чтобы создать жесткую ссылку, просто:

hln source destination

Обновление macOS High Sierra

Поддерживает ли файловая система Apple жесткие ссылки на каталоги?

Жесткие ссылки на каталоги не поддерживаются файловой системой Apple.Все жесткие ссылки на каталог преобразуются в символические ссылки или псевдонимы при конвертации из форматов томов HFS + в APFS в macOS.

От Часто задаваемые вопросы по APFS developer.apple.com

Подписаться https://github.com/selkhateeb/hardlink/issues/31 для будущих альтернатив.

В Linux и других версиях Unix

Тот Самый ln команда может создавать жесткие ссылки:

ln source destination

В Windows (Vista, 7, 8, ...)

Кто-то предложил использовать мклинк создайте соединение в Windows, но я его еще не пробовал:

mklink /j "source" "destination"

Это настоящий крюк предварительной фиксации который заменяет двоичные объекты символьных ссылок в индексе содержимым этих символьных ссылок.

Положи это в .git/hooks/pre-commit, и сделать его исполняемым:

#!/bin/sh
# (replace "find ." with "find ./<path>" below, to work with only specific paths)

# (these lines are really all one line, on multiple lines for clarity)
# ...find symlinks which do not dereference to directories...
find . -type l -exec test '!' -d {} ';' -print -exec sh -c \
# ...remove the symlink blob, and add the content diff, to the index/cache
    'git rm --cached "$1"; diff -au /dev/null "$1" | git apply --cached -p1 -' \
# ...and call out to "sh".
    "process_links_to_nondir" {} ';'

# the end

Примечания

Мы максимально используем функциональность, совместимую с POSIX;однако, diff -a не совместим с POSIX, возможно, помимо прочего.

В этом коде могут быть некоторые ошибки, даже несмотря на то, что он был несколько протестирован.

Уже довольно давно я добавлял файлы помимо символических ссылок.Раньше это работало просто отлично, без каких-либо специальных приготовлений.С тех пор как я обновился до Git 1.6.1, это больше не работает.

Возможно, вы сможете переключиться на Git 1.6.0, чтобы заставить это работать.Я надеюсь, что в будущей версии Git будет установлен флаг для git-add позволяя ему снова переходить по символическим ссылкам.

Я устал от того, что каждое решение здесь либо устарело, либо требует root, так что Я создал решение на основе LD_PRELOAD (Только для Linux).

Он подключается к внутренним функциям Git, переопределяя функцию "это символическая ссылка?", позволяя рассматривать символические ссылки как их содержимое.По умолчанию все ссылки за пределами репозитория являются встроенными;смотрите ссылку для получения подробной информации.

С Git 2.3.2 + (1 квартал 2015) есть еще один случай, когда Git будет нет больше не переходите по символической ссылке:видишь зафиксировать e0d201b Автор: Джунио Си Хамано (gitster) (основной сопровождающий Git)

apply:не прикасайтесь к файлу, находящемуся за пределами символической ссылки

Поскольку Git отслеживает символические ссылки как символические ссылки, путь, который имеет символическую ссылку в своей начальной части (например path/to/dir/file, где path/to/dir является символической ссылкой на что-то еще, будь то внутри или за пределами рабочего дерева) никогда не может появиться в исправлении, которое действительно применяется, если только тот же самый патч сначала не удалит символическую ссылку, чтобы разрешить создание там каталога.

Обнаружьте и отклоните такой патч.

Аналогично, когда входные данные создают символическую ссылку path/to/dir а затем создает файл path/to/dir/file, нам нужно пометить это как ошибку , фактически не создавая path/to/dir символическая ссылка в файловой системе.

Вместо этого для любого исправления во входных данных, которое оставляет путь (т.е.без удаления) в результате мы сверяем все ведущие пути с результирующим деревом, которое будет создано исправлением, проверяя все исправления во входных данных, а затем цель приложения исправления (либо индекс, либо рабочее дерево).

Таким образом, мы:

  • поймайте ошибку при добавлении символической ссылки path/to/dir и напильник path/to/dir/file в то же время,
  • допуская допустимый патч, который удаляет символический link path/to/dir а затем добавляет файл path/to/dir/file.

Это означает, что в этом случае сообщение об ошибке не будет общим, например "%s: patch does not apply", но более конкретный:

affected file '%s' is beyond a symbolic link

Хммм, mount --bind похоже, на Дарвина это не действует.

У кого-нибудь есть трюк, который срабатывает?

[отредактировано]

Хорошо, я нашел ответ в Mac OS X - создать жесткую ссылку.За исключением того, что этот API не доступен через ln, поэтому вы должны использовать свою собственную крошечную программу, чтобы сделать это.Вот ссылка на эту программу:

Создание жестких ссылок на каталог в Mac OS X

Наслаждайтесь!

Вкл . MacOS (У меня есть Мохаве/ 10.14, git версия 2.7.1), используйте bindfs.

brew install bindfs

cd /path/to/git_controlled_dir

mkdir local_copy_dir

bindfs <source_dir> local_copy_dir

На это намекали другие комментарии, но не было четко указано в других ответах.Надеюсь, это сэкономит кому-то немного времени.

Я использую Git 1.5.4.3, и он следует за переданной символической ссылкой, если она имеет завершающую косую черту.Например.

# Adds the symlink itself
$ git add symlink

# Follows symlink and adds the denoted directory's contents
$ git add symlink/

Преобразование из символических ссылок может быть полезным.Ссылка в папке Git вместо символической ссылки по сценарию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top