Символьні посилання Git у Windows


246

Наші розробники використовують суміш ОС Windows та ОС на базі Unix. Тому символічні посилання, створені на машинах Unix, стають проблемою для розробників Windows. У Windows (msysgit) симпосилання перетворюється на текстовий файл із шляхом до файлу, на який він вказує. Натомість я хотів би перетворити симпосилання в фактичне символьне посилання Windows.

У мене ( оновлене ) рішення до цього є:

  • Напишіть сценарій після оформлення замовлення, який буде рекурсивно шукати текстові файли "symlink".
  • Замініть їх на вікно symlink (використовуючи mklink) з такою ж назвою та розширенням, як фіктивний "symlink"
  • Ігноруйте ці вікна посилання, додавши запис у .git / info / виключити

Я цього не реалізував, але вважаю, що це міцний підхід до цієї проблеми.

Запитання:

  1. Які недоліки ви бачите у цьому підході?
  2. Чи реалізований цей сценарій після оформлення замовлення? тобто чи можу я рекурсивно дізнатися, що створюється фіктивний файл "symlink", який створює git?
  3. Хтось уже працював над таким сценарієм?

3
Хоча Git підтримує посилання, я настійно рекомендую не зберігати їх як посилання у вашому сховищі, особливо якщо ви також працюєте з цим кодом у Windows.
Грег Хьюгілл

2
@Greg Hewgill - я повністю згоден з тобою. На жаль, природа нашої бази коду вимагає символьних посилань ... тому їх видалення не є можливим.
Кен Хіракава

12
Ви також можете запитати у списку розсилки msysgit, чому вони не реалізували його так у першу чергу.
drizzd

8
@GregHewgill чому б і ні? Windows підтримує як символічні посилання, так і переходи - це справді здається відсутнім функцією у Windows версіях Git для мене ...
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
helo ken Ви б не хотіли поділитися своїм сценарієм, який перевіряє текстові файли для символьного посилання та замінює їх символьними посиланнями на Windows за допомогою mklink. в той час як це насправді працює для нас - частина, що не змінюється, не відповідає. при переході до іншої гілки git каже, що файли symlink змінені і їх потрібно скористати спочатку, тоді як статус git говорить, що змін немає. багато ідеї?
Жорег

6
Ось PowerShell, який я щойно зібрав, - gist.github.com/ferventcoder/7995025
ferventcoder

3
@flungo Існує більш портативний спосіб друкувати четвертий стовпець, ніж використання GNU awk. Наприклад: git ls-files -s | grep '^12' | cut -f2(другий стовпчик з обмеженими вкладками; інші стовпці
відкладені

1
Один лайнер для Cygwin / bash для позначення всіх посилань без змін:for f in `git ls-files -s | awk '/120000/{print $4}'`; do git update-index --assume-unchanged $f; done
DaveAlden

187

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

  1. Насправді є кілька недоліків запропонованого рішення, головним чином щодо збільшення потенціалу забруднення сховищ або випадкового додавання дублікатів файлів, коли вони знаходяться в стані «симпосилання Windows». (Детальніше про це під "обмеженнями" нижче.)
  2. Так, сценарій після оформлення замовлення реалізований! Можливо, не як буквальний післяшаговий git checkoutкрок, але рішення, наведене нижче, досить добре задовольнило мої потреби, що буквальний сценарій після оформлення замовлення не був необхідним.
  3. Так!

Рішення:

Наші розробники знаходяться в майже такій самій ситуації, як і у ОП: суміш хостів, схожих на 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дзвінків, звичайно) - не більше башизмів !
  • Підтримуються каталоги та файли з пробілами в них.
  • Нульові та ненульові коди статусу виходу (для повідомлення про успіх / невдачу запитуваної команди відповідно) тепер належним чином зберігаються / повертаються.
  • 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. Перевірте вікі .

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


1
Це не спрацювало для мене. Я перевстановив git для Windows, не забудьте встановити прапорець symlink та знову клонувати мій проект. Мояtslint.json файл, що посилається на файл у батьківському каталозі, все ще містить ../tslint.json. Шкода, адже це справді виглядало як найлегше з усіх запропонованих там рішень.
Ян Агаард

8
@JanAagaard Ви повинні його клонувати так: git clone -c core.symlinks=true <URL> А в Windows ви повинні запустити його з правами адміністратора.
серлунчалот

6
@ARF "Запустіть gpedit.msc (тобто редактор групової політики) та додайте облікові записи до конфігурації комп'ютера \ Налаштування Windows \ Налаштування безпеки \ Локальні політики \ Призначення прав користувача \ Створення символічних посилань."
sirlunchalot

2
@sirlunchalot Дякуємо за допомогу. З того часу я зрозумів, що моя проблема полягає в тому, що мій користувач входить до групи адміністраторів і що ця властивість не впливає на цих користувачів. Вони вимагають підвищення рівня UAC, чого не спрацьовує git.
ARF

9
Права адміністратора не потрібні в "Режимі розробника" в Windows 10 Creators Update. Дякуємо @dennis у своєму коментарі .
Домінік

16

Він повинен бути реалізований у msysgit, але є два мінуси:

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

Я здійснив швидкий пошук, і над цим активно виконується робота, див. Випуск 224 .


2
Оновлення: з вищезазначених причин проблему було закрито як wontfix. Обговорення вказує на те, що виправлення можна було б прийняти за допомогою ще однієї роботи над патчем (скажімо, за допомогою символьних посилань, лише якщо вони працюють).
Blaisorblade

