Liên kết tượng trưng với một hook trong git


86

Tôi đã viết hook post-merge tùy chỉnh của riêng mình, bây giờ tôi đã thêm thư mục "hooks" vào thư mục dự án chính của mình (vì git không theo dõi các thay đổi trong .git / hooks), ở đâu đó tôi đọc được rằng tôi có thể tạo liên kết tượng trưng từ hook thành .git / hooks để tôi không phải sao chép tệp từ thư mục này sang thư mục khác mỗi khi ai đó thay đổi nó, vì vậy tôi đã thử:

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

Nhưng nó dường như không hoạt động, bất kỳ ý tưởng tại sao? "ln hooks / post-merge .git / hooks / post-merge" hoạt động tốt nhưng tạo liên kết cứng giống như copyin, tôi đoán vậy ...


22
Bởi vì liên kết biểu tượng được phân giải liên quan đến vị trí của nó. Một liên kết biểu tượng trong .git/hooks/đó trỏ đến để hooks/post-mergeđược giải quyết .git/hooks/hooks/post-merge, liên kết này không tồn tại. Bạn muốn ln -s -f ../../hooks/post-merge .git/hooks/post-merge. Hoặc làm cho cuộc sống của bạn dễ dàng hơn: ln -s -f ../hooks .git/hooks. Vấn đề của bạn không liên quan gì đến git.
Aristotle Pagaltzis

1
stackoverflow.com/questions/3462955/…stackoverflow.com/questions/427207/… (và stackoverflow.com/questions/3703159/… ) chỉ ra thực tế rằng liên kết biểu tượng có thể hoạt động.
VonC

Hãy sửa tôi nếu tôi sai, nhưng một Liên kết biểu tượng vẫn phải được thiết lập trên mỗi máy trạm. Điều duy nhất mà điều này tiết kiệm, là sao chép nó theo cách thủ công hoặc viết một lệnh khác sao chép tệp hook được theo dõi vào .git/hooks.
adi518

Câu trả lời:


161

bạn vừa sử dụng đường dẫn sai, nó phải là:

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

10
Tôi không hiểu tại sao tôi cần phải truy cập hai thư mục để liên kết một tài nguyên nằm trong thư mục mà tôi đã cdvào. Nó không nên được ln -s ./hooks/?
Droogans

45
Điều này. Khi git đang đánh giá liên kết biểu tượng, nó dường như làm như vậy bằng cách sử dụng .git/hookslàm thư mục làm việc của nó, vì vậy các đường dẫn tương đối phải tương đối với thư mục đó. Điều này sẽ dễ hiểu hơn nếu bạn lần đầu cdvào .git/hookstrước khi tạo liên kết biểu tượng và tìm ra đường dẫn tương đối từ đó.
Eliot

12
@Eliot không có việc tạo và phân giải các liên kết tượng trưng bị ảnh hưởng bởi thư mục làm việc. Bất cứ điều gì bạn cung cấp lnsẽ được lưu trữ dưới dạng mục tiêu và được giải quyết liên quan đến vị trí của liên kết.
Joó Ádám

2
@ JoóÁdám Bạn nói đúng. Vì vậy, vấn đề ở đây là lệnh gốc chỉ định một đường dẫn tương đối không chính xác. Tuy nhiên, việc cdnhập vào .git/hookstrước khi tạo liên kết sẽ giúp bạn viết lệnh, vì sau đó bạn có thể tự động điền vào đường dẫn chính xác.
Eliot

1
Tất cả điều này cuối cùng đã làm việc cho tôi. Sự khác biệt duy nhất là tôi đang liên kết với của riêng tôi prepare-commit-msg. Vấn đề là nếu tôi đang chỉnh sửa thông báo cam kết bằng nano, sau đó Ctl + X ra để hủy bỏ, git vẫn hoàn thành một cam kết thay vì hủy bỏ như trước khi tôi thực hiện thay đổi này. Có cách nào để thoát nano mà không khiến cam kết này hoàn thành không?
frakman1

15

Trong khi bạn có thể sử dụng các liên kết tượng trưng, ​​bạn cũng có thể thay đổi thư mục hooks cho dự án của mình trong cài đặt git của bạn bằng:

git config core.hooksPath hooks/

Cái này là cục bộ theo mặc định nên nó sẽ không làm hỏng git hooks cho các dự án khác của bạn. Nó hoạt động cho tất cả hook trong kho này, vì vậy nó đặc biệt hữu ích nếu bạn có nhiều hơn một hook.

Nếu bạn đã có hook tùy chỉnh .git/hooks/mà bạn không muốn chia sẻ với nhóm của mình, bạn có thể thêm chúng vào hook / và thêm dấu .gitignoređể chúng không bị chia sẻ.


Rất đẹp! Một thủ thuật hữu ích :) Có vẻ như tương lai tốt hơn nhiều so với việc liên kết từng cái một với sym.
jkp

2

Thay đổi thư mục trước khi liên kết

cd /path/to/project-repo/.git/hooks
ln -s -f ../../hooks/post-merge ./post-merge

Thậm chí đơn giản, sau khi cd:ln -s -f ../../hooks/post-merge
jamesdlin

0

Việc tính toán đường dẫn được thực hiện liên quan đến liên kết biểu tượng. Hãy hiểu bằng cách sử dụng một ví dụ,

ln -s path/to/file symlink/file

Ở đây, đường dẫn đến tệp thực sự phải là đường dẫn tương đối từ đường dẫn liên kết biểu tượng.
Hệ thống thực sự tính toán đường dẫn tệp vì symlink/path/path/to/file
Lệnh trên phải được viết lại thành

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

Cấu trúc thư mục,

/ code
------ liên kết biểu tượng / tệp
------ đường dẫn / đến / tệp


0

Sử dụng nhận xét của Michael Cihar, đây là một ví dụ về tập lệnh bash mà tôi đã viết để đơn giản tạo các liên kết tượng trưng này. Tập lệnh này nằm trong git_hooks / dir, ở gốc dự án. Thư mục .git / của tôi cũng ở cùng cấp thư mục.

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

Tập lệnh của tôi phải được chạy từ trong thư mục git_hooks / thực tế. Bạn có thể sửa đổi nó để hoạt động khác, nếu bạn muốn.

Tập lệnh này sẽ liên kết biểu tượng bất kỳ tệp nào không có đuôi tệp trong thư mục git_hooks /. Tôi có một README.txt trong thư mục này + tập lệnh này (có tên là symlink.sh). Tất cả các git hook thực sự được đặt tên là 'pre-commit', 'pre-push', v.v. vì vậy chúng sẽ được liên kết tượng trưng.


-1

tại sao không chỉ cp ./hooks/* .git / hooks /

điều này làm việc cho tôi trong Mac OS


15
Bởi vìI don't have to copy the file from one folder to the other every time someone changes
George Dimitriadis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.