สคริปต์ Git hook สามารถจัดการพร้อมกับที่เก็บได้หรือไม่?


337

เราต้องการสร้างสคริปต์เบ็ดพื้นฐานบางอย่างที่เราทุกคนสามารถแบ่งปันได้ - สำหรับสิ่งต่าง ๆ เช่นการจัดรูปแบบการส่งข้อความล่วงหน้า Git <project>/.git/hooks/มีสคริปต์เบ็ดสำหรับที่จะถูกเก็บไว้ตามปกติ อย่างไรก็ตามสคริปต์เหล่านั้นจะไม่ถูกเผยแพร่เมื่อผู้ใช้ทำการโคลนและไม่ได้ควบคุมเวอร์ชัน

มีวิธีที่ดีที่จะช่วยให้ทุกคนได้รับสคริปต์ที่ถูกต้องหรือไม่ ฉันสามารถทำให้เบ็ดสคริปต์เหล่านั้นชี้ไปที่สคริปต์ควบคุมเวอร์ชันใน repo ของฉันได้หรือไม่


5
เป็นคำถามที่ดี ฉันหวังว่าจะมีคำตอบที่ดีกว่า (โดยไม่มีการร้องเรียน @mipadi ฉันแค่หวังว่า git มีวิธีการทำสิ่งนี้โดยอัตโนมัติยิ่งขึ้น - แม้ว่าจะมีตัวเลือกที่ระบุให้กับ
clit

ฉันเห็นด้วย @lindes! แต่บางทีการ จำกัด การแบ่งปันของ hooks นี้โดยตั้งใจ? ฉันคิดว่าสิ่งต่าง ๆ จะยุ่งเหยิงสำหรับผู้ใช้ Windows
kristianlm

@ Kristianlm: มีหลายเหตุผลที่มันอาจจะยุ่งในบางครั้ง ... และก็เป็นเวลาที่มันดีที่จะมีมัน ฉันแค่หวังว่าจะมีตัวเลือกหรือสิ่งที่จะคัดลอกเบ็ด ฉันเดาว่าฉันจะต้องตรวจสอบรหัส git-core บางครั้งและทำการแก้ไข :) (หรือความหวังว่าคนอื่นไม่ ... หรืออยู่กับการแก้ปัญหาในคำตอบของ mipadiหรืออะไรก็ตาม.)
Lindes

pre-commitทำให้ง่ายสำหรับการผูกตะขอล่วงหน้า ไม่ตอบคำถามของ OP เกี่ยวกับการจัดการ git hook โดยพลการ แต่ hooks ที่ผูกมัดไว้ล่วงหน้าน่าจะใช้บ่อยที่สุดเพื่อจุดประสงค์ด้านคุณภาพของรหัส
ericsoco

คำตอบ:


144

ในทางทฤษฎีคุณสามารถสร้างhooksไดเรกทอรี (หรือชื่อใดก็ได้ที่คุณต้องการ) ในไดเรกทอรีโครงการของคุณด้วยสคริปต์ทั้งหมดแล้วเชื่อมโยงเข้า.git/hooksด้วยกัน แน่นอนว่าแต่ละคนที่เลียนแบบ repo จะต้องตั้งค่า symlinks เหล่านี้ (แม้ว่าคุณจะได้รับแฟนซีและมีสคริปต์การปรับใช้ที่ cloner สามารถเรียกใช้เพื่อตั้งค่ากึ่งอัตโนมัติ)

ในการทำ symlink บน * ระวังสิ่งที่คุณต้องทำคือ:

root="$(pwd)"
ln -s "$root/hooks" "$root/.git/hooks"

ใช้ln -sfถ้าคุณพร้อมที่จะเขียนทับสิ่งที่มีอยู่.git/hooks


38
นี่ไม่ใช่เรื่องไม่สำคัญดังนั้นฉันจึงรวมลิงก์ไปยังวิธีการเชื่อมโยงอย่างถูกต้อง: stackoverflow.com/questions/4592838/…
David T.

17
git เวอร์ชั่น 2.9 ตอนนี้มีตัวเลือกcore.hooksPathการกำหนดค่าสำหรับการตั้งค่าไฟล์นอก. git เพื่อเชื่อมโยงไปยังโฟลเดอร์ hooks
Aaron Rabinowitz

216

ในGit 2.9ตัวเลือกการกำหนดค่าจะcore.hooksPathระบุไดเรกทอรี hooks ที่กำหนดเอง

ย้าย hooks ของคุณไปยังhooksไดเรกทอรีที่ถูกติดตามในพื้นที่เก็บข้อมูลของคุณ จากนั้นกำหนดค่าแต่ละอินสแตนซ์ของที่เก็บเพื่อใช้การติดตามhooksแทน$GIT_DIR/hooks:

git config core.hooksPath hooks

