Câu trả lời:
Tôi thường đồng ý với Scytale, với một vài gợi ý bổ sung, đủ để nó đáng để trả lời riêng.
Trước tiên, bạn nên viết một tập lệnh tạo ra các liên kết tượng trưng phù hợp, đặc biệt nếu các móc nối này là về thực thi chính sách hoặc tạo thông báo hữu ích. Mọi người sẽ có nhiều khả năng sử dụng móc hơn nếu họ chỉ có thể gõ bin/create-hook-symlinks
hơn là họ phải tự làm.
Thứ hai, móc liên kết trực tiếp ngăn người dùng thêm vào móc cá nhân của riêng họ. Ví dụ, tôi thích hook hook pre-commit mẫu hơn, đảm bảo rằng tôi không có bất kỳ lỗi khoảng trắng nào. Một cách tuyệt vời để giải quyết vấn đề này là thả tập lệnh trình bao móc trong repo của bạn và liên kết tượng trưng tất cả các hook với nó. Sau đó, trình bao bọc có thể kiểm tra $0
(giả sử đó là tập lệnh bash; tương tự như argv[0]
cách khác) để tìm ra hook nào được gọi là, sau đó gọi hook thích hợp trong repo của bạn, cũng như hook của người dùng thích hợp, sẽ phải đổi tên , truyền tất cả các đối số cho mỗi. Ví dụ nhanh từ bộ nhớ:
#!/bin/bash
if [ -x $0.local ]; then
$0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
tracked_hooks/$(basename $0) "$@" || exit $?
fi
Tập lệnh cài đặt sẽ di chuyển tất cả các hook có sẵn sang một bên (nối .local
vào tên của chúng) và symlink tất cả các tên hook đã biết đến tập lệnh trên:
#!/bin/bash
HOOK_NAMES="applypatch-msg pre-applypatch post-applypatch pre-commit prepare-commit-msg commit-msg post-commit pre-rebase post-checkout post-merge pre-receive update post-receive post-update pre-auto-gc"
# assuming the script is in a bin directory, one level into the repo
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
for hook in $HOOK_NAMES; do
# If the hook already exists, is executable, and is not a symlink
if [ ! -h $HOOK_DIR/$hook -a -x $HOOK_DIR/$hook ]; then
mv $HOOK_DIR/$hook $HOOK_DIR/$hook.local
fi
# create the symlink, overwriting the file if it exists
# probably the only way this would happen is if you're using an old version of git
# -- back when the sample hooks were not executable, instead of being named ____.sample
ln -s -f ../../bin/hooks-wrapper $HOOK_DIR/$hook
done
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
.
Không, đưa chúng vào kho lưu trữ là tốt, tôi thậm chí còn đề nghị làm như vậy (nếu chúng cũng hữu ích cho người khác). Người dùng phải kích hoạt chúng một cách rõ ràng (ví dụ như bạn đã nói, bằng cách liên kết tượng trưng), một mặt hơi đau, nhưng mặt khác bảo vệ người dùng khỏi chạy mã tùy ý mà không có sự đồng ý của họ.
Ngày nay, bạn có thể thực hiện các thao tác sau để đặt thư mục nằm dưới sự kiểm soát phiên bản thành thư mục git hook của bạn, ví dụ: MY_REPO_DIR/.githooks
sẽ là
git config --local core.hooksPath .githooks/
Vẫn không thể thực thi trực tiếp, nhưng, nếu bạn thêm một ghi chú trong README (hoặc bất cứ điều gì), điều này đòi hỏi tối thiểu nỗ lực cho mỗi phần của nhà phát triển.
Từ http://git-scm.com/docs/git-init#_template_directory , bạn có thể sử dụng một trong các cơ chế này để cập nhật thư mục .git / hook của mỗi repo git mới được tạo:
Thư mục mẫu chứa các tệp và thư mục sẽ được sao chép vào $ GIT_DIR sau khi được tạo.
Thư mục mẫu sẽ là một trong những thứ sau đây (theo thứ tự):
đối số được đưa ra với tùy chọn --template;
nội dung của biến môi trường $ GIT_TEMPLATE_DIR;
biến cấu hình init.templateDir; hoặc là
thư mục mẫu mặc định: / usr / share / git-core / samples.
Như những người khác nêu trong câu trả lời của họ, Nếu hook của bạn là cụ thể cho các dự án cụ thể của bạn thì hãy đưa chúng vào chính dự án, được quản lý bởi git. Tôi sẽ còn làm điều này hơn nữa và nói rằng, do thực tế tốt khi xây dựng dự án của bạn bằng cách sử dụng một tập lệnh hoặc lệnh, các hook của bạn sẽ được cài đặt trong quá trình xây dựng.
Tôi đã viết một bài viết về việc quản lý móc git , nếu bạn muốn đọc về điều này sâu hơn một chút.
Từ chối trách nhiệm đầy đủ; Tôi đã viết plugin Maven được mô tả dưới đây.
Nếu bạn đang xử lý quản lý xây dựng với Maven cho các dự án Java của mình, thì plugin Maven sau đây xử lý các cài đặt hook từ một vị trí trong dự án của bạn.
https://github.com/rudikershaw/git-build-hook
Đặt tất cả các móc Git của bạn vào một thư mục trong dự án của bạn, sau đó định cấu hình của bạn pom.xml
để bao gồm khai báo, mục tiêu và cấu hình plugin sau đây.
<build>
<plugins>
<plugin>
<groupId>com.rudikershaw.gitbuildhook</groupId>
<artifactId>git-build-hook-maven-plugin</artifactId>
<configuration>
<gitConfig>
<!-- The location of the directory you are using to store the Git hooks in your project. -->
<core.hooksPath>hooks-directory/</core.hooksPath>
</gitConfig>
</configuration>
<executions>
<execution>
<goals>
<!-- Sets git config specified under configuration > gitConfig. -->
<goal>configure</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... etc ... -->
</plugins>
</build>
Khi bạn chạy dự án xây dựng, plugin sẽ cấu hình git để chạy hook ra khỏi thư mục được chỉ định. Điều này sẽ thiết lập hiệu quả các hook trong thư mục đó cho mọi người làm việc trong dự án của bạn.
Đối với NPM, có một phụ thuộc được gọi là Husky , cho phép bạn cài đặt các hook bao gồm các hook được viết bằng JavaScript.
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
Ngoài ra, có các cam kết trước cho các dự án Python, Overcommit cho các dự án Ruby và Lefthook cho các dự án Ruby hoặc Node.
Gói https://www.npmjs.com/package/pre-commit npm xử lý việc này một cách tao nhã cho phép bạn chỉ định các móc nối trước trong gói.json của bạn.
Đối với các dự án PHP dựa trên Trình soạn thảo, bạn có thể tự động phân phối cho các kỹ sư. Dưới đây là một ví dụ cho các hook hook trước và commit-messenger.
Tạo một hooks
thư mục, sau đó trong composer.json của bạn:
},
"scripts": {
"post-install-cmd": [
"cp -r 'hooks/' '.git/hooks/'",
"php -r \"copy('hooks/pre-commit', '.git/hooks/pre-commit');\"",
"php -r \"copy('hooks/commit-msg', '.git/hooks/commit-msg');\"",
"php -r \"chmod('.git/hooks/pre-commit', 0777);\"",
"php -r \"chmod('.git/hooks/commit-msg', 0777);\"",
],
Sau đó, bạn thậm chí có thể cập nhật chúng khi dự án tiếp tục vì mọi người đang chạy composer install
một cách thường xuyên.
Đây là một tập lệnh, add-git-hook.sh, mà bạn có thể gửi như một tệp thông thường trong kho lưu trữ và có thể được thực thi để nối hook git vào tệp tập lệnh. Điều chỉnh móc nào sẽ sử dụng (pre-commit, post-commit, pre-push, v.v.) và định nghĩa của hook trong heredoc cat.
#!/usr/bin/bash
# Adds the git-hook described below. Appends to the hook file
# if it already exists or creates the file if it does not.
# Note: CWD must be inside target repository
HOOK_DIR=$(git rev-parse --show-toplevel)/.git/hooks
HOOK_FILE="$HOOK_DIR"/post-commit
# Create script file if doesn't exist
if [ ! -e "$HOOK_FILE" ] ; then
echo '#!/usr/bin/bash' >> "$HOOK_FILE"
chmod 700 "$HOOK_FILE"
fi
# Append hook code into script
cat >> "$HOOK_FILE" <<EOF
########################################
# ... post-commit hook script here ... #
########################################
EOF
Kịch bản này có thể có ý nghĩa để có quyền thực thi hoặc người dùng có thể chạy nó trực tiếp. Tôi đã sử dụng điều này để tự động git-pull trên các máy khác sau khi tôi cam kết.
EDIT-- Tôi đã trả lời câu hỏi dễ hơn không phải là những gì được hỏi và không phải là những gì OP đang tìm kiếm. Tôi đã phản đối các trường hợp sử dụng và các đối số để vận chuyển các tập lệnh hook trong repo so với việc quản lý chúng bên ngoài trong các bình luận bên dưới. Hy vọng đó là nhiều hơn những gì bạn đang tìm kiếm.
Bạn có thể sử dụng giải pháp được quản lý để quản lý hook pre-commit như pre-commit . Hoặc một giải pháp tập trung cho git-hook phía máy chủ như Datree.io . Nó có các chính sách tích hợp như:
Nó sẽ không thay thế tất cả các hook của bạn, nhưng nó có thể giúp các nhà phát triển của bạn có những hook rõ ràng nhất mà không cần cấu hình cài đặt hook trên mọi máy tính / repo của nhà phát triển.
Tuyên bố miễn trừ trách nhiệm: Tôi là một trong những người sáng lập Datrees
chmod +x .git/hooks/*
vào của bạnbin/create-hook-symlinks
để làm việc đó.