Membuat git auto-commit

155

Saya ingin menggunakan git untuk merekam semua perubahan pada file.

Apakah ada cara saya dapat mengaktifkan git 'commit' untuk secara otomatis terjadi setiap kali file diperbarui - jadi ada komitmen baru untuk setiap perubahan pada file?

Idealnya saya ingin pengguna saya tidak tahu bahwa git berjalan di belakang layar. Seorang pengguna kemudian berpotensi "membatalkan" perubahan ke file - dan ini bisa dicapai dengan menarik versi sebelumnya dari git.

git-noob
sumber
9
Akan lebih mudah menggunakan filesystem versi: en.wikipedia.org/wiki/Versioning_file_system
William Pursell
1
SparkleShare cukup mengesankan tentang hal itu.
theode
SparkleShare terlihat pilihan yang bagus tetapi menghancurkan folder .git di dalam git utama
insign
Anda dapat menggunakan github.com/jw0k/gwatch . Ini bekerja pada Windows dan Linux.
rubix_addict
@rubix_addict Mengapa Anda tidak mempostingnya sebagai jawaban?
Tobias Kienzler

Jawaban:

127

Di Linux Anda bisa menggunakan inotifywait untuk secara otomatis menjalankan perintah setiap kali konten file diubah.

Edit: perintah berikut melakukan file.txt segera setelah disimpan:

inotifywait -q -m -e CLOSE_WRITE --format="git commit -m 'autocommit on change' %w" file.txt | sh
JesperE
sumber
2
Bagaimana Anda bisa membuatnya melakukan ini untuk seluruh folder (bukan hanya satu file?)
Anderson Green
2
Gunakan -rflag untuk inotifywait, tetapi perhatikan bahwa kernel memiliki batasan pada jumlah jam tangan inotifywait yang dapat diatur. man inotifywaitakan memberi tahu Anda lebih banyak.
JesperE
14
apakah ada opsi di windows ..?
Chandan Pasunoori
50

Jawaban inotifywait sebelumnya memang bagus, tetapi itu bukan solusi yang cukup lengkap. Seperti yang ditulis, ini adalah komit satu tembakan untuk satu kali perubahan dalam file. Ini tidak berfungsi untuk kasus umum di mana mengedit file membuat inode baru dengan nama asli. inotifywait -m tampaknya mengikuti file dengan inode, bukan dengan nama. Juga, setelah file berubah, itu tidak dipentaskan untuk git commit tanpa git add atau git commit -a . Membuat beberapa penyesuaian, inilah yang saya gunakan di Debian untuk melacak semua perubahan pada file kalender saya:

/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

Ini dapat digeneralisasi untuk menunggu pada daftar file dan / atau direktori, dan proses inotifywait yang sesuai , dan restart setiap inotifywait ketika file diubah.

Lester Buck
sumber
8
Lester dapatkah Anda memperluas cara menggeneralisasi ini ke direktori?
Diego
29

Jawaban sebelumnya yang merekomendasikan tidak menunggu pekerjaan ini memberi saya petunjuk ke arah yang benar ketika saya memiliki masalah ini sendiri, jadi saya menulis naskah kecil. Pertama ini hanya bisa menonton seluruh folder secara rekursif (kebalikan dari contoh Lester Buck), tetapi kemudian saya juga ingin menonton file di tempat lain, jadi saya memperluasnya.

Hasilnya adalah sebuah skrip yang saat ini dipanggil gitwatch, seperti yang dilakukannya: skrip ini mengawasi file atau folder untuk perubahan (menggunakan inotifywait), dan mengkomitnya ke repositori git.

Anda dapat menemukan skrip, info lebih lanjut dan instruksi di github: https://github.com/nevik/gitwatch

Nevik Rehnel
sumber
4
skrip kecil yang berguna di sana. Saya akan mencatatnya.
iwein
menarik mungkin bermanfaat untuk situs-situs magento. Saya mengujinya tetapi tampaknya tidak bisa mendorongnya secara otomatis juga
NoSixties
16

