ทำให้คอมไพล์กระทำโดยอัตโนมัติ


155

ฉันต้องการใช้ git เพื่อบันทึกการเปลี่ยนแปลงทั้งหมดในไฟล์

มีวิธีที่ฉันสามารถเปิดคอมมิท 'คอมมิชชัน' เพื่อให้เกิดขึ้นโดยอัตโนมัติทุกครั้งที่มีการอัปเดตไฟล์หรือไม่ดังนั้นจึงมีคอมมิทใหม่สำหรับการเปลี่ยนแปลงทุกไฟล์

เป็นการดีที่ฉันต้องการให้ผู้ใช้ของฉันไม่รู้ด้วยซ้ำว่าคอมไพล์กำลังทำงานอยู่เบื้องหลัง จากนั้นผู้ใช้สามารถ "ยกเลิก" การเปลี่ยนแปลงไฟล์ - และสิ่งนี้สามารถทำได้โดยการดึงรุ่นก่อนหน้าออกจากระบบคอมไพล์


9
มันจะง่ายกว่าถ้าใช้ระบบไฟล์ที่กำหนดเวอร์ชัน: en.wikipedia.org/wiki/Versioning_file_system
William Pursell

1
SparkleShare ค่อนข้างประทับใจในเรื่องนั้น
theode

SparkleShare ดูตัวเลือกที่ดี แต่มันทำลายโฟลเดอร์. git ใด ๆ ภายใน git หลัก
insign

คุณสามารถใช้github.com/jw0k/gwatch มันทำงานบน Windows และ Linux
rubix_addict

@rubix_addict ทำไมคุณไม่โพสต์สิ่งนั้นเป็นคำตอบ?
Tobias Kienzler

คำตอบ:


127

บน Linux คุณสามารถใช้inotifywaitเพื่อดำเนินการคำสั่งโดยอัตโนมัติทุกครั้งที่มีการเปลี่ยนแปลงเนื้อหาของไฟล์

แก้ไข: คำสั่งต่อไปนี้คอมมิต file.txt ทันทีที่มันถูกบันทึก:

inotifywait -q -m -e CLOSE_WRITE --format="git commit -m 'autocommit on change' %w" file.txt | sh

2
คุณจะทำให้มันทำงานได้ทั้งโฟลเดอร์ (ไม่ใช่แค่ไฟล์เดียว)
Anderson Green

2
ใช้-rแฟinotifywaitล็กถึงแต่โปรดทราบว่าเคอร์เนลมีข้อ จำกัด เกี่ยวกับจำนวน inotifywait watches ที่สามารถตั้งค่าได้ man inotifywaitจะบอกคุณมากกว่านี้
JesperE

14
มีตัวเลือกใน windows .. ?
Chandan Pasunoori

50

คำตอบที่ไม่คาดคิดมาก่อนนั้นยอดเยี่ยม แต่ก็ไม่ได้เป็นคำตอบที่สมบูรณ์ ตามที่เขียนไว้มันเป็นช็อตเดียวที่กระทำเพื่อการเปลี่ยนแปลงครั้งเดียวในไฟล์ มันไม่ทำงานสำหรับกรณีทั่วไปที่การแก้ไขไฟล์สร้าง inode ใหม่ด้วยชื่อเดิม inotifywait -mติดตามไฟล์โดย inode ไม่ใช่ชื่อ นอกจากนี้หลังจากที่ไฟล์ที่มีการเปลี่ยนแปลงก็ไม่ได้จัดฉากสำหรับคอมไพล์กระทำโดยไม่ต้องคอมไพล์เพิ่มหรือGIT กระทำ -a ทำการปรับบางอย่างนี่คือสิ่งที่ฉันใช้บน Debian เพื่อติดตามการเปลี่ยนแปลงทั้งหมดในไฟล์ปฏิทินของฉัน:

/etc/rc.local:


su -c /home/<username>/bin/gitwait -l <username>

/ home / <username> / bin / gitwait:


#!/bin/bash
#
# gitwait - watch file and git commit all changes as they happen
#

while true; do

  inotifywait -qq -e CLOSE_WRITE ~/.calendar/calendar

  cd ~/.calendar; git commit -a -m 'autocommit on change'

done

นี่อาจเป็นแบบทั่วไปเพื่อรอรายการของไฟล์และ / หรือไดเรกทอรีและกระบวนการinotifywait ที่สอดคล้องกันและรีสตาร์ทinotifywaitแต่ละรายการในขณะที่ไฟล์มีการเปลี่ยนแปลง


8
เลสเตอร์คุณช่วยกรุณาขยายวิธีการทั่วไปในไดเรกทอรี?
Diego

29

