Как я могу заставить Git переходить по символическим ссылкам?
Вопрос
Моим лучшим вариантом будет сценарий оболочки, который заменяет символические ссылки копиями, или есть другой способ сообщить 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.
Подписаться 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 вместо символической ссылки по сценарию.