Git Symlinks в Windows

246

Наши разработчики используют сочетание ОС Windows и Unix. Поэтому символические ссылки, созданные на машинах Unix, становятся проблемой для разработчиков Windows. В windows (msysgit) символическая ссылка преобразуется в текстовый файл с путем к файлу, на который он указывает. Вместо этого я хотел бы преобразовать символическую ссылку в фактическую символическую ссылку Windows.

( Обновленное ) решение, которое я должен это:

  • Напишите сценарий после оформления заказа, который будет рекурсивно искать текстовые файлы «symlink».
  • Замените их символической ссылкой Windows (используя mklink) с тем же именем и расширением, что и у фиктивной "символической ссылки"
  • Не обращайте внимания на эти символические ссылки Windows, добавив запись в .git / info / exclude

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

Вопросы:

  1. Какие, если таковые имеются, недостатки вы видите в этом подходе?
  2. Является ли этот сценарий после оформления заказа даже осуществимым? то есть я могу рекурсивно выяснить фиктивные "символические" файлы, которые создает git?
  3. Кто-нибудь уже работал над таким сценарием?
Кен Хиракава
источник
3
Хотя Git поддерживает символические ссылки, я настоятельно рекомендую не хранить их в качестве ссылок в вашем хранилище, особенно если вы также работаете с этим кодом в Windows.
Грег Хьюгилл
2
@ Грег Хьюгилл - я полностью с тобой согласен. К сожалению, природа нашей кодовой базы требует символических ссылок ... поэтому их удаление не вариант для нас.
Кен Хиракава
12
Вы также можете спросить в списке рассылки msysgit, почему они не реализовали его таким образом.
drizzd
8
@GregHewgill почему бы и нет? Windows поддерживает и символические ссылки, и переходы - это действительно кажется отсутствующей функцией в версиях Git для Windows ...
BrainSlugs83
6
При включенном «Режиме разработчика» в Windows 10 создание символических ссылок не требует прав администратора! (Другие так же прокомментировали ответы с меньшим количеством голосов, но я их не видел. Надеюсь, этот комментарий более заметен для будущих читателей.)
Дейв Паскуа,

Ответы:

105

Вы можете найти символические ссылки, ища файлы в режиме 120000, возможно, с помощью этой команды:

git ls-files -s | awk '/120000/{print $4}'

После того, как вы замените ссылки, я бы рекомендовал пометить их как неизмененные git update-index --assume-unchanged, а не перечислять их в .git/info/exclude.

Джош Ли
источник
2
Мне пришлось заменить awk на gawk для msysgit, но в остальном он работал отлично. Спасибо!
Кен Хиракава
6
привет кен. Не могли бы вы поделиться своим сценарием, который проверяет текстовые файлы символических ссылок и заменяет их символическими ссылками на окнах с помощью mklink. в то время как это на самом деле работает для нас, --assume-неизмененная часть не работает. при переключении на другую ветку git говорит, что файлы символических ссылок изменены, и их нужно сначала зафиксировать, а git status говорит, что никаких изменений нет.
Йорег
6
Вот PowerShell, который я только что собрал - gist.github.com/ferventcoder/7995025
ferventcoder
3
@flungo Есть более переносимые способы печати четвертого столбца, чем использование GNU awk. Например: git ls-files -s | grep '^12' | cut -f2(второй столбец с разделителями табуляции; другие столбцы разделены пробелом)
Zenexer
1
Один вкладыш для Cygwin / bash, чтобы пометить все символические for f in `git ls-files -s | awk '/120000/{print $4}'`; do git update-index --assume-unchanged $f; done
ссылки
187

Некоторое время назад я задавал этот же вопрос (не здесь, просто в целом), и в итоге я нашел решение, очень похожее на предложение ОП. Сначала я предоставлю прямые ответы на вопросы 1, 2 и 3, а затем опубликую решение, которое я в итоге использовал.

  1. У предлагаемого решения действительно есть несколько недостатков, в основном в отношении увеличения вероятности загрязнения хранилища или случайного добавления дубликатов файлов, когда они находятся в состоянии «символьная ссылка Windows». (Подробнее об этом в разделе «Ограничения» ниже.)
  2. Да, скрипт после оформления заказа реализуем! Может быть, не как буквальный git checkoutшаг, но решение, приведенное ниже, удовлетворит мои потребности достаточно хорошо, чтобы буквальный сценарий после оформления заказа не был необходим.
  3. Да!