git-wip adalah solusi hebat yang bekerja dengan baik untuk saya. "WIP" adalah singkatan dari "work in progress". Setiap kali Anda menjalankan 'git wip', perubahan tersebut dilakukan ke cabang terpisah. Itu dapat dijalankan pada baris perintah, tetapi ada ekstensi untuk vim dan emacs untuk secara otomatis menjalankan git-wip setiap kali file ditulis.

rafak
sumber
12

Saya ingin melakukan ini di windows, dan menemukan cara terbaik adalah menggunakan Direktori Monitor untuk memeriksa perubahan lalu ketika mendeteksi perubahan, jalankan:

Program: cmd.exe

Params: /CC:\pathToBatchFile.bat

File kumpulan itu berisi:

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"
))

Saya juga mencoba memiliki perintah lain di sana untuk menambahkan file ( "%PROGRAMFILES(X86)%\git\bin\sh.exe" --login -i -c "git add *.*"), tapi saya rasa saya tidak bisa berfungsi dengan benar.

Saya juga membuat kait pasca-komit yang berisi:

#!/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

(Jika ada konflik maka itu akan membatalkan tarikan dan membatalkan dorong, tetapi tidak ada cara yang jelas untuk mengatakan bahwa telah terjadi - pada akhirnya kami meninggalkan seluruh gagasan karena satu kekurangan ini.)

Perintah curl memberi tahu server saya bahwa itu perlu melakukan tarik pada kode. Semua yang diperlukan untuk menanganinya di php adalah:

<?
$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";
}
?>

Satu-satunya masalah dengan itu adalah itu perlu dijalankan oleh pengguna root, bukan pengguna apache, jadi saya juga harus membuat file /etc/sudoers.d/berisi:

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

Bagi saya, saya pikir itu bekerja cukup solid. Direktori Monitor dapat dikonfigurasi untuk dijalankan pada startup dan mulai diminimalkan, dan dapat menonton beberapa folder berbeda

Redzarf
sumber
Juga di Windows, saya tidak bisa menjalankan git di bawah LocalSystem, jadi jika Anda membuat layanan pemantauan Anda sendiri, Anda harus menjalankannya di bawah pengguna yang benar-benar dapat menjalankan Git. Kemungkinan saya hanya melewatkan beberapa pengaturan / konfigurasi, tetapi mungkin lebih baik untuk membuat akun komit git baru
Whelkaholism
8
#!/bin/bash
git commit -a -m "autoupdate `date +%F-%T`"
git push

pembersihan otomatis dengan tanggal dan waktu saat ini.

pengendara web
sumber
8

Inotify benar-benar terdengar seperti alat yang tepat untuk pekerjaan itu.

Ada alat bernama incron yang bisa persis seperti yang Anda cari. Anda dapat menentukan file atau folder (dan tipe acara, seperti "ubah", "buat", "batalkan tautan") dalam sesuatu seperti crontab, dan perintah untuk dijalankan saat peristiwa semacam itu terjadi.

Berbeda dengan inotifywait (yang akan menjadi analog dari cron orang miskin sleep 10;do stuff), ini akan menangkap setiap peristiwa, bukan hanya yang pertama.

Saya belum menggunakannya sendiri, tetapi dari dokumentasi itu tidak terlihat terlalu rumit untuk diatur.

pixelbrei
sumber
7

Saya menulis sebuah program, GitPrime , untuk menyediakan penyimpanan otomatis untuk repositori Git lokal Anda. Sekarang mudah untuk memutar kembali sebelum Anda merusaknya! Repositori Bitbucket .

Ini harus bekerja pada platform apa pun yang mendukung bash shell termasuk Windows + Cygwin.

Brendan
sumber
+1 Saya menggunakan ini di windows (CygWin) untuk menyimpan otomatis perubahan yang saya buat ke repositori git-tf setiap 10 menit menggunakan tugas yang dijadwalkan
Darbio
6

Jika ada yang mencoba melakukan ini dari Powershell, saya berhasil menggunakan yang berikut:

