Git Символы в Windows
Наши разработчики используют сочетание ОС Windows и Unix. Поэтому символические ссылки, созданные на машинах Unix, становятся проблемой для разработчиков Windows. В windows (msysgit) символическая ссылка преобразуется в текстовый файл с указанием пути к файлу, на который он указывает. Вместо этого я хотел бы преобразовать символическую ссылку в символическую ссылку Windows.
Решение (обновлено), которое у меня есть:
- Напишите post-checkout script, который будет рекурсивно искать текстовые файлы symlink.
- Замените их символической ссылкой Windows (используя mklink) с тем же именем и расширением, что и фиктивная "символическая ссылка"
- Игнорировать эти символические ссылки Windows, добавив запись в .git/info/exclude
Я не реализовал это, но считаю, что это надежный подход к этой проблеме.
Вопросы:
- Что, если таковые имеются, то вы видите этот подход?
- Является ли этот пост-checkout script даже выполнимым? то есть я могу рекурсивно узнать фиктивные "символические" файлы git создает?
- Кто-нибудь уже работал над такими script?
Ответы
Ответ 1
Вы можете найти символические ссылки, ища файлы с режимом 120000
, возможно, с помощью этой команды:
git ls-files -s | awk '/120000/{print $4}'
После того, как вы замените ссылки, я бы рекомендовал маркировать их как неизменные с помощью git update-index --assume-unchanged
, а не перечислять их в .git/info/exclude
.
Ответ 2
Я задавал этот один и тот же вопрос некоторое время назад (не здесь, как правило, вообще), и в итоге получилось очень похожее решение предложения OP. Сначала я дам прямые ответы на вопросы 1 2 и 3, а затем опубликую решение, которое я использовал.
- В предлагаемом решении действительно несколько недостатков, главным образом в отношении увеличения потенциала загрязнения репозитория или случайного добавления дубликатов файлов, когда они находятся в состоянии "символической ссылки Windows". (Подробнее об этом см. Ниже "Ограничения").
- Да, сценарий проверки post- можно реализовать! Возможно, это не так, как буквальный шаг post-
git checkout
, но приведенное ниже решение удовлетворило мои потребности достаточно хорошо, чтобы буквальный post- скрипт проверки не был необходим. - Да!
Решение:
Наши разработчики в той же ситуации, что и OP: смесь Windows и Unix-хостов, репозиториев и подмодулей со многими символическими ссылками git, а также нет встроенной поддержки в выпуске MsysGit для интеллектуальной обработки этих символических ссылок на хостах Windows,
Благодаря Джошу Ли за то, что git совершает символические ссылки со специальным файловым номером 120000
. С помощью этой информации можно добавить несколько git-псевдонимов, которые позволяют создавать и манипулировать символическими ссылками git на хостах Windows.
-
Создание символических ссылок git в Windows
ОБНОВЛЕНО 2014-11-12 (см. Ниже)
git config --global alias.add-symlink '!__git_add_symlink(){
argv=([email protected])
argc=${#argv[@]}
# Look for options
options=(" -h")
o_help="false"
case "${argv[@]}" in *" -h"*) o_help="true" ;; esac
if [ "$o_help" == "true" -o "$argc" -lt "2" ]; then
echo "\
Usage: git add-symlink <target> <link>
* <target> is a RELATIVE PATH, respective to <link>.
* <link> is a RELATIVE PATH, respective to the repository'\' root dir.
* Command must be run from the repository'\' root dir."
return 0
fi
target_arg=${argv[0]}
link_arg=${argv[1]}
if [ ! -e "$target_arg" ]; then
echo "ERROR: Target $target_arg does not exist; not creating invalid symlink."
return 1
fi
hash=$(echo -n "$target_arg" | git hash-object -w --stdin)
git update-index --add --cacheinfo 120000 "$hash" "$link_arg"
git checkout -- "$link_arg"
}; __git_add_symlink "[email protected]"'
Использование: git add-symlink <src> <dst>
, где <src>
- относительная ссылка (по отношению к <dst>
) к текущему местоположению файла или каталога для ссылки, а <dst>
- относительная ссылка (в отношении корня репозитория) к ссылке желаемого адресата.
Например, дерево репозитория:
dir/
dir/foo/
dir/foo/bar/
dir/foo/bar/baz (file containing "I am baz")
dir/foo/bar/lnk_file (symlink to ../../../file)
file (file containing "I am file")
lnk_bar (symlink to dir/foo/bar/)
Может быть создан в Windows следующим образом:
git init
mkdir -p dir/foo/bar/
echo "I am baz" > dir/foo/bar/baz
echo "I am file" > file
git add -A
git commit -m "Add files"
git add-symlink ../../../file dir/foo/bar/lnk_file
git add-symlink dir/foo/bar/ lnk_bar
git commit -m "Add symlinks"
-
Замена символических ссылок git на жесткие ссылки NTFS + переходы
git config --global alias.rm-symlink '!__git_rm_symlink(){
git checkout -- "$1"
link=$(echo "$1")
POS=$'\''/'\''
DOS=$'\''\\\\'\''
doslink=${link//$POS/$DOS}
dest=$(dirname "$link")/$(cat "$link")
dosdest=${dest//$POS/$DOS}
if [ -f "$dest" ]; then
rm -f "$link"
cmd //C mklink //H "$doslink" "$dosdest"
elif [ -d "$dest" ]; then
rm -f "$link"
cmd //C mklink //J "$doslink" "$dosdest"
else
echo "ERROR: Something went wrong when processing $1 . . ."
echo " $dest may not actually exist as a valid target."
fi
}; __git_rm_symlink "$1"'
git config --global alias.rm-symlinks '!__git_rm_symlinks(){
for symlink in $(git ls-files -s | egrep "^120000" | cut -f2); do
git rm-symlink "$symlink"
git update-index --assume-unchanged "$symlink"
done
}; __git_rm_symlinks'
Применение:
git rm-symlink dir/foo/bar/lnk_file
git rm-symlink lnk_bar
git update-index --assume-unchanged dir/foo/bar/lnk_file
git update-index --assume-unchanged lnk_bar
Это удаляет git-символические ссылки один за другим, заменяя их жесткими ссылками NTFS (в случае файлов) или соединениями NTFS (в случае каталогов). Преимущество использования ссылок hardlinks + над "истинными" символическими ссылками NTFS заключается в том, что для того, чтобы они могли быть созданы, не требуются повышенные права UAC. Наконец, на собственном отдыхе вы можете отключить -A s-модифицированные (или не) "удаленные" символические ссылки с помощью git update-index
.
Для удобства вы также можете запустить:
git rm-symlinks
Это удаляет ВСЕ ссылки git symlinks в текущем репозитории, заменяя их жесткими ссылками + переходы по мере необходимости и автоматически помещая изменения, которые следует игнорировать по git status
.
Чтобы удалить символические ссылки из подмодулей, просто используйте встроенную поддержку git для итерации по ним:
git submodule foreach --recursive git rm-symlinks
Но, для каждого такого радикального действия, как это, обратное приятно иметь...
-
Восстановление символических ссылок git в Windows
git config --global alias.checkout-symlinks '!__git_checkout_symlinks(){
POS=$'\''/'\''
DOS=$'\''\\\\'\''
for symlink in $(git ls-files -s | egrep "^120000" | cut -f2); do
git update-index --no-assume-unchanged "$symlink"
dossymlink=${symlink//$POS/$DOS}
cmd //C rmdir //Q "$dossymlink" 2>/dev/null
git checkout -- "$symlink"
echo "Restored git symlink $symlink <<===>> $(cat $symlink)"
done
}; __git_checkout_symlinks'
Использование: git checkout-symlinks
, который отменяет git rm-symlinks
, эффективно восстанавливая хранилище до его естественного состояния (за исключением ваших изменений, которые должны оставаться неизменными).
А для подмодулей:
git submodule foreach --recursive git checkout-symlinks
-
Ограничения:
- Может быть запущен только из корня репо, иначе произойдет странность...
- Автоматическое заполнение на основе табуляции нарушается при вводе одного из этих псевдонимов
-
Если люди забывают git checkout-symlinks
прежде чем делать что-то вроде git add -A
, они могут загрязнить репо!
Используя наш "пример репо" от:
echo "I am nuthafile" > dir/foo/bar/nuthafile
echo "Updating file" >> file
git add -A
git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: dir/foo/bar/nuthafile
# modified: file
# deleted: lnk_bar # POLLUTION
# new file: lnk_bar/baz # POLLUTION
# new file: lnk_bar/lnk_file # POLLUTION
# new file: lnk_bar/nuthafile # POLLUTION
#
Упс...
По этой причине приятно включить эти псевдонимы в качестве шагов для выполнения для пользователей Windows до того, как -A nd -A создаст проект, а не после проверки или до нажатия. Но каждая ситуация другая. Эти псевдонимы были достаточно полезны для меня, что настоящая post- проверка не требовалась.
Надеюсь, это поможет!
Рекомендации:
http://git-scm.com/book/en/Git-Internals-Git-Objects
http://technet.microsoft.com/en-us/library/cc753194
UPDATE 2014-11-12: потому что я лично только когда-либо очень активно использовал псевдонимы rm-symlinks
и checkout-symlinks
выше, мне удалось упустить довольно неприятную ошибку в псевдониме add-symlink
. Ранее -n
не получалось передаваться в echo
оператор, ответственный за создание файла ссылки git, который позже будет добавлен в промежуточную область как часть операции add-symlink
. Это означает, что конечная 0x0D 0x0A
(0x0D 0x0A
на хостах Windows) добавлялась ко всем символическим ссылкам git, созданным с помощью add-symlink
. Хотя эти символические ссылки git по-прежнему будут "удаляться" на хостах Windows с помощью rm-symlinks
просто отлично, если они когда-либо были преданы публичному репо и позже клонированы в подлинной системе на основе posix, эти ссылки всегда будут нарушены на другом боковая сторона. Эта проблема исправлена, и add-symlink
теперь должен работать так, как ожидалось.
Ответ 3
Самая последняя версия git scm (testet 2.11.1) позволяет включить символические ссылки. Но вы снова должны клонировать репозиторий с символическими ссылками git clone -c core.symlinks=true <URL>
. Вам нужно запустить эту команду с правами администратора. Также возможно создать символические ссылки на Windows с помощью mklink.
Проверьте wiki.
![enter image description here]()
Ответ 4
Он должен быть реализован в msysgit, но есть два недостатка:
- Символьные ссылки доступны только в Windows Vista и более поздних версиях (это не должно быть проблемой в 2011 году, и все же это...), поскольку более старые версии поддерживают только ссылки на каталоги.
- (большой) Microsoft рассматривает символические ссылки как угрозу безопасности, поэтому только администраторы могут создавать их по умолчанию. Вам нужно будет повысить привилегии процесса git или использовать fstool, чтобы изменить это поведение на каждом компьютере, на котором вы работаете.
Я сделал быстрый поиск, и там активная работа над этим, см. вопрос 224.
Ответ 5
Я бы предположил, что вы не используете символические ссылки в репо. Храните фактический контент внутри репо ', а затем разместите символические ссылки на стороне репо', указывающей на содержимое.
Итак, скажем, вы используете репо ', чтобы сравнить хостинг вашего сайта на * nix с хостингом на выигрыше. Сохраните содержимое в своем репо ', скажем /httpRepoContent
и c:\httpRepoContent
, поскольку это папка, которая синхронизируется через GIT, SVN и т.д.
Затем замените папку содержимого вашего веб-сервера (/var/www
и c:\program files\web server\www
{имена действительно не имеют значения, отредактируйте, если нужно}) с символической ссылкой на контент вашего репо. Веб-серверы будут видеть контент как на самом деле в "правильном" месте, но вы можете использовать свой источник управления.
Однако, если вам нужно использовать символические ссылки в репо ', вам нужно будет изучить нечто вроде скриптов pre/post commit. Я знаю, что вы можете использовать их, чтобы делать что-то, например, файлы кода синтаксического анализа через форматирование, например, чтобы было возможно преобразовать символические ссылки между платформами.
если кто-то знает хорошее место, чтобы узнать, как делать эти сценарии для общих элементов управления источником, SVN GIT MG, то добавьте комментарий.
Ответ 6
Для тех, кто использует CygWin в Vista, Win7 или выше, команда native git
может создавать "правильные" символические ссылки, которые распознаются приложениями Windows, такими как Android Studio. Вам просто нужно установить переменную среды CYGWIN
, чтобы включить winsymlinks:native
или winsymlinks:nativestrict
как таковой:
export CYGWIN="$CYGWIN winsymlinks:native"
Недостатком этого (и значительного в этом) является то, что оболочка CygWin должна быть "Запуск от имени администратора", чтобы иметь разрешения ОС, необходимые для создания подобных символических ссылок. Однако, если они созданы, для их использования не требуются специальные разрешения. До тех пор, пока они не будут изменены в репозитории другим разработчиком, git
после этого будет нормально работать с обычными правами пользователя.
Лично я использую это только для символических ссылок, которые перемещаются приложениями Windows (т.е. не CygWin) из-за этой дополнительной трудности.
Для получения дополнительной информации об этой опции см. этот вопрос SO: Как сделать символическую ссылку с cygwin в Windows 7
Ответ 7
Вот пакет script для преобразования символических ссылок в репозиторий, только для файлов, основанных на ответе Джоша Ли. script с дополнительной проверкой прав администратора на https://gist.github.com/Quazistax/8daf09080bf54b4c7641.
@echo off
pushd "%~dp0"
setlocal EnableDelayedExpansion
for /f "tokens=3,*" %%e in ('git ls-files -s ^| findstr /R /C:"^120000"') do (
call :processFirstLine %%f
)
REM pause
goto :eof
:processFirstLine
@echo.
@echo FILE: %1
dir "%~f1" | find "<SYMLINK>" >NUL && (
@echo FILE already is a symlink
goto :eof
)
for /f "usebackq tokens=*" %%l in ("%~f1") do (
@echo LINK TO: %%l
del "%~f1"
if not !ERRORLEVEL! == 0 (
@echo FAILED: del
goto :eof
)
setlocal
call :expandRelative linkto "%1" "%%l"
mklink "%~f1" "!linkto!"
endlocal
if not !ERRORLEVEL! == 0 (
@echo FAILED: mklink
@echo reverting deletion...
git checkout -- "%~f1"
goto :eof
)
git update-index --assume-unchanged "%1"
if not !ERRORLEVEL! == 0 (
@echo FAILED: git update-index --assume-unchanged
goto :eof
)
@echo SUCCESS
goto :eof
)
goto :eof
:: param1 = result variable
:: param2 = reference path from which relative will be resolved
:: param3 = relative path
:expandRelative
pushd .
cd "%~dp2"
set %1=%~f3
popd
goto :eof
Ответ 8
Короткий ответ: теперь они хорошо поддерживаются, если вы можете включить режим разработчика.
От https://blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/
Теперь в Windows 10 Creators Update пользователь (с правами администратора) может сначала включить режим разработчика, а затем любой пользователь на машине может запустить команду mklink без повышения командной строки.
Что привело к этому изменению? Доступность и использование символических ссылок - это большое дело для современных разработчиков:
Многие популярные инструменты разработки, такие как git и менеджеры пакетов, такие как npm, распознают и сохраняют символические ссылки при создании репозиториев или пакетов соответственно. Когда эти репозитории или пакеты затем восстанавливаются в другом месте, символические ссылки также восстанавливаются, обеспечивая свободное пространство на диске (и время пользователя).
Легко упускать из виду все другие анонсы "Творческого обновления", но если вы включите режим разработчика, вы можете создавать символические ссылки без повышенных привилегий. Возможно, вам придется переустановить и убедиться, что поддержка включена, так как она не по умолчанию.
![Symbolic Links aren't enabled by default]()
Ответ 9
Я искал легкое решение для решения символических ссылок unix на окнах. Большое спасибо за вышеупомянутые псевдонимы Git.
Существует одна небольшая оптимизация, которая может быть выполнена с помощью rm-symlinks, чтобы она не удаляла файлы в целевой папке в случае, если псевдоним запускается во второй раз случайно. Пожалуйста, соблюдайте новое условие if в цикле, чтобы убедиться, что файл еще не является ссылкой на каталог до запуска логики.
git config --global alias.rm-symlinks '!__git_rm_symlinks(){
for symlink in $(git ls-files -s | egrep "^120000" | cut -f2); do
*if [ -d "$symlink" ]; then
continue
fi*
git rm-symlink "$symlink"
git update-index --assume-unchanged "$symlink"
done
}; __git_rm_symlinksenter
Ответ 10
Я использую сим-ссылки все время между моим корнем документа и каталогом git repo. Мне нравится держать их в покое. В окнах я использую параметр mklink/j. Соединение, кажется, позволяет git вести себя нормально:
>mklink /j <location(path) of link> <source of link>
например:
>mklink /j c:\gitRepos\Posts C:\Bitnami\wamp\apache2\htdocs\Posts
Ответ 11
Один простой трюк, который мы используем, - просто называть git add --all
дважды подряд.
Например, наш скрипт фиксации Windows 7 вызывает:
$ git add --all
$ git add --all
Первое добавление рассматривает ссылку как текст и добавляет папки для удаления.
Второе добавляет правильную трассировку ссылки и отменяет удаление путем восстановления файлов.
Он менее изящный, чем некоторые другие предлагаемые решения, но это простое решение для некоторых из наших устаревших сред, которые добавили символические ссылки.
Ответ 12
так как все изменилось с GIT, поскольку многие из этих ответов были опубликованы здесь, являются правильными инструкциями по правильному отображению символических ссылок в окнах с
АВГУСТ 2018
1. Убедитесь, что git установлен с поддержкой symlink
![During the install of git on windows]()
2. Скажите Bash, чтобы создать жесткие ссылки вместо символических ссылок
EDIT - (папка git)/etc/bash.bashrc
ДОБАВИТЬ В НОМЕР - MSYS=winsymlinks:nativestrict
3. Установите git config для использования символических ссылок
git config core.symlinks true
или
git clone -c core.symlinks=true <URL>
ПРИМЕЧАНИЕ. Я попытался добавить это в глобальную конфигурацию git, и в настоящий момент он не работает для меня, поэтому я рекомендую добавить это к каждому репо...
4. Потяните репо
ПРИМЕЧАНИЕ. Если вы не включили режим разработчика в последней версии Windows 10, вам нужно запустить bash как администратор для создания символических ссылок
5. Сбросьте все Symlinks (необязательно). Если у вас есть существующее репо или вы используете подмодули, вы можете обнаружить, что символические ссылки создаются неправильно, поэтому для обновления всех символических ссылок в репо вы можете запускать эти команды.
find -type l -delete
git reset --hard
ПРИМЕЧАНИЕ. Это приведет к сбросу любых изменений с момента последнего фиксации, поэтому убедитесь, что вы совершили первый