โดยทั่วไปแล้วพา ธ อาจเป็นแบบสัมบูรณ์หรือสัมพันธ์กับไดเรกทอรีที่มีการเรียกใช้ hooks (โดยปกติจะเป็นรูทของต้นไม้ที่ใช้งานได้โปรดดูที่ส่วนคำอธิบายของman githooks)


15
... และไดเร็กตอรี่ hooks ที่ชี้ไปที่สามารถเป็นที่เก็บ s hooks แยกกัน;)
René Link

10
ทีนี้, พารามิเตอร์การตั้งค่าอัตโนมัตินี้ถูกตั้งค่าเมื่อคุณทำ git clone หรือไม่?
แหวน

4
เนื่องจากไม่สามารถตั้งค่าตัวแปรกฎ git config โดยที่เก็บที่คุณกำลังโคลน ฉันคิดว่านี่เพื่อป้องกันการเรียกใช้โค้ดโดยอำเภอใจ git config ควบคุมการทำงานของรหัสผ่าน hooks, ชื่อผู้ใช้ในการส่งข้อความและฟังก์ชั่นที่สำคัญอื่น ๆ
Max Shenfield

1
จะเป็นอย่างไรถ้ามีคนในทีมเช็คเอาต์คอมไพล์ไปยังสาขาอื่น พวกเขาต้องรวมไว้ในทุกสาขา ..
นักเลง

1
นั่นเป็นเรื่องจริง ในทางกลับกันหากคุณอัปเดตฮุกในคอมมิชชันที่ใหม่กว่า repos ที่ลอกเลียนแบบจะได้รับโดยอัตโนมัติเมื่อทำงานกับสาขาที่อยู่ด้านบน ทั้งสองวิธีมีทั้งขึ้นและลง
fabb

15

หากโครงการของคุณเป็นโครงการ JavaScript และคุณใช้npmเป็นผู้จัดการแพคเกจที่คุณสามารถใช้ร่วมกัน githooksในการบังคับใช้ githooks npm installบน


5
ตอนนี้ฉันรู้แล้วว่าใครเป็นคนที่เพิ่มอึให้กับคน.git/hooksอื่น
gavenkoa

คำเตือน - ไม่รองรับ Windows (ยกเว้นว่ามันจะทำงานในฐานะผู้ดูแลระบบใน git bash) วิธีแก้ปัญหาอย่างง่ายคือการเพิ่ม "preinstall": "git config core.hooksPath hooks" เป็นสคริปต์ใน package.json ie ที่ไหน hooks เป็นโฟลเดอร์ที่มีสคริปต์คอมไพล์ของคุณ
Shane Gannon

8

สำหรับผู้ใช้Nodejsทางออกที่ง่ายคือการปรับปรุงpackage.jsonด้วย