& "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"
mekul
sumber
5
Dan bagaimana ini dipicu secara otomatis?
jerik
2
tugas yang dijadwalkan?
ozzy432836
2

Jika Anda tahu nama file dan Anda ingin memonitor hanya satu (atau beberapa file), Anda dapat memanggil "git commit" setiap beberapa menit untuk mencapai hal ini. Jika file belum berubah, git hanya akan mengeluh dan Anda harus mengabaikan kesalahan ini tetapi selain itu, tidak akan ada korupsi.

Selain itu, Anda ingin menandai file-file ini sebagai "auto commit" agar dapat melakukan komit juga. Dengan cara ini, pengguna dapat melihat perubahan otomatis dan juga perubahan "logis" yang lebih besar yang disertai dengan komentar komit untuk menjelaskan yang telah berubah sejak komit manual terakhir.

Misalnya, gunakan "AUTOCOMMIT" sebagai pesan komit. Kemudian, Anda dapat menulis alat untuk membersihkan komit ini menggunakan log git (untuk mengetahui revisi untuk membunuh) atau Anda dapat mencoba untuk membuat cabang AUTOCOMMIT menggunakan strategi tekad tabrakan brute force untuk dipalu dalam "komitmen manual".

Pilihan lain adalah menggunakan perintah git level rendah untuk membangun repositori khusus Anda sendiri.

Terakhir, Anda dapat menyalin file ke nama baru ("$ filename.ac") saat melakukan komitmen otomatis untuk membedakan antara versi manual dan otomatis.

Aaron Digulla
sumber
1

Saya cukup yakin Anda harus mengaitkannya dengan editor apa pun yang digunakan pengguna Anda. Anda bisa menulis sesuatu untuk polling untuk perubahan, tetapi tergantung pada pola penggunaan, frekuensi polling mungkin harus sangat tinggi untuk memastikan itu mengambil perubahan individu daripada beberapa perubahan.

Hank Gay
sumber
Juga, polling untuk perubahan akan menciptakan kondisi balapan.
Bombe
1
Tidak dengan editor seperti emacs dan yi, yang menulis file "secara transaksi" untuk memastikan bahwa data tidak akan hilang setelah crash.
Robin Green
1

Kedengarannya seperti Anda sedang mencari sesuatu yang mirip dengan etckeeper , yang dirancang untuk secara otomatis memeriksa semua perubahan Anda ke / etc / * ke git (atau VCS apa pun yang Anda inginkan), tetapi saya tidak melihat alasan mengapa itu tidak dapat digunakan dengan file selain yang ada di / etc.

Jika Anda hanya ingin berurusan dengan satu file tunggal, mungkin itu tidak akan sempurna, tetapi jika Anda ingin melacak semua yang ada di direktori tertentu, saya pikir ada baiknya memeriksa.

iconoclast
sumber
1

Skrip ini tidak berjalan ketika pengguna mengubah file, tetapi bisa dijalankan sebagai tugas cron (dengan menjatuhkannya ke direktori /etc/cron.*), yang juga merupakan solusi yang masuk akal.

Skrip ini akan mengulangi melalui direktori / srv / www Anda (ubah ke tempat semua situs Anda disimpan), tambahkan, komit, dan dorong semua file, dan catat semuanya ke /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
runningonplants
sumber
0

Ini tidak memuaskan bagian "Idealnya" dari pertanyaan, tetapi ini adalah pertanyaan terdekat yang saya lihat dengan jawaban yang saya inginkan, jadi saya pikir itu bisa masuk ke sini. Posting stackoverflow pertama saya, jadi minta maaf jika saya salah.

Script berikut memastikan komit otomatis pada perubahan diselamatkan, tetapi tidak prompt pengguna untuk melakukan masukan. (Saya menyadari skenario saya sedikit berbeda dengan 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
Fintan
sumber
0

Untuk Windows

Menurut artikel ini tentang autocommit , Anda harus membuat .batfile dengan konten:

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

dan jalankan dengan Task Scheduler. Jika Anda tidak tahu bagaimana melakukan langkah-demi-langkah, lihat artikel itu.

T.Todua
sumber