Tautan simbolis ke sebuah hook di git

86

Saya membuat hook pasca-penggabungan kustom saya sendiri, sekarang saya menambahkan direktori "hooks" ke folder proyek utama saya (karena git tidak melacak perubahan dalam .git / hooks), di suatu tempat saya membaca bahwa saya dapat membuat link simbolis dari hooks ke .git / hooks jadi saya tidak perlu menyalin file dari satu folder ke folder lain setiap kali seseorang mengubahnya jadi saya mencoba:

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

Tapi sepertinya tidak berhasil, ada ide mengapa? "ln hooks / post-merge .git / hooks / post-merge" berfungsi dengan baik tetapi membuat hard link sama dengan copyin saya kira ....

Mateusz Dymczyk
sumber
22
Karena symlink diselesaikan relatif terhadap lokasinya. Sebuah symlink di .git/hooks/poin itu untuk hooks/post-mergediselesaikan .git/hooks/hooks/post-merge, yang tidak ada. Kamu mau ln -s -f ../../hooks/post-merge .git/hooks/post-merge. Atau membuat hidup Anda lebih mudah: ln -s -f ../hooks .git/hooks. Masalah Anda tidak ada hubungannya dengan git.
Aristoteles Pagaltzis
Koreksi saya jika saya salah, tetapi Symlink masih harus diatur per workstation. Satu-satunya hal yang disimpan ini, adalah menyalinnya secara manual atau menulis perintah lain yang menyalin file hook yang dilacak ke dalamnya .git/hooks.
adi518

Jawaban:

161

Anda baru saja menggunakan jalan yang salah, seharusnya:

ln -s -f ../../hooks/post-merge .git/hooks/post-merge
Michal Čihař
sumber
10
Saya tidak mengerti mengapa saya perlu membuka dua direktori untuk menautkan sumber daya yang ada di folder tempat saya berada cd. Bukankah seharusnya begitu ln -s ./hooks/?
Droogans
45
Ini. Saat git mengevaluasi symlink, tampaknya ia melakukannya dengan menggunakan .git/hooksdirektori kerjanya, jadi jalur relatif harus relatif terhadap direktori itu. Ini lebih jelas jika Anda terlebih dahulu cdmasuk .git/hookssebelum membuat symlink, dan mencari tahu jalur relatif dari sana.
Eliot
12
@Eliot baik pembuatan maupun resolusi symlink dipengaruhi oleh direktori kerja. Apa pun yang Anda berikan lnakan disimpan sebagai target dan diselesaikan relatif terhadap lokasi tautan.
Joó Ádám
2
@ JoóÁÁá Anda benar. Jadi masalahnya di sini adalah bahwa perintah asli menentukan jalur relatif yang salah. Namun, cdmasuk ke .git/hookssebelum Anda membuat tautan akan membantu Anda menulis perintah, karena Anda kemudian dapat melengkapi otomatis ke jalur yang benar.
Eliot
1
Semua ini berhasil untuk saya pada akhirnya. Satu-satunya perbedaan adalah saya menautkan ke milik saya sendiri prepare-commit-msg. Masalahnya adalah jika saya mengedit pesan komit menggunakan nano, lalu Ctl + X keluar untuk membatalkan, git tetap menyelesaikan komit alih-alih membatalkan seperti dulu sebelum saya membuat perubahan ini. Adakah cara agar nano keluar tanpa menyebabkan komit ini selesai?
frakman1
15

Meskipun Anda dapat menggunakan tautan simbolik, Anda juga dapat mengubah folder kait untuk proyek Anda di pengaturan git dengan:

git config core.hooksPath hooks/

Yang bersifat lokal secara default sehingga tidak akan merusak git hooks untuk proyek Anda yang lain. Ini berfungsi untuk semua hook di repositori ini, jadi ini sangat berguna jika Anda memiliki lebih dari satu hook.

Jika Anda sudah memiliki pengait khusus .git/hooks/yang tidak ingin Anda bagikan dengan tim Anda, Anda dapat menambahkannya di pengait / dan menambahkannya .gitignoreagar tidak dibagikan.

Pierre.Sassoulas
sumber
Sangat bagus! Trik praktis :) Tampaknya jauh lebih tahan masa depan daripada menghubungkannya dengan sym satu per satu.
jkp
2

Mengubah direktori sebelum menautkan

cd /path/to/project-repo/.git/hooks
ln -s -f ../../hooks/post-merge ./post-merge
Jekis
sumber
Lebih sederhana lagi, setelah cd:ln -s -f ../../hooks/post-merge
jamesdlin
0

Perhitungan jalur dilakukan relatif terhadap symlink. Mari kita pahami menggunakan contoh,

ln -s path/to/file symlink/file

Di sini, jalur ke file seharusnya merupakan jalur relatif dari jalur symlink.
Sistem sebenarnya menghitung jalur file sebagai symlink/path/path/to/file
Perintah di atas harus ditulis ulang sebagai

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

Struktur folder,

/ kode
------ symlink / file
------ jalur / ke / file

swayamraina
sumber
0

Memanfaatkan komentar Michael Cihar, berikut adalah contoh script bash yang saya tulis untuk membuat symlink tersebut. Skrip ini terletak di git_hooks / dir yang ada di root proyek. Folder .git / saya juga berada di tingkat direktori yang sama.

#!/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

Skrip saya harus dijalankan dari dalam direktori git_hooks / sebenarnya. Anda dapat memodifikasinya agar berperilaku berbeda, jika Anda mau.

Skrip ini akan menghubungkan file apa pun yang tidak memiliki ekstensi file dalam direktori git_hooks /. Saya memiliki README.txt di direktori ini + skrip ini (bernama symlink.sh). Semua git hook yang sebenarnya diberi nama 'pre-commit', 'pre-push', dll. Sehingga mereka akan terhubung dengan symlink.

cchoe1.dll
sumber
-2

mengapa tidak hanya cp ./hooks/* .git / hooks /

ini berhasil untuk saya di Mac OS

Frazko
sumber
15
KarenaI don't have to copy the file from one folder to the other every time someone changes
George Dimitriadis