Hãy ngay lập tức bắt đầu với một phế liệu của móc pre-receive
mà tôi đã viết:Git móc '-nhận tiền' và 'git-vang-format' kịch bản đáng tin cậy từ chối push vi phạm công ước mã phong cách
#!/bin/sh
##
format_bold='\033[1m'
format_red='\033[31m'
format_yellow='\033[33m'
format_normal='\033[0m'
##
format_error="${format_bold}${format_red}%s${format_normal}"
format_warning="${format_bold}${format_yellow}%s${format_normal}"
##
stdout() {
format="${1}"
shift
printf "${format}" "${@}"
}
##
stderr() {
stdout "${@}" 1>&2
}
##
output() {
format="${1}"
shift
stdout "${format}\n" "${@}"
}
##
error() {
format="${1}"
shift
stderr "${format_error}: ${format}\n" 'error' "${@}"
}
##
warning() {
format="${1}"
shift
stdout "${format_warning}: ${format}\n" 'warning' "${@}"
}
##
die() {
error "${@}"
exit 1
}
##
git() {
command git --no-pager "${@}"
}
##
list() {
git rev-list "${@}"
}
##
clang_format() {
git clang-format --style='file' "${@}"
}
##
while read sha1_old sha1_new ref; do
case "${ref}" in
refs/heads/*)
branch="$(expr "${ref}" : 'refs/heads/\(.*\)')"
if [ "$(expr "${sha1_new}" : '0*$')" -ne 0 ]; then # delete
unset sha1_new
# ...
else # update
if [ "$(expr "${sha1_old}" : '0*$')" -ne 0 ]; then # create
unset sha1_old
sha1_range="${sha1_new}"
else
sha1_range="${sha1_old}..${sha1_new}"
# ...
fi
fi
# ...
GIT_WORK_TREE="$(mktemp --tmpdir -d 'gitXXXXXX')"
export GIT_WORK_TREE
GIT_DIR="${GIT_WORK_TREE}/.git"
export GIT_DIR
mkdir -p "${GIT_DIR}"
cp -a * "${GIT_DIR}/"
ln -s "${PWD}/../.clang-format" "${GIT_WORK_TREE}/"
error=
for sha1 in $(list "${sha1_range}"); do
git checkout --force "${sha1}" > '/dev/null' 2>&1
if [ "$(list --count "${sha1}")" -eq 1 ]; then
# What should I put here?
else
git reset --soft 'HEAD~1' > '/dev/null' 2>&1
fi
diff="$(clang_format --diff)"
if [ "${diff%% *}" = 'diff' ]; then
error=1
error '%s: %s\n%s' \
'Code style issues detected' \
"${sha1}" \
"${diff}" \
1>&2
fi
done
if [ -n "${error}" ]; then
die '%s' 'Code style issues detected'
fi
fi
;;
refs/tags/*)
tag="$(expr "${ref}" : 'refs/tags/\(.*\)')"
# ...
;;
*)
# ...
;;
esac
done
exit 0
LƯU Ý:
Các địa điểm có mã không liên quan được trang bị # ...
.
LƯU Ý:
Nếu bạn không quen thuộc với git-clang-format
, hãy xem here.
Móc đó hoạt động như mong đợi, và cho đến nay, tôi không nhận thấy bất kỳ lỗi nào, nhưng nếu bạn phát hiện bất kỳ vấn đề nào hoặc có đề xuất cải tiến, tôi đánh giá cao bất kỳ báo cáo nào. Có lẽ, tôi nên đưa ra nhận xét về ý định đằng sau cái móc này là gì. Vâng, nó kiểm tra mọi sửa đổi để tuân thủ các quy ước kiểu mã bằng cách sử dụng git-clang-format
và nếu bất kỳ quy tắc nào không tuân thủ, nó sẽ tạo ra sự khác biệt có liên quan (bản phát hành nói cho nhà phát triển những gì nên được sửa) cho mỗi người trong số họ. Về cơ bản, tôi có hai câu hỏi chuyên sâu về móc này.
Trước tiên, lưu ý rằng tôi thực hiện sao chép kho lưu trữ trống (máy chủ) của từ xa vào một số thư mục tạm thời và kiểm tra mã để phân tích ở đó. Hãy để tôi giải thích về ý định này. Lưu ý rằng tôi thực hiện một số git checkout
s và git reset
s (do vòng lặp for
) để phân tích tất cả các bản sửa đổi được đẩy riêng lẻ với git-clang-format
. Những gì tôi đang cố gắng để tránh ở đây, là (có thể) vấn đề đồng thời về đẩy truy cập vào kho lưu trữ trần (máy chủ) của từ xa. Đó là, tôi đang bị ấn tượng rằng nếu nhiều nhà phát triển sẽ cố gắng đẩy cùng một lúc với điều khiển từ xa với móc cài đặt pre-receive
này, điều đó có thể gây ra sự cố nếu mỗi "phiên" này không thực hiện git checkout
s và git reset
s bản sao lưu trữ riêng của nó. Vì vậy, để đặt nó đơn giản, không git-daemon
có tích hợp khóa quản lý cho đồng thời đẩy "phiên"? Nó sẽ thực hiện các trường hợp móc pre-receive
tương ứng một cách chặt chẽ theo tuần tự hoặc có khả năng xen kẽ (có khả năng có thể gây ra hành vi không xác định)? Một cái gì đó nói với tôi rằng cần phải có một giải pháp tích hợp cho vấn đề này với sự đảm bảo cụ thể, nếu không làm thế nào điều khiển từ xa sẽ làm việc nói chung (thậm chí không có móc phức tạp) đang bị đẩy đồng thời? Nếu có một giải pháp tích hợp như vậy, thì bản sao là không cần thiết và chỉ đơn giản là sử dụng lại kho trống sẽ thực sự đẩy nhanh quá trình xử lý. Bằng cách này, bất kỳ tham chiếu đến tài liệu chính thức liên quan đến câu hỏi này là rất hoan nghênh.
Thứ hai, git-clang-format
chỉ xử lý được tổ chức (nhưng không cam kết) thay đổi so với cam kết cụ thể (HEAD
theo mặc định). Vì vậy, bạn có thể dễ dàng nhìn thấy nơi một trường hợp góc nằm. Có, đó là với cam kết gốc (bản sửa đổi). Thực tế, không thể áp dụng git reset --soft 'HEAD~1'
cho các cam kết gốc vì chúng không có cha mẹ để đặt lại. Do đó, việc kiểm tra sau đây với câu hỏi thứ hai của tôi là ở đó:
if [ "$(list --count "${sha1}")" -eq 1 ]; then
# What should I put here?
else
git reset --soft 'HEAD~1' > '/dev/null' 2>&1
fi
Tôi đã thử git update-ref -d 'HEAD'
nhưng điều này phá vỡ kho theo cách như vậy mà git-clang-format
là không thể xử lý nó nữa. Tôi tin rằng điều này có liên quan đến thực tế là tất cả các bản sửa đổi được đẩy đang được phân tích (bao gồm cả bản gốc này) không thực sự thuộc về bất kỳ chi nhánh nào. Tức là, họ đang ở trạng thái tách raHEAD
.Sẽ là hoàn hảo để tìm giải pháp cho trường hợp góc này, do đó, cam kết ban đầu cũng có thể trải qua cùng một kiểm tra bằng git-clang-format
để tuân thủ các quy ước kiểu mã.
Hòa bình.