Символическая ссылка на хук в git

86

Я написал свой собственный хук после слияния, теперь я добавил каталог "хуков" в мою основную папку проекта (поскольку git не отслеживает изменения в .git / hooks), где-то я читал, что могу сделать символическую ссылку из хуков в .git / hooks, поэтому мне не нужно копировать файл из одной папки в другую каждый раз, когда кто-то его изменяет, поэтому я попробовал:

ln -s -f hooks/post-merge .git/hooks/post-merge

Но, похоже, это не работает, есть идеи, почему? "ln hooks / post-merge .git / hooks / post-merge" работает нормально, но создание жесткой ссылки - то же самое, что и копирование, я думаю ....

Матеуш Дымчик
источник
22
Потому что символическая ссылка разрешена относительно своего местоположения. Символьная ссылка .git/hooks/, указывающая на, hooks/post-mergeразрешается на .git/hooks/hooks/post-merge, которого не существует. Вы хотите ln -s -f ../../hooks/post-merge .git/hooks/post-merge. Или сделать вашу жизнь проще: ln -s -f ../hooks .git/hooks. Ваша проблема не имеет ничего общего с git.
Аристотель Пагальцис
1
stackoverflow.com/questions/3462955/… и stackoverflow.com/questions/427207/…stackoverflow.com/questions/3703159/… ) указывают на то, что символическая ссылка может работать.
VonC
Поправьте меня, если я ошибаюсь, но Symlink все равно нужно настроить для каждой рабочей станции. Единственное, что это спасает, - это копирование вручную или написание другой команды, которая копирует файл отслеживаемой ловушки .git/hooks.
adi518

Ответы:

161

вы просто использовали неправильный путь, он должен быть:

ln -s -f ../../hooks/post-merge .git/hooks/post-merge
Михал Чихарж
источник
10
Я не понимаю, почему мне нужно подняться на два каталога, чтобы связать ресурс, который находится в папке, в которую я cdпопал. Разве это не должно быть просто так ln -s ./hooks/?
Droogans 04
45
Этот. Когда git оценивает символическую ссылку, он, по-видимому, делает это, используя в .git/hooksкачестве своего рабочего каталога, поэтому относительные пути должны быть относительно этого каталога. Это больше самопонятны если вы первый cdв .git/hooksпрежде чем сделать символическую ссылку, и фигура из относительного пути оттуда.
Элиот
12
@Eliot рабочий каталог не влияет ни на создание, ни на разрешение символических ссылок. Все, что вы дадите, lnбудет сохранено как цель и разрешено относительно местоположения ссылки.
Joó Ádám
2
@ JoóÁdám Ты прав. Итак, проблема в том, что исходная команда указывает неверный относительный путь. Тем не менее, если вы cdвойдете в систему .git/hooksперед тем, как создать ссылку, это поможет вам написать команду, так как затем вы можете автозаполнить правильный путь.
Элиот
1
В конце концов, все это у меня сработало. Единственная разница в том, что я ссылаюсь на свою prepare-commit-msg. Проблема в том, что если я редактирую сообщение фиксации с помощью nano, затем Ctrl + X выходит для прерывания, git все равно завершает фиксацию вместо прерывания, как это было до того, как я сделал это изменение. Есть ли способ выполнить нано-выход без завершения этого коммита?
frakman1
15

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

git config core.hooksPath hooks/

Который по умолчанию является локальным, поэтому он не повредит git-хуки для других ваших проектов. Он работает для всех хуков в этом репозитории, поэтому особенно полезен, если у вас более одного хука.

Если у вас уже есть настраиваемые хуки, .git/hooks/которыми вы не хотите делиться со своей командой, вы можете добавить их в хуки / и добавить, .gitignoreчтобы они не использовались.

Пьер Сассулас
источник
Очень хорошо! Удобный трюк :) Кажется, гораздо более перспективным, чем символьное связывание их по очереди.
jkp 06
2

Смена каталога перед связыванием

cd /path/to/project-repo/.git/hooks
ln -s -f ../../hooks/post-merge ./post-merge
Джекис
источник
Еще проще, после cd:ln -s -f ../../hooks/post-merge
jamesdlin
0

Расчет пути выполняется относительно символической ссылки. Давайте разберемся на примере,

ln -s path/to/file symlink/file

Здесь путь к файлу должен быть относительным путем от пути символической ссылки.
Система фактически вычисляет путь к файлу, так как symlink/path/path/to/file
Вышеупомянутая команда должна быть переписана как

ln -s ../path/to/file symlink/path

Структура папок,

/ код
------ символическая ссылка / файл
------ путь / к / файлу

Swayamraina
источник
0

Используя комментарий Майкла Цихара, вот пример сценария bash, который я написал для простого создания этих символических ссылок. Этот скрипт находится в git_hooks / dir, который находится в корне проекта. Моя папка .git / также находится на том же уровне каталога.

#!/usr/bin/env bash

pwd=$(pwd);

# Script is designed to be ran from git_hooks/ dir
if [[ "$pwd" == *"git_hooks"* ]]; then

  files=$(ls | grep -v -e '.*\.');

   while read -r file; do

     ln -s ../../git_hooks/$file ../.git/hooks/
     echo "Linked $file -> ../.git/hooks/$file"

   done <<< "$files";

else

  echo "";
  echo "ERROR: ";
  echo "You must be within the git_hooks/ dir to run this command";
  exit 1;

fi

Мой сценарий должен запускаться из фактического каталога git_hooks /. Вы можете изменить его поведение, если хотите.

Этот скрипт создаст символическую ссылку на любой файл, который не имеет суффикса с расширением файла в каталоге git_hooks /. У меня есть README.txt в этом каталоге + этот скрипт (с именем symlink.sh). Все фактические хуки git называются pre-commit, pre-push и т. Д., Поэтому они будут иметь символические ссылки.

cchoe1
источник
-1

почему бы просто не cp ./hooks/* .git / hooks /

это сработало для меня в Mac OS

Frazko
источник
15
Так как I don't have to copy the file from one folder to the other every time someone changes
Джордж Димитриадис