คำตอบก่อนหน้านี้แนะนำinotifywaitสำหรับงานนี้ทิปฉันในทิศทางที่ถูกต้องเมื่อฉันมีปัญหานี้ด้วยตัวเองดังนั้นฉันจึงเขียนสคริปต์เล็กน้อย ก่อนอื่นนี่แค่ดูโฟลเดอร์ทั้งหมดซ้ำ (ตรงข้ามกับตัวอย่างของ Lester Buck) แต่จากนั้นฉันก็อยากดูไฟล์ที่อื่นดังนั้นฉันจึงขยายมัน

ผลลัพธ์คือสคริปต์ที่ถูกเรียกใช้ในปัจจุบันgitwatchซึ่งเป็นสิ่งที่มันทำ: มันจะเฝ้าดูไฟล์หรือโฟลเดอร์สำหรับการเปลี่ยนแปลง

คุณสามารถค้นหาสคริปต์ข้อมูลเพิ่มเติมและคำแนะนำได้ที่ github: https://github.com/nevik/gitwatch


4
สคริปต์ตัวน้อยที่มีประโยชน์ ฉันจะจดบันทึกมัน
iwein

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

16

git-wipเป็นทางออกที่ยอดเยี่ยมที่ทำงานได้ดีสำหรับฉัน "WIP" หมายถึง "งานระหว่างทำ" ทุกครั้งที่คุณเรียกใช้ 'git wip' การเปลี่ยนแปลงจะถูกส่งไปยังสาขาแยกต่างหาก สามารถรันบนบรรทัดคำสั่ง แต่มีส่วนขยายสำหรับ vim และ emacs เพื่อรัน git-wip โดยอัตโนมัติในแต่ละครั้งที่เขียนไฟล์


12

ฉันต้องการทำเช่นนี้ใน windows และพบวิธีที่ดีที่สุดคือการใช้การตรวจสอบไดเรกทอรีเพื่อตรวจสอบการเปลี่ยนแปลงจากนั้นเมื่อตรวจพบว่ามีการเปลี่ยนแปลงการทำงาน:

โปรแกรม: cmd.exe

พารามิเตอร์: /CC:\pathToBatchFile.bat

ไฟล์แบตช์นั้นมี:

c:
cd c:\gitRepoDirectory\
(if exist "%PROGRAMFILES(X86)%" (
"%PROGRAMFILES(X86)%\git\bin\sh.exe" --login -i -c "git commit -am AutoCommitMessage"
) else (
"%PROGRAMFILES%\git\bin\sh.exe" --login -i -c "git commit -am AutoCommitMessage"
))

ฉันยังลองใช้คำสั่งอื่นเพื่อเพิ่มไฟล์ ( "%PROGRAMFILES(X86)%\git\bin\sh.exe" --login -i -c "git add *.*") แต่ฉันคิดว่าฉันทำงานไม่ถูกต้อง

ฉันทำเบ็ด post-commit ที่มี:

#!/bin/sh
git.exe pull -v --progress  "origin"
git.exe push    --progress  "origin" master:master
curl.exe -s https://webserverdomain.com/updateFromGitHook.x?r=repoName

(หากมีความขัดแย้งใด ๆ ก็จะยกเลิกการดึงและยกเลิกการกด แต่ไม่มีวิธีที่ชัดเจนที่จะบอกว่าเกิดขึ้น - ในที่สุดเราก็ทิ้งความคิดทั้งหมดเพราะข้อบกพร่องนี้)

คำสั่ง curl นั้นบอกเซิร์ฟเวอร์ของฉันว่าจำเป็นต้องทำการดึงรหัส ทั้งหมดที่จำเป็นในการจัดการใน php คือ:

<?
$r = $_GET['r'];
if (!empty($c)) {
    //use system instead of exec if you want the output to go back to the git client
    exec("cd /path/to/repo/parent/$r; sudo git reset --hard HEAD; sudo git pull;");
    echo "\n\nServer: Updated\n\n";
} else {
    echo "\n\nServer: UPDATE FAILED\n\n";
}
?>

ปัญหาเดียวที่เกิดขึ้นคือต้องมีการเรียกใช้โดยผู้ใช้รูทแทนที่จะเป็นผู้ใช้ apache ดังนั้นฉันจึงต้องสร้างไฟล์/etc/sudoers.d/ที่มี:

www-data ALL = NOPASSWD: /usr/bin/git

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


นอกจากนี้บน Windows ฉันไม่สามารถเรียกใช้ git ภายใต้ LocalSystem ได้ดังนั้นหากคุณสร้างบริการตรวจสอบของคุณเองคุณจะต้องเรียกใช้งานภายใต้ผู้ใช้ที่สามารถเรียกใช้ Git ได้ เป็นไปได้ฉันเพิ่งขาดการตั้งค่า / การกำหนดค่าบางอย่าง แต่อาจดีกว่าที่จะตั้งค่าบัญชีคอมมิทใหม่กระทำต่อไป
Whelkaholism