{
  "name": "name",
  "version": "0.0.1",
  ......
  "scripts": {
    "preinstall": "git config core.hooksPath hooks", 

การติดตั้งล่วงหน้าจะทำงานก่อน

ติดตั้ง NPM

และเปลี่ยนเส้นทาง git เพื่อค้นหา hooks ภายในไดเรกทอรี. \ hooks (หรือชื่ออะไรก็ได้ที่คุณเลือก) ไดเรกทอรีนี้ควรเลียนแบบ. \. git \ hooksในแง่ของชื่อไฟล์ (ลบด้วย. ตัวอย่าง) และโครงสร้าง

ลองนึกภาพ Maven และเครื่องมือสร้างอื่น ๆ จะมีเทียบเท่ากับpreinstall

ควรทำงานได้กับทุกแพลตฟอร์ม

หากคุณต้องการข้อมูลเพิ่มเติมโปรดดูที่https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team/


5

วิธีการเกี่ยวกับคอมไพล์ตะขอมันเส้นทางวิงวอนขอเป็นสคริปต์ภายใต้ไดเรกทอรีโครงการ.git/hooksgithooks

นอกจากนี้ยังมีคุณสมบัติมากมายที่จะช่วยให้คุณลดการคัดลอกและ symlink เบ็ดทั่วสถานที่


5

ภาษาการเขียนโปรแกรมที่ทันสมัยส่วนใหญ่หรือค่อนข้างเป็นเครื่องมือสร้างสนับสนุนปลั๊กอินเพื่อจัดการ git hooks นั่นหมายถึงสิ่งที่คุณต้องทำคือกำหนดค่า package.json, pom.xml และทุกคนในทีมของคุณจะไม่มีตัวเลือก แต่ต้องปฏิบัติตามเว้นแต่พวกเขาจะเปลี่ยนไฟล์บิลด์ ปลั๊กอินจะเพิ่มเนื้อหาไปยังไดเรกทอรี. git สำหรับคุณ

ตัวอย่าง:

https://github.com/rudikershaw/git-build-hook

https://github.com/olukyrich/githook-maven-plugin

https://www.npmjs.com/package/git-hooks


ฉันพยายามทำให้สำเร็จด้วยวิธีทั่วไปเพื่อใช้ในโครงการของฉันดังนั้นฉันจึงเขียนเครื่องมือนี้: pypi.org/project/hooks4git
Lovato

3

เราใช้โซลูชัน Visual Studio (และโครงการอื่น ๆ ) ที่มีทั้งก่อนและหลังการสร้างเหตุการณ์ ฉันกำลังเพิ่มโครงการเพิ่มเติมชื่อ 'GitHookDeployer' โปรเจ็กต์เองแก้ไขไฟล์ในเหตุการณ์ post build ไฟล์นั้นถูกตั้งค่าให้คัดลอกไปยังไดเรกทอรีการสร้าง ดังนั้นโครงการจะถูกสร้างขึ้นทุกครั้งและไม่เคยข้าม ในการสร้างเหตุการณ์มันทำให้แน่ใจว่า git hooks ทั้งหมดอยู่ในตำแหน่ง

โปรดทราบว่านี่ไม่ใช่วิธีแก้ปัญหาทั่วไปเนื่องจากบางโครงการไม่มีอะไรต้องสร้าง


2

คุณสามารถใช้วิธีการแก้ปัญหาการจัดการก่อนกระทำการจัดการเบ็ดเหมือนก่อนกระทำ หรือวิธีการแก้ปัญหาที่ส่วนกลางในฝั่งเซิร์ฟเวอร์คอมไพล์ตะขอเช่นDatree.io มันมีนโยบายในตัวเช่น:

  1. ตรวจสอบและป้องกันการผสานความลับ
  2. การบังคับใช้ที่เหมาะสมการกำหนดค่าใช้ Git
  3. บังคับใช้การรวมตั๋ว Jira - พูดถึงหมายเลขตั๋วในชื่อคำขอดึง / ส่งข้อความยอมรับ

มันจะไม่แทนที่ฮุกของคุณทั้งหมด แต่มันอาจช่วยนักพัฒนาของคุณด้วยสิ่งที่ชัดเจนที่สุดโดยไม่ต้องมีการกำหนดค่าของการติดตั้ง hooks บนคอมพิวเตอร์ทุก ๆ นักพัฒนา / repo

ข้อจำกัดความรับผิดชอบ: ฉันเป็นหนึ่งในผู้ก่อตั้ง Datrees


1

คุณสามารถทำให้โฟลเดอร์ hooks เป็นที่เก็บคอมไพล์อีกอันและเชื่อมโยงมันเป็น submodule ... ฉันเดาว่ามันคุ้มค่าก็ต่อเมื่อคุณมีสมาชิกจำนวนมากและ hooks เปลี่ยนแปลงเป็นประจำ


1

โดยหลักแล้ว hooks จะเขียนเป็น bash หากคุณติดตามไฟล์ตัวอย่าง แต่คุณสามารถเขียนเป็นภาษาใดก็ได้ที่มีอยู่และตรวจสอบให้แน่ใจว่ามีแฟล็กที่สามารถเรียกทำงานได้

ดังนั้นคุณสามารถเขียนรหัส Python หรือ Go เพื่อให้บรรลุเป้าหมายและวางไว้ใต้โฟลเดอร์ hooks มันจะทำงานได้ แต่มันจะไม่ถูกจัดการพร้อมกับพื้นที่เก็บข้อมูล

สองตัวเลือก

a) สคริปต์หลายตัว

คุณสามารถเขียนโค้ด hooks ภายในตัวช่วยและเพิ่มโค้ดเล็ก ๆ ลงใน hooks เพื่อเรียกสคริปต์ที่สมบูรณ์แบบของคุณดังนี้:

$ cat .git/hooks/pre-commit
#!/bin/bash
../../hooks/myprecommit.js

b) สคริปต์เดียว

ตัวเลือกที่เย็นกว่าคือการเพิ่มสคริปต์เพียงหนึ่งสคริปต์เพื่อควบคุมสคริปต์ทั้งหมดแทนที่จะเป็นสคริปต์หลายสคริปต์ ดังนั้นคุณจึงสร้าง hooks / mysuperhook.go ขึ้นมาและชี้ให้เห็นตะขอทุกอันที่คุณต้องการ

$ cat .git/hooks/pre-commit
#!/bin/bash
../../hooks/mysuperhook.go $(basename $0)

พารามิเตอร์จะให้สคริปต์ของคุณที่จะถูกเรียกเบ็ดและคุณสามารถแยกความแตกต่างในรหัสของคุณ ทำไม? บางครั้งคุณอาจต้องการเรียกใช้การตรวจสอบเดียวกันสำหรับการกระทำและผลักดันเช่น

ถ้าอย่างนั้น