Решение:

Наши разработчики находятся практически в той же ситуации, что и OP: смесь Windows и Unix-подобных хостов, репозиториев и субмодулей со многими символическими ссылками git и никакой собственной (пока) поддержки в версии MsysGit для интеллектуальной обработки этих символических ссылок на хостах Windows ,

Спасибо Джошу Ли за то, что он указал на тот факт, что git передает символические ссылки в специальном файловом режиме 120000. С помощью этой информации можно добавить несколько псевдонимов git, которые позволяют создавать и обрабатывать символические ссылки git на хостах Windows.

  1. Создание символических ссылок git в Windows

    git config --global alias.add-symlink '!'"$(cat <<'ETX'
    __git_add_symlink() {
      if [ $# -ne 2 ] || [ "$1" = "-h" ]; then
        printf '%b\n' \
            'usage: git add-symlink <source_file_or_dir> <target_symlink>\n' \
            'Create a symlink in a git repository on a Windows host.\n' \
            'Note: source MUST be a path relative to the location of target'
        [ "$1" = "-h" ] && return 0 || return 2
      fi
    
      source_file_or_dir=${1#./}
      source_file_or_dir=${source_file_or_dir%/}
    
      target_symlink=${2#./}
      target_symlink=${target_symlink%/}
      target_symlink="${GIT_PREFIX}${target_symlink}"
      target_symlink=${target_symlink%/.}
      : "${target_symlink:=.}"
    
      if [ -d "$target_symlink" ]; then
        target_symlink="${target_symlink%/}/${source_file_or_dir##*/}"
      fi
    
      case "$target_symlink" in
        (*/*) target_dir=${target_symlink%/*} ;;
        (*) target_dir=$GIT_PREFIX ;;
      esac
    
      target_dir=$(cd "$target_dir" && pwd)
    
      if [ ! -e "${target_dir}/${source_file_or_dir}" ]; then
        printf 'error: git-add-symlink: %s: No such file or directory\n' \
            "${target_dir}/${source_file_or_dir}" >&2
        printf '(Source MUST be a path relative to the location of target!)\n' >&2
        return 2
      fi
    
      git update-index --add --cacheinfo 120000 \
          "$(printf '%s' "$source_file_or_dir" | git hash-object -w --stdin)" \
          "${target_symlink}" \
        && git checkout -- "$target_symlink" \
        && printf '%s -> %s\n' "${target_symlink#$GIT_PREFIX}" "$source_file_or_dir" \
        || return $?
    }
    __git_add_symlink
    ETX
    )"
    

    Использование:, git add-symlink <source_file_or_dir> <target_symlink>где аргумент, соответствующий исходному файлу или каталогу, должен принимать форму пути относительно целевой символической ссылки. Вы можете использовать этот псевдоним так же, как обычноln .

    Например, дерево хранилища:

    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"
    
  2. Замена символьных ссылок git на жесткие ссылки NTFS + соединения

    git config --global alias.rm-symlinks '!'"$(cat <<'ETX'
    __git_rm_symlinks() {
      case "$1" in (-h)
        printf 'usage: git rm-symlinks [symlink] [symlink] [...]\n'
        return 0
      esac
      ppid=$$
      case $# in
        (0) git ls-files -s | grep -E '^120000' | cut -f2 ;;
        (*) printf '%s\n' "$@" ;;
      esac | while IFS= read -r symlink; do
        case "$symlink" in
          (*/*) symdir=${symlink%/*} ;;
          (*) symdir=. ;;
        esac
    
        git checkout -- "$symlink"
        src="${symdir}/$(cat "$symlink")"
    
        posix_to_dos_sed='s_^/\([A-Za-z]\)_\1:_;s_/_\\\\_g'
        doslnk=$(printf '%s\n' "$symlink" | sed "$posix_to_dos_sed")
        dossrc=$(printf '%s\n' "$src" | sed "$posix_to_dos_sed")
    
        if [ -f "$src" ]; then
          rm -f "$symlink"
          cmd //C mklink //H "$doslnk" "$dossrc"
        elif [ -d "$src" ]; then
          rm -f "$symlink"
          cmd //C mklink //J "$doslnk" "$dossrc"
        else
          printf 'error: git-rm-symlink: Not a valid source\n' >&2
          printf '%s =/=> %s  (%s =/=> %s)...\n' \
              "$symlink" "$src" "$doslnk" "$dossrc" >&2
          false
        fi || printf 'ESC[%d]: %d\n' "$ppid" "$?"
    
        git update-index --assume-unchanged "$symlink"
      done | awk '
        BEGIN { status_code = 0 }
        /^ESC\['"$ppid"'\]: / { status_code = $2 ; next }
        { print }
        END { exit status_code }
      '
    }
    __git_rm_symlinks
    ETX
    )"
    
    git config --global alias.rm-symlink '!git rm-symlinks'  # for back-compat.
    

    Использование:

    git rm-symlinks [symlink] [symlink] [...]
    

    Этот псевдоним может удалить символические ссылки git по одному или сразу за один раз. Симлинки будут заменены на жесткие ссылки NTFS (в случае файлов) или соединения NTFS (в случае каталогов). Преимущество использования жестких ссылок + переходов над «настоящими» символьными ссылками NTFS состоит в том, что для их создания не требуются повышенные разрешения UAC.

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

    git submodule foreach --recursive git rm-symlinks
    

    Но для каждого такого радикального действия приятно иметь разворот ...

  3. Восстановление символьных ссылок git в Windows

    git config --global alias.checkout-symlinks '!'"$(cat <<'ETX'
    __git_checkout_symlinks() {
      case "$1" in (-h)
        printf 'usage: git checkout-symlinks [symlink] [symlink] [...]\n'
        return 0
      esac
      case $# in
        (0) git ls-files -s | grep -E '^120000' | cut -f2 ;;
        (*) printf '%s\n' "$@" ;;
      esac | while IFS= read -r symlink; do
        git update-index --no-assume-unchanged "$symlink"
        rmdir "$symlink" >/dev/null 2>&1
        git checkout -- "$symlink"
        printf 'Restored git symlink: %s -> %s\n' "$symlink" "$(cat "$symlink")"
      done
    }
    __git_checkout_symlinks
    ETX
    )"
    
    git config --global alias.co-symlinks '!git checkout-symlinks'
    

    Использование:, git checkout-symlinks [symlink] [symlink] [...]которое отменяет git rm-symlinks, эффективно восстанавливая хранилище в его естественное состояние (за исключением ваших изменений, которые должны остаться нетронутыми).

    И для подмодулей:

    git submodule foreach --recursive git checkout-symlinks
    
  4. Ограничения:

    • Каталоги / файлы / символические ссылки с пробелами в пути должны работать. Но вкладки или новые строки? YMMV… (Под этим я подразумеваю: не делайте этого, потому что это не будет работать.)

    • Если вы или другие забыли 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 до и после создания проекта, а не после проверки или перед отправкой. Но каждая ситуация отличается. Эти псевдонимы были достаточно полезны для меня, так что настоящее решение после проверки не было необходимости.

Надеюсь, это поможет!

Ссылки:

http://git-scm.com/book/en/Git-Internals-Git-Objects

http://technet.microsoft.com/en-us/library/cc753194

Последнее обновление: 2019-03-13

  • Соответствие POSIX (ну, кроме тех mklinkзвонков, конечно) - больше никаких Bashisms !
  • Каталоги и файлы с пробелами в них поддерживаются.
  • Нулевой и ненулевой коды состояния выхода (для сообщения об успешном / неудачном выполнении запрошенной команды соответственно) теперь должным образом сохраняются / возвращаются.
  • add-symlinkПсевдоним теперь работает больше как LN (1) и может быть использован из любого каталога в хранилище, а не только репозиторий корневого каталога.
  • rm-symlinkПсевдоним ( в единственном числе) был заменен на rm-symlinksпсевдониме (множественное число), которая в настоящее время принимает несколько аргументов (или без аргументов вообще, который находит все симлинка на протяжении всего хранилища, как и прежде) для избирательного превращения GIT символических ссылок на NTFS жестких ссылок + переходы ,
  • checkout-symlinksПсевдоним также был обновлен , чтобы принять несколько аргументов (или вообще никакого, == все) для селективного обращения вышеуказанных преобразований.

Последнее замечание: хотя я тестировал загрузку и запуск этих псевдонимов с использованием Bash 3.2 (и даже 3.1) для тех, кто по-прежнему может зависнуть в таких древних версиях по ряду причин, имейте в виду, что такие старые версии, как эти, печально известны своим парсером ошибок. Если у вас возникли проблемы при попытке установить любой из этих псевдонимов, первое, на что вы должны обратить внимание - это обновить вашу оболочку (для Bash проверьте версию с помощью CTRL + X, CTRL + V). В качестве альтернативы, если вы пытаетесь установить их, вставив их в эмулятор терминала, вам может повезти, вставив их в файл и используя его вместо этого, например, как

. ./git-win-symlinks.sh

Удачи!

Марк Г.
источник
не могли бы вы взглянуть на это здесь? stackoverflow.com/questions/21403772/…
Гуфи
это отличный и замечательный скрипт, но есть ли какая-то причина, по которой он должен произвольно добавлять слово «git» в конце некоторых моих файлов, которые я создаю с помощью git add-symlink?
Питер Тернер
Кроме того, если имя вашего файла содержит «-h», вы получаете использование. Еще очень полезный скрипт!
Питер Тернер
Ваш git add-symlinkрецепт был фантастически ценным для меня. Большое спасибо.
Дэн Ленски
1
Есть ли способ автоматически выполнить эти сценарии с помощью хуков?
ARF
74

Последняя версия git scm (testet 2.11.1) позволяет включать символические ссылки. Но вы должны снова клонировать хранилище с символическими ссылками git clone -c core.symlinks=true <URL>. Вам нужно запустить эту команду с правами администратора. Также можно создавать символические ссылки в Windows с помощью mklink. Проверьте вики .

введите описание изображения здесь

sirlunchalot
источник
1
Это не сработало для меня. Я переустановил git для Windows, не забудьте установить флажок символической ссылки и снова клонировать мой проект. Мой tslint.jsonфайл, ссылающийся на файл в родительском каталоге, все еще содержит ../tslint.json. Жаль, потому что это действительно выглядело как самое простое из всех предложенных решений.
Ян Огард
8
@JanAagaard Вы должны клонировать это так: git clone -c core.symlinks=true <URL> А в Windows вы должны запустить его с правами администратора.
sirlunchalot
6
@ARF "Запустите gpedit.msc (т. Е. Редактор групповой политики) и добавьте учетные записи в конфигурацию компьютера \ Конфигурация Windows \ Параметры безопасности \ Локальные политики \ Назначение прав пользователя \ Создать символические ссылки."
sirlunchalot
2
@sirlunchalot Спасибо за помощь. С тех пор я понял, что моя проблема в том, что мой пользователь входит в группу администраторов и что это свойство не влияет на этих пользователей. Они требуют повышения UAC, которое не делает git.
АРФ
9
Права администратора не требуются в «Режиме разработчика» в Windows 10 Creators Update. Спасибо @dennis в своем комментарии .
Доминик
16

Это должно быть реализовано в msysgit, но есть два недостатка:

  • Символьные ссылки доступны только в Windows Vista и более поздних версиях (не должно быть проблемой в 2011 году, и все же это ...), поскольку более старые версии поддерживают только соединения каталогов.
  • (большой) Microsoft считает символические ссылки угрозой безопасности, поэтому только администраторы могут создавать их по умолчанию. Вам нужно будет повысить привилегии процесса git или использовать fstool для изменения этого поведения на каждой машине, на которой вы работаете.

Я сделал быстрый поиск, и сейчас активно ведется работа, см. Выпуск 224 .

диджеев
источник
2
Обновление: по вышеуказанным причинам проблема была закрыта как wontfix. Обсуждение показывает, что исправление может быть принято после некоторой работы над патчем (скажем, с использованием символических ссылок, только если они работают).
Blaisorblade
2
A.) в настоящее время msysgit вообще не поддерживает символические ссылки - так почему бы не сделать так, чтобы он обнаруживал: «о, у вас перспективы с NTFS, позвольте мне использовать символические ссылки» или «о, вы работаете в ОС, которая поддерживает соединения с NTFS, позвольте мне использовать те ", или" о, вы на Windows 98 / FAT32, позвольте мне вернуться к тому, чтобы просто не иметь эту функцию и вместо этого дать вам предупреждение! " а затем Б.) Почти все разработчики Microsoft. инструменты не работают должным образом (по крайней мере, не для всех их функций), если вы не запускаете их как администратор - все в ИТ знают, что разработчики должны быть администраторами в своих собственных блоках.
BrainSlugs83
1
Хотя я запускаю определенные машины в учетной записи администратора, я не придерживаюсь этой философии на своей машине разработки. Я всегда работаю как обычный пользователь с включенным UAC. Я держу отдельную консоль открытой для операций, которые требуют повышенных привилегий. Что касается реализации этого, то все зависит от того, кто (как и вы) добровольно его реализует. Разработчики msysgit не известны благотворительностью ...
djs
@djs Пользователь должен открыть командную строку с «Запуск от имени администратора». Он почти буквально работает как пользователь-администратор, который полностью меняет среду. Невозможно запустить mklink / d от имени пользователя, который также входит в группу администраторов. UAC не подскажет. Это не удастся, всегда. Работает только два способа: буквально как пользователь-администратор (глагол RunAs) или пользователь без прав администратора с изменением групповой политики. Соединения должны быть по умолчанию и должны распознаваться всеми инструментами. «Риск безопасности» заключается в том, что символические ссылки в Windows могут «перенаправлять» SMB-ресурсы. Это боль и жестокость.
Эндрю Т Финнелл
8
Объявленные в декабре 2016 года символические ссылки в Windows 10 больше не являются действиями администратора. blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/…
Деннис
16

так как с GIT все изменилось, так как многие из этих ответов были опубликованы здесь, это правильные инструкции для правильной работы символических ссылок в Windows с

Август 2018


1. Убедитесь, что git установлен с поддержкой символических ссылок.

Во время установки git на windows

2. Скажите Bash создать жесткие ссылки вместо символических ссылок.

РЕДАКТИРОВАТЬ - (папка git) /etc/bash.bashrc

ДОБАВИТЬ В ДНО - MSYS=winsymlinks:nativestrict

3. Установите git config для использования символических ссылок

git config core.symlinks true

или

git clone -c core.symlinks=true <URL>

ПРИМЕЧАНИЕ: я попытался добавить это в глобальный git config, и в данный момент он не работает для меня, поэтому я рекомендую добавлять это в каждый репозиторий ...

4. вытащить репо

ПРИМЕЧАНИЕ. Если вы не включили режим разработчика в последней версии Windows 10, вам необходимо запустить bash от имени администратора для создания символических ссылок.

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

find -type l -delete
git reset --hard

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

Саймон
источник
15

Краткий ответ: теперь они хорошо поддерживаются, если вы можете включить режим разработчика.

С https://blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/

Теперь в Windows 10 Creators Update пользователь (с правами администратора) может сначала включить режим разработчика, а затем любой пользователь на машине может выполнить команду mklink, не поднимая консоль командной строки.

Что привело это изменение? Доступность и использование символических ссылок очень важны для современных разработчиков:

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

Легко пропустить все остальные объявления об «обновлении Создателя», но если вы включите режим разработчика, вы сможете создавать символические ссылки без повышенных привилегий. Возможно, вам придется переустановить git и убедиться, что поддержка символических ссылок включена, так как это не по умолчанию.

Символические ссылки не включены по умолчанию

Orangutech
источник
1
gpedit.msc-> Local Computer Policy-> Computer Configuration-> Windows Settings-> Security Settings-> Local Policies-> User Rights Assignmentбыл каноническим способом назначать права пользователей, таких как SeCreateSymbolicLinkи друзья, целую вечность. Кроме как ntrights.exeиз Resource Kit или PowerShell ...
0xC0000022L
11

2020 Ответ

  1. Включить «Режим разработчика» в Windows 10 - дает mklinkразрешения
  2. Убедитесь, что символические ссылки включены в git
    • git config --global core.symlinks true
    • или установите флажок при установке msysgit

Переключение веток заставит воссоздать недостающие символические ссылки.

Будьте осторожны, поддержка Symlinks в Windows с некоторыми другими клиентами Git не завершена. Особенно GitKraken.

Кэмерон Таклинд
источник
Все мои локальные репозитории имеют core.symlinks = false, что переопределит ваше решение. Любая идея, что производит эту локальную конфигурацию автоматически? Возможно, установка Git для Windows без установки флажка?
gravidThoughts
@gravidThoughts, какие git-клиенты установлены? Может быть, некоторые инструменты делают это? Это правда на свежем клоне?
Кэмерон Таклинд
10

Я бы посоветовал вам не использовать символические ссылки в репо ». Сохраните фактический контент внутри репо, а затем разместите символические ссылки вне репо, которые указывают на контент.

Допустим, вы используете репо для сравнения хостинга вашего сайта на * nix с хостингом на win. Храните контент в своем репо », скажем, /httpRepoContentи c:\httpRepoContentэто папка, которая синхронизируется через GIT, SVN и т. Д.

Затем замените папку содержимого вашего веб-сервера ( /var/wwwи c:\program files\web server\www{имена не имеют большого значения, отредактируйте, если необходимо}) символической ссылкой на содержимое вашего репозитория '. Веб-серверы будут видеть контент как на самом деле в «правильном» месте, но вы можете использовать свой источник контроля.

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

если кто-то знает хорошее место, чтобы научиться делать эти сценарии для общих элементов управления исходным кодом, SVN GIT MG, тогда, пожалуйста, добавьте комментарий.

thecoshman
источник
В конце концов, я выбрал этот подход, чтобы создать папку с символическими ссылками и создать символические ссылки на то место, где был оригинальный файл. Другой подход не сработал даже после того, как я изменил настройку .git / config core.symlinks = true. В хранилище был сохранен только файл символической ссылки, а не данные. Также были проблемы с отметками времени папок по символической ссылке, поэтому git bash никогда не видел, когда в папке изменялся файл.
Яйца
@ Яйца то, что вы могли видеть, я думаю, это то, что ссылка была внутри репо, и поэтому git сохранил ее, просто. Проблема, однако, в том, что цель находилась вне репо, а git не переходит по ссылке на данные цели. В Linux у вас есть тип ссылки, которая подходит для этого, в основном, у вас есть два пути к одним и тем же данным, хранящимся на диске; Я чувствую, что новые окна могут сделать это сейчас. В любом случае, я все еще не думаю, что это будет делать то, что хотят люди.
Thecoshman
@thecoshman Это не решение, а обходной путь. Однако иногда это не вариант. У меня есть репозиторий с git-annex, и все его архитектура работает из-за символических ссылок.
marcelo.guedes
8

Для тех, кто использует CygWin в Vista, Win7 или выше, встроенная gitкоманда может создавать «правильные» символические ссылки, которые распознаются приложениями Windows, такими как Android Studio . Вам просто нужно установить CYGWINпеременную окружения для включения winsymlinks:nativeили winsymlinks:nativestrictкак таковую:

export CYGWIN="$CYGWIN winsymlinks:native"

Недостатком этого (и существенного при этом) является то, что оболочка CygWin должна быть «Запуск от имени администратора», чтобы иметь разрешения ОС, необходимые для создания таких символических ссылок. Однако после их создания никаких специальных разрешений для их использования . Пока они не изменены в хранилище другим разработчиком, gitпосле этого он работает нормально с обычными разрешениями пользователя.

Лично я этим пользуюсь только для символических ссылок, которые перемещаются приложениями Windows (т.е. не CygWin) из-за этой дополнительной трудности.

Для получения дополнительной информации об этой опции см. Этот вопрос SO: Как сделать символическую связь с Cygwin в Windows 7

Брайан Уайт
источник
6

Вот пакетный скрипт для преобразования символических ссылок в репозитории, только для файлов, основанный на ответе Джоша Ли. Сценарий с дополнительной проверкой прав администратора находится по адресу 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
Quazistax
источник
Недокументированный ответ действительно не очень полезен, когда уже есть такие длинные и подробные ответы.
Xennex81
4

Я все время использую ссылки sym между моим корневым каталогом и каталогом 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

mmv_sat
источник
2
Будьте очень осторожны с Windows Explorer и соединениями; он не дифференцирует соединения от базового местоположения, и удаление будет возвращаться в цель и удалять ее содержимое, тогда как удаление символической ссылки просто удалит символическую ссылку. Просто ловушка для неосторожных.
Лоуренс Дол
5
На самом деле, только что проверил это на последней из Windows7, и он больше не делает, так что обработка переходов была улучшена когда-то за последние несколько лет.
Лоуренс Дол
3

Я искал простое решение для работы с символическими ссылками Unix на окнах. Большое спасибо за вышеупомянутые псевдонимы Git. Существует одна небольшая оптимизация, которую можно выполнить с rm-символическими ссылками, чтобы она не удаляла файлы в папке назначения в случае, если псевдоним запускается во второй раз случайно. Пожалуйста, соблюдайте новое условие 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 
prgrminglover
источник
2

Один простой трюк, который мы используем, - это просто звонить git add --allдважды подряд.

Например, наши вызовы сценария фиксации для Windows 7:

$ git add --all
$ git add --all

Первое добавление обрабатывает ссылку как текст и добавляет папки для удаления.

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

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

Майк Панофф
источник