มันถือว่าเป็นแนวปฏิบัติที่ไม่ดีหรือไม่ - ใส่.git/hooks
ลงในที่เก็บโครงการ (ใช้ symlink เป็นต้น) ถ้าใช่เป็นวิธีที่ดีที่สุดในการส่ง hooks แบบเดียวกันกับผู้ใช้ git ที่แตกต่างกันคืออะไร
มันถือว่าเป็นแนวปฏิบัติที่ไม่ดีหรือไม่ - ใส่.git/hooks
ลงในที่เก็บโครงการ (ใช้ symlink เป็นต้น) ถ้าใช่เป็นวิธีที่ดีที่สุดในการส่ง hooks แบบเดียวกันกับผู้ใช้ git ที่แตกต่างกันคืออะไร
คำตอบ:
โดยทั่วไปฉันเห็นด้วยกับ Scytale พร้อมคำแนะนำเพิ่มเติมสองสามคำว่าคุ้มค่ากับคำตอบที่แยกต่างหาก
ขั้นแรกคุณควรเขียนสคริปต์ที่สร้าง symlink ที่เหมาะสมโดยเฉพาะหาก hooks เหล่านี้เกี่ยวกับการบังคับใช้นโยบายหรือการสร้างการแจ้งเตือนที่มีประโยชน์ ผู้คนจะมีแนวโน้มที่จะใช้ hooks หากพวกเขาสามารถพิมพ์ได้bin/create-hook-symlinks
มากกว่าที่พวกเขาต้องทำเอง
ประการที่สองการเชื่อมโยง hooks โดยตรงป้องกันผู้ใช้จากการเพิ่ม hooks ส่วนตัวของพวกเขาเอง ตัวอย่างเช่นฉันชอบ hook pre-commit ตัวอย่างซึ่งทำให้แน่ใจว่าฉันไม่มีข้อผิดพลาดในช่องว่าง วิธีที่ยอดเยี่ยมในการทำเช่นนี้ก็คือการวางสคริปต์ของฮุกเกอร์ใน repo ของคุณและเชื่อมโยงhooks ทั้งหมดเข้ากับมัน wrapper สามารถตรวจสอบ$0
(สมมติว่ามันเป็นสคริปต์ทุบตี; เทียบเท่าเหมือนargv[0]
อย่างอื่น) ที่จะคิดว่าเบ็ดมันถูกเรียกว่าเป็นแล้วเรียกเบ็ดที่เหมาะสมภายใน repo ของคุณเช่นเดียวกับเบ็ดของผู้ใช้ที่เหมาะสมซึ่งจะต้องเปลี่ยนชื่อ ผ่านการขัดแย้งทั้งหมดไปยังแต่ละ ตัวอย่างด่วนจากหน่วยความจำ:
#!/bin/bash
if [ -x $0.local ]; then
$0.local "$@" || exit $?
fi
if [ -x tracked_hooks/$(basename $0) ]; then
tracked_hooks/$(basename $0) "$@" || exit $?
fi
สคริปต์การติดตั้งจะย้าย hooks ที่มีอยู่ล่วงหน้าทั้งหมดไปที่ด้านข้าง (ต่อท้าย.local
ชื่อ) และเชื่อมโยงชื่อ hook ที่รู้จักทั้งหมดไปยังสคริปต์ด้านบน:
#!/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
วิธีที่ดีกว่าที่จะได้รับผบเบ็ดคือ
ไม่การวางลงในพื้นที่เก็บข้อมูลเป็นเรื่องปกติฉันขอแนะนำให้ทำเช่นนั้น (หากมีประโยชน์สำหรับผู้อื่นเช่นกัน) ผู้ใช้ต้องเปิดใช้งานอย่างชัดเจน (ดังที่คุณพูดเช่นโดยการเชื่อมโยง) ซึ่งอยู่ในมือข้างหนึ่งของความเจ็บปวดเล็กน้อย แต่ปกป้องผู้ใช้ในอีกทางหนึ่งจากการใช้รหัสโดยพลการโดยไม่ได้รับความยินยอม
ทุกวันนี้คุณสามารถทำสิ่งต่อไปนี้เพื่อตั้งค่าไดเรกทอรีที่อยู่ภายใต้การควบคุมเวอร์ชันให้เป็นไดเรกทอรี git hooks ของคุณเช่นMY_REPO_DIR/.githooks
จะเป็น
git config --local core.hooksPath .githooks/
ยังไม่สามารถบังคับใช้ได้โดยตรง แต่ถ้าคุณเพิ่มบันทึกย่อใน README ของคุณ (หรืออะไรก็ตาม) สิ่งนี้ต้องการความพยายามขั้นต่ำในส่วนของนักพัฒนาแต่ละคน
จากhttp://git-scm.com/docs/git-init#_template_directoryคุณสามารถใช้หนึ่งในกลไกเหล่านี้เพื่ออัปเดต. git / hooks dir ของ repo git แต่ละรายการที่สร้างขึ้นใหม่:
ไดเรกทอรีแม่แบบมีไฟล์และไดเรกทอรีที่จะถูกคัดลอกไปยัง $ GIT_DIR หลังจากสร้างแล้ว
ไดเรกทอรีเทมเพลตจะเป็นหนึ่งในสิ่งต่อไปนี้ (เรียงตามลำดับ):
อาร์กิวเมนต์ที่กำหนดด้วยตัวเลือก - เทมเพลท;
เนื้อหาของตัวแปรสภาพแวดล้อม $ GIT_TEMPLATE_DIR
ตัวแปรการกำหนดค่า init.templateDir หรือ
ไดเรกทอรีแม่แบบเริ่มต้น: / usr / share / git-core / templates
ตามที่คนอื่น ๆ ระบุไว้ในคำตอบหากตะขอของคุณมีความเฉพาะเจาะจงสำหรับโครงการเฉพาะของคุณให้รวมพวกเขาไว้ในโครงการด้วยตัวเองจัดการโดย git ฉันจะใช้สิ่งนี้ให้ดียิ่งขึ้นและบอกว่าเนื่องจากเป็นแนวปฏิบัติที่ดีในการสร้างโปรเจ็กต์ของคุณโดยใช้สคริปต์หรือคำสั่งเดียวตะขอของคุณควรถูกติดตั้งระหว่างการ build
ฉันเขียนบทความเกี่ยวกับการจัดการ hooks gitหากคุณสนใจที่จะอ่านเกี่ยวกับเรื่องนี้ในเชิงลึกมากขึ้น
ข้อจำกัดความรับผิดชอบฉบับเต็ม; ฉันเขียนปลั๊กอิน Maven ตามที่อธิบายไว้ด้านล่าง
หากคุณจัดการการจัดการการสร้างด้วย Maven สำหรับโครงการ Java ของคุณปลั๊กอิน Maven ต่อไปนี้จะจัดการติดตั้ง hooks จากตำแหน่งในโครงการของคุณ
https://github.com/rudikershaw/git-build-hook
ใส่ตะขอ Git ของคุณทั้งหมดลงในไดเรกทอรีในโครงการของคุณจากนั้นกำหนดค่าpom.xml
ให้รวมการประกาศปลั๊กอินเป้าหมายและการกำหนดค่าต่อไปนี้
<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>
เมื่อคุณเรียกใช้งานบิลด์โปรเจ็กต์ของคุณปลั๊กอินจะกำหนดค่า git เพื่อให้ hooks ออกจากไดเรกทอรีที่ระบุ นี่จะเป็นการตั้งค่า hooks ในไดเรกทอรีนั้นอย่างมีประสิทธิภาพสำหรับทุกคนที่ทำงานในโครงการของคุณ
สำหรับ NPM มีการขึ้นต่อกันเรียกว่าฮัสกี้ซึ่งอนุญาตให้คุณติดตั้ง hooks รวมถึงที่เขียนใน JavaScript
// package.json
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
นอกจากนี้ยังมีการคอมมิตล่วงหน้าสำหรับโครงการ Python, Overcommitสำหรับโครงการ Ruby และLefthookสำหรับโครงการRuby หรือ Node
https://www.npmjs.com/package/pre-commit NPM จับแพคเกจนี้อย่างสวยงามช่วยให้คุณสามารถระบุก่อนกระทำตะขอใน package.json ของคุณ
นี่คือสคริปต์ add-git-hook.sh ซึ่งคุณสามารถจัดส่งเป็นไฟล์ปกติในที่เก็บและสามารถดำเนินการต่อท้าย git hook ไปยังไฟล์สคริปต์ได้ ปรับ hook ที่จะใช้ (pre-commit, post-commit, pre-push, ฯลฯ ) และคำจำกัดความของ hook ใน cat heredoc
#!/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
สคริปต์นี้อาจเหมาะสมที่จะมีสิทธิ์ใช้งานหรือผู้ใช้สามารถเรียกใช้โดยตรง ฉันใช้สิ่งนี้เพื่อดึงคอมไพล์บนเครื่องอื่นโดยอัตโนมัติหลังจากที่ฉันยืนยัน
แก้ไข - ฉันตอบคำถามง่ายขึ้นซึ่งไม่ใช่สิ่งที่ถูกถามและไม่ใช่สิ่งที่ OP กำลังมองหา ฉันเลือกใช้กรณีและข้อโต้แย้งสำหรับการจัดส่งสคริปต์เบ็ดใน repo กับการจัดการพวกเขาภายนอกในความคิดเห็นด้านล่าง หวังว่าจะเป็นสิ่งที่คุณกำลังมองหา
สำหรับโปรเจ็กต์ PHP ที่ใช้ Composer คุณสามารถแจกจ่ายให้กับวิศวกรโดยอัตโนมัติ นี่คือตัวอย่างสำหรับ hooks การผูกมัดล่วงหน้าและ commit-msg
สร้างhooks
โฟลเดอร์จากนั้นใน composer.json ของคุณ:
},
"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);\"",
],
จากนั้นคุณสามารถอัปเดตพวกเขาขณะที่โครงการดำเนินต่อไปเนื่องจากทุกคนทำงานcomposer install
เป็นประจำ
คุณสามารถใช้วิธีการแก้ปัญหาการจัดการก่อนกระทำการจัดการเบ็ดเหมือนก่อนกระทำ หรือวิธีการแก้ปัญหาที่ส่วนกลางในฝั่งเซิร์ฟเวอร์คอมไพล์ตะขอเช่นDatree.io มันมีนโยบายในตัวเช่น:
มันจะไม่แทนที่ hooks ทั้งหมดของคุณ แต่อาจช่วยให้นักพัฒนาของคุณเห็นได้ชัดเจนที่สุดโดยไม่ต้องมีการกำหนดค่าให้ติดตั้ง hooks ลงในคอมพิวเตอร์ / นักพัฒนาทุกคน
ข้อจำกัดความรับผิดชอบ: ฉันเป็นหนึ่งในผู้ก่อตั้ง Datrees
chmod +x .git/hooks/*
ให้คุณbin/create-hook-symlinks
ทำงาน