8

Inotify ดูเหมือนจะเป็นเครื่องมือที่เหมาะสมสำหรับงานจริงๆ

มีเครื่องมือที่เรียกว่าincronซึ่งอาจเป็นสิ่งที่คุณกำลังมองหา คุณสามารถระบุไฟล์หรือโฟลเดอร์ (และประเภทเหตุการณ์เช่น "เปลี่ยน", "สร้าง", "ยกเลิกการเชื่อมโยง") ในบางสิ่งเช่น crontab และคำสั่งให้เรียกใช้เมื่อมีเหตุการณ์ดังกล่าวเกิดขึ้น

ตรงกันข้ามกับ inotifywait (ซึ่งจะเป็นแอนะล็อกของ cron ของคนจนsleep 10;do stuff) สิ่งนี้จะจับทุกเหตุการณ์ไม่ใช่แค่เหตุการณ์แรก

ฉันไม่ได้ใช้ด้วยตนเอง แต่จากเอกสารไม่ได้ดูซับซ้อนเกินกว่าจะติดตั้งได้


7

ฉันเขียนโปรแกรมGitPrimeเพื่อให้บันทึกอัตโนมัติสำหรับที่เก็บ Git ในพื้นที่ของคุณ ตอนนี้ง่ายต่อการย้อนกลับไปก่อนที่คุณจะจับมัน! Bitbucket พื้นที่เก็บข้อมูล

สิ่งนี้ควรใช้กับแพลตฟอร์มใดก็ได้ที่รองรับ bash shell รวมถึง Windows + Cygwin


+1 ฉันใช้สิ่งนี้บน windows (CygWin) เพื่อบันทึกการเปลี่ยนแปลงโดยอัตโนมัติฉันทำกับที่เก็บ git-tf ทุก ๆ 10 นาทีโดยใช้งานที่กำหนดไว้
Darbio

6

ในกรณีที่ทุกคนพยายามทำสิ่งนี้จาก Powershell ฉันประสบความสำเร็จโดยใช้สิ่งต่อไปนี้:

& "C:\Program Files (x86)\Git\bin\sh.exe" -c "cd D:\PATH\TO\REPO && git add --all  &&  git commit -m 'Automatic Commit Message Goes Here' && git push origin master"

5
และสิ่งนี้จะถูกเรียกใช้โดยอัตโนมัติอย่างไร
jerik

2
งานที่กำหนดไว้?
ozzy432836


2

หากคุณรู้ชื่อของไฟล์และคุณต้องการตรวจสอบเพียงหนึ่งไฟล์ (หรือไม่กี่ไฟล์) คุณสามารถเรียก "git commit" ทุก ๆ สองสามนาทีเพื่อให้ได้สิ่งนี้ หากไฟล์ไม่เปลี่ยนแปลง git จะบ่นและคุณจะต้องละเว้นข้อผิดพลาดนี้ แต่อย่างอื่นนอกจากนั้นจะไม่มีความเสียหาย

นอกจากนั้นคุณจะต้องทำเครื่องหมายไฟล์เหล่านี้ว่า "auto commit" เพื่อให้สามารถทำการส่งด้วยตนเองได้เช่นกัน ด้วยวิธีนี้ผู้ใช้สามารถเห็นการเปลี่ยนแปลงอัตโนมัติและการเปลี่ยนแปลง "เชิงตรรกะ" ที่ใหญ่กว่าซึ่งมาพร้อมกับคอมมิตคอมเม้นท์เพื่ออธิบายว่ามีการเปลี่ยนแปลงตั้งแต่การคอมมิทครั้งล่าสุด

ตัวอย่างเช่นใช้ "AUTOCOMMIT" เป็นข้อความยืนยัน ในภายหลังคุณสามารถเขียนเครื่องมือเพื่อล้างคอมมิทเหล่านี้โดยใช้บันทึก git (เพื่อค้นหาการแก้ไขเพื่อฆ่า) หรือคุณสามารถลองสร้างสาขา AUTOCOMMIT โดยใช้กลยุทธ์การแก้ไขปัญหาการชนกันอย่างดุเดือดเพื่อตอกย้ำใน

อีกทางเลือกหนึ่งคือการใช้คำสั่งระดับต่ำของคอมไพล์เพื่อสร้างพื้นที่เก็บข้อมูลเฉพาะของคุณเอง

สุดท้ายคุณสามารถคัดลอกไฟล์ไปยังชื่อใหม่ ("$ filename.ac") ในขณะที่ทำอัตโนมัติมุ่งมั่นที่จะแยกความแตกต่างระหว่างรุ่นคู่มือและรุ่นอัตโนมัติ


1

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


นอกจากนี้การสำรวจเพื่อเปลี่ยนแปลงจะสร้างเงื่อนไขการแข่งขัน
Bombe