2
А.) Наразі msysgit взагалі не підтримує символьні посилання - так чому б йому не виявити "ой ти на Vista з NTFS, дозволь мені використовувати символьні посилання" або "о, ти в ОС, яка підтримує з'єднання з NTFS, дозвольте мені скористатися цими ", або" о, ви на Windows 98 / fat32, дозвольте мені просто не мати цієї функції, і натомість вам попередити! " а потім Б.) Досить багато розробників Microsoft. інструменти не працюють належним чином (принаймні, не для всіх їх функцій), якщо ви не запускаєте їх як адміністратор - усі в ІТ знають, що розробникам потрібно бути адміністратором у власних скриньках.
BrainSlugs83

1
Хоча я запускаю певні машини в обліковому записі адміністратора, я не дотримуюся цієї філософії на моїй розробці. Я завжди працюю як звичайний користувач із підтримкою UAC. Я тримаю окрему консоль відкритою для операцій, які вимагають підвищених привілеїв. Що стосується здійснення цього, то хтось (як ви) добровільно зводиться до цього. Розробники msysgit не відомі благодійністю ...
djs

@djs Користувач повинен відкрити командний рядок з "Запустити як адміністратор". Він майже буквально працює як Адміністратор, який повністю змінює середовище. Немає способу запустити 'mklink / d' як Користувач, який також є у групі Адміністратора. Це не підкаже UAC. Це завжди вийде з ладу. Це працює лише двома способами: буквально як користувач адміністратора (RunAs Verb) або користувач, який не адміністратор, із зміною групової політики. З'єднання повинні бути типовими і їх слід розпізнавати усіма інструментами. "Ризик безпеки" полягає в тому, що посилання на Windows можуть "перенаправляти" акції SMB. Це біль і жорстокий.
Ендрю Т Фіннелл

8
Оголошено в грудні 2016 року. Посилання на Windows у Windows 10 вже не є діями адміністратора. blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/…
Dennis

16

так що з GIT все змінилося, оскільки тут було розміщено багато цих відповідей - це правильні вказівки щодо правильної роботи символьних посилань у Windows.

Серпня 2018 року


1. Переконайтесь, що git встановлений із підтримкою symlink

Під час встановлення git на 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. Скидання всіх посилань (необов’язково) Якщо у вас є репо-репортаж або ви використовуєте підмодулі, ви можете виявити, що символьні посилання створюються неправильно, тому для оновлення всіх посилань у репо можна запустити ці команди.

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 і переконатися, що підтримка symlink увімкнена, оскільки це не за замовчуванням.

Символічні посилання за умовчанням не увімкнено


1
gpedit.msc-> Local Computer Policy-> Computer Configuration-> Windows Settings-> Security Settings-> Local Policies-> User Rights Assignmentє канонічним способом привласнення прав користувачів на зразок SeCreateSymbolicLinkта друзів протягом століть. За винятком ntrights.exeресурсного набору або 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 з хостингом на виграш. Зберігайте вміст у вашому репортажі, давайте скажемо /httpRepoContentтаc:\httpRepoContent це папка, яка синхронізується через GIT, SVN тощо.

Потім замініть папку вмісту вашого веб-сервера ( /var/wwwіc:\program files\web server\www {імена насправді не мають значення, відредагуйте, якщо потрібно}) символічним посиланням на вміст вашого репо '. Веб-сервери побачать вміст насправді у "правильному" місці, але ви користуєтесь своїм джерелом управління.

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

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


Зрештою, я обрав такий підхід, щоб створити папку виходу з символьної посилання та створити символьні посилання на те, де раніше був оригінальний файл. Інший підхід не працював навіть після того, як я змінив .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) через цю додаткову складність.

Для отримання додаткової інформації про цей параметр, дивіться це питання ТА: Як встановити символічне посилання з 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

Недокументована відповідь насправді не дуже корисна, коли вже є такі тривалі та багатослівні відповіді.
Xennex81

4

Я весь час використовую посилання sym між моїм коренем документа та каталогом git repo. Мені подобається тримати їх окремо. У Windows я використовую опцію mklink / j. З'єднання, здається, дозволяє git поводитися нормально:

>mklink /j <location(path) of link> <source of link>

наприклад:

>mklink /j c:\gitRepos\Posts C:\Bitnami\wamp\apache2\htdocs\Posts


2
Будьте дуже обережні з провідником Windows і розв'язками; це не диференціює з'єднання від базового місця розташування, а видалення повторюється в ціль та видаляє його вміст, тоді як видалення символьної посилання просто видалить посилання. Просто пастка для необережних.
Лоуренс Дол

5
Насправді, лише тестували це на останньому Windows7, і це вже не робиться, тому обробка вузлів вдосконалена десь за останні кілька років.
Лоуренс Дол

3

Я шукав просте рішення для вирішення символічних посилань Unix на Windows. Дуже дякую за вищенаведені псевдоніми Git. Існує одна невелика оптимізація, яку можна зробити для rm-символьних посилань, щоб вона не видаляла файли в папці призначення у випадку, якщо псевдонім запускається вдруге випадково. Будь ласка, дотримуйтесь нового, якщо умова в циклі, щоб переконатися, що файл не є посиланням на каталог до запуску логіки.

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 

2

Один простий трюк, який ми використовуємо, - це просто дзвонити git add --allдвічі поспіль.

Наприклад, наші виклики сценарію Windows 7 здійснюють:

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

Перше додавання розглядає посилання як текст і додає папки для видалення.

Друге додавання правильно переходить посилання та скасовує видалення шляхом відновлення файлів.

Це менш елегантно, ніж деякі інші запропоновані рішення, але це просте виправлення деяких наших застарілих середовищ, які додали символьні посилання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.