จากนั้นคุณอาจต้องการฟังก์ชันเพิ่มเติมเช่น:

  • ทริกเกอร์เบ็ดด้วยตนเองเพื่อตรวจสอบว่าทุกอย่างโอเคแม้กระทั่งก่อนที่จะส่งหรือส่ง หากคุณเพียงแค่เรียกสคริปต์ของคุณ (ตัวเลือกกหรือข) จะทำเคล็ดลับ
  • ทริกเกอร์ hooks บน CI ดังนั้นคุณไม่จำเป็นต้องเขียนเช็คเหมือนกันสำหรับ CI ใหม่มันก็แค่เรียกการเรียกและส่งทริกเกอร์ เช่นเดียวกับข้างต้นควรแก้มัน
  • เรียกเครื่องมือภายนอกเช่นตัวตรวจสอบความถูกต้องของมาร์คดาวน์หรือตัวตรวจสอบความถูกต้องของ YAML คุณสามารถสร้าง syscalls และจำเป็นต้องจัดการกับ STDOUT และ STDERR
  • ตรวจสอบให้แน่ใจว่านักพัฒนาซอฟต์แวร์ทั้งหมดมีวิธีง่ายๆในการติดตั้ง hooks ดังนั้นจึงจำเป็นต้องเพิ่มสคริปต์ที่ดีในที่เก็บเพื่อแทนที่ hooks เริ่มต้นด้วยอันที่ถูกต้อง
  • มีผู้ช่วยเหลือระดับโลกบางคนเช่นเช็คเพื่อป้องกันการผูกมัดเพื่อพัฒนาและสาขาหลักโดยไม่ต้องเพิ่มลงในที่เก็บข้อมูลทุกแห่ง คุณสามารถแก้ไขได้โดยมีที่เก็บอื่นที่มีสคริปต์ส่วนกลาง

มันง่ายกว่านี้ไหม?

ใช่มีเครื่องมือหลายอย่างที่จะช่วยคุณจัดการ git-hooks แต่ละคนได้รับการปรับแต่งเพื่อจัดการปัญหาจากมุมมองที่แตกต่างกันและคุณอาจต้องเข้าใจพวกเขาทั้งหมดเพื่อให้ได้สิ่งที่ดีที่สุดสำหรับคุณหรือทีมของคุณ GitHooks.comเสนอการอ่านจำนวนมากเกี่ยวกับการเชื่อมโยงและเครื่องมือต่าง ๆ ที่มีในปัจจุบัน

ณ วันนี้มี 21 โครงการที่ระบุไว้ด้วยกลยุทธ์ที่แตกต่างกันในการจัดการ hooks git บางอันใช้สำหรับเบ็ดเดี่ยวบางอันใช้สำหรับภาษาที่เฉพาะเจาะจงและอื่น ๆ

หนึ่งในเครื่องมือเหล่านั้นเขียนขึ้นโดยผมและให้บริการฟรีเป็นโครงการ opensource จะเรียกว่าhooks4git มันเขียนใน Python (เพราะฉันชอบ) แต่ความคิดคือการจัดการรายการทั้งหมดที่ระบุไว้ข้างต้นในไฟล์การกำหนดค่าเดียวที่เรียกว่า. hooks4git.ini ซึ่งอาศัยอยู่ในพื้นที่เก็บข้อมูลของคุณและสามารถเรียกใช้สคริปต์ใด ๆ ที่คุณต้องการโทรในภาษาใด ๆ .

การใช้ git hooks นั้นยอดเยี่ยมมาก แต่วิธีที่พวกเขามักจะนำเสนอคือทำให้ผู้คนไม่ชอบมัน


ฉันโพสต์เวอร์ชั่นที่สั้นลงเมื่อไม่นานมานี้และตามที่ได้ตกลงกับผู้ดูแลสิ่งนี้นำคำอธิบายมาไว้ในนั้นและลิงก์สั้น ๆ ไปยังเครื่องมือที่ฉันเขียนเองซึ่งฉันคิดว่าอาจช่วยนักพัฒนาคนอื่น ๆ
Lovato

1

สำหรับผู้ใช้เกร็ก

ฉันพบสคริปต์เหล่านี้มีประโยชน์มากสำหรับโครงการที่มีระดับ

build.gradle

apply from: rootProject.file('gradle/install-git-hooks.gradle')

gradle / ติดตั้ง Git-hooks.gradle

tasks.create(name: 'gitExecutableHooks') {
    doLast {
        Runtime.getRuntime().exec("chmod -R +x .git/hooks/");
    }
}
task installGitHooks(type: Copy) {
    from new File(rootProject.rootDir, 'pre-commit')
    into { new File(rootProject.rootDir, '.git/hooks') }
}
gitExecutableHooks.dependsOn installGitHooks
clean.dependsOn gitExecutableHooks

ก่อนกระทำ

.... your pre commit scripts goes here
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.