1
ไม่ใช่กับบรรณาธิการเช่น emacs และ yi ซึ่งเขียนไฟล์ "transactionally" เพื่อพยายามให้แน่ใจว่าข้อมูลจะไม่สูญหายหลังจากเกิดความผิดพลาด
Robin Green

1

ดูเหมือนว่าคุณกำลังมองหาสิ่งที่คล้ายกับetckeeperซึ่งถูกออกแบบมาเพื่อตรวจสอบการเปลี่ยนทั้งหมดของคุณเป็น / etc / * เป็น git (หรือสิ่งที่ VCS ที่คุณต้องการ) โดยอัตโนมัติ แต่ฉันเห็นเหตุผลที่ไม่สามารถใช้กับไฟล์ได้ นอกเหนือจากที่อยู่ใน / etc

หากคุณต้องการจัดการกับไฟล์เดียวอาจจะไม่สมบูรณ์ แต่ถ้าคุณต้องการติดตามทุกสิ่งในไดเรกทอรีที่ระบุฉันคิดว่ามันคุ้มค่าที่จะตรวจสอบ


1

สคริปต์นี้ไม่ทำงานเมื่อผู้ใช้เปลี่ยนไฟล์ แต่สามารถเรียกใช้เป็นงาน cron (โดยวางลงในไดเรกทอรี /etc/cron.*) ซึ่งเป็นโซลูชันที่สมเหตุสมผล

สคริปต์นี้จะวนซ้ำผ่านไดเรกทอรี / srv / www ของคุณ (เปลี่ยนเป็นที่ใดก็ตามที่เก็บเว็บไซต์ทั้งหมดของคุณ) เพิ่มกระทำและส่งไฟล์ทั้งหมดแล้วบันทึกทุกอย่างไปที่ /var/log/gitlog.txt

now=$(date +"%m.%d.%Y_%T")
logfile='/var/log/gitlog.txt'

for dir in /srv/www/*/
do
echo -e '\n' >> $logfile
echo "autocommit $dir $now" >> $logfile
echo "--------------------------" >> $logfile

cd $dir
git add . >> $logfile
git commit -am "autocommit $now" >> $logfile
git push origin master >> $logfile
done

0

ฉันมีปัญหาเดียวกันและใน mac launchd ให้ทางออกที่ดี มันจะดูไฟล์หรือไดเรกทอรีและหากมีการเปลี่ยนแปลงคุณสามารถเรียกใช้แอพหรือสิ่งอื่น ...


ดูที่ "การตรวจสอบไดเรกทอรี" ที่นี่: developer.apple.com/library/mac/#documentation/MacOSX/…
Kris

0

ฉันสร้างเชลล์สคริปต์ตัวจิ๋วนี้เพื่อตรวจสอบสถานะไฟล์และคำสั่งทริกเกอร์เช่นคอมไพล์ส่งต่อเพื่อสร้างความสำเร็จ

ดาวน์โหลดและทดลองใช้ฟรี

https://github.com/nzvincent/nzvincent-github/blob/master/inotify-tools/inotify.sh


0

นี่ไม่เป็นไปตามส่วน "อุดมคติ" ของคำถาม แต่นี่เป็นคำถามที่ใกล้เคียงที่สุดที่ฉันเห็นต่อคำตอบที่ฉันต้องการดังนั้นฉันจึงคิดว่ามันสามารถไปที่นี่ได้ แม้ว่าการโพสต์แบบสแต็กแรกของฉันดังนั้นขออภัยถ้าฉันเข้าใจผิด

สคริปต์ต่อไปนี้ช่วยให้มั่นใจได้ถึงการกระทำโดยอัตโนมัติเกี่ยวกับการเปลี่ยนแปลงที่บันทึกไว้ แต่จะแจ้งให้ผู้ใช้ส่งข้อมูล (ฉันรู้ว่าสถานการณ์ของฉันแตกต่างจากของ git-noob เล็กน้อย)


# While running, monitors the specified directory, and when a file therein 
# is created or edited and saved, this prompts the user for a commit message.
# The --exclude is to avoid extra prompts for the changes made to 
# version control directories.

# requires inotify-tools

inotifywait --exclude '/\..+' -m  path/to/directory -e modify -e create |
        while read path action file; do
                gnome-terminal -e 'bash -c "cd path/to/directory; 
                                            git add *; 
                                            echo What did you just do??; 
                                            read varname; 
                                            git commit -m \"$varname\""'
        done

0

สำหรับ Windows

ตามบทความเกี่ยวกับการเติมข้อความอัตโนมัติคุณต้องสร้าง.batไฟล์ที่มีเนื้อหา:

git add -u
git commit -m "your commit message"
git push origin master 

Task Schedulerและดำเนินการกับ หากคุณไม่ทราบวิธีการทีละขั้นตอนให้อ้างอิงบทความนั้น

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