Здійснення автоматичної передачі git


155

Я хотів би використовувати git для запису всіх змін у файл.

Чи є спосіб я ввімкнути git 'commit', щоб це автоматично відбувалося кожного разу, коли файл оновлюється - тож є нова фіксація для кожної зміни файлу?

В ідеалі я хотів би, щоб мої користувачі навіть не знали, що git працює за кадром. Потім користувач може потенційно "скасувати" зміни у файлі - і цього можна досягти, витягнувши попередню версію з git.


9
Простіше буде використовувати файлову систему версій: en.wikipedia.org/wiki/Versioning_file_system
William Pursell

1
SparkleShare на це був досить вражаючим.
Теода

SparkleShare виглядає чудовим варіантом, але він знищує будь-яку папку .git всередині основного git
введіть

Ви можете використовувати github.com/jw0k/gwatch . Він працює в Windows та Linux.
rubix_addict

@rubix_addict Чому ви не опублікували це як відповідь?
Тобіас Кіенцлер

Відповіді:


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, які воно може встановити. man inotifywaitрозповім більше.
JesperE

14
чи є варіант у windows ..?
Чандан Пасунорі

50

Раніше відповідь inotifywait чудова, але це не зовсім повне рішення. Як було написано, це одноразовий вчинок для одноразової зміни файлу. Це не працює для загального випадку, коли редагування файлу створює новий inode з оригінальним іменем. inotifywait -m, мабуть, слідкує за файлами inode, а не за іменем. Крім того, після зміни файлу він не ставиться для git počin без додавання git або git commit -a . Внесення деяких коригувань, ось що я використовую на Debian для відстеження всіх змін у моєму календарі файлів:

/etc/rc.local:


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

/ home / <ім'я користувача> / 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
Лестер, можете, будь ласка, розширити, як узагальнити це до каталогу?
Дієго

29

Попередні відповіді, в яких рекомендували inotifywait для цієї роботи, підказали мені в правильному напрямку, коли у мене була сама проблема, тому я написав невеликий сценарій. Спочатку це могло дивитись лише цілі папки рекурсивно (навпаки прикладу Лестера Бака), але потім я також хотів переглянути файл десь в іншому місці, тому розширив його.

Результатом цього є сценарій, який в даний час називається gitwatch, як це робиться: він переглядає файл або папку для змін (використовуючи inotifywait) і передає їх у сховище git.

Ви можете знайти сценарій, додаткову інформацію та інструкції на сайті github: https://github.com/nevik/gitwatch


4
корисний маленький сценарій там. Я заноту це.
iwein

цікаве може бути корисним для сайтів магенто. Я тестую це, але, здається, не можу змусити його автоматично натискати
NoSixties

16

git-wip - це чудове рішення, яке добре працює для мене. "WIP" означає "незавершене виробництво". Щоразу, коли ви запускаєте "git wip", зміни вносяться в окрему гілку. Його можна запустити в командному рядку, але є розширення для vim та emacs для автоматичного запуску git-wip кожного разу, коли файл записується.


12

Я хотів це зробити у Windows, і я знайшов найкращий спосіб - використовувати Monitor Monitor для перевірки змін, а потім, коли він виявив зміни, чи запустіть:

Програма: 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 *.*"), але я не думаю, що я працював належним чином.

Я також зробив гачок після збору, що містить:

#!/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";
}
?>

Єдина проблема з цим полягала в тому, що він повинен був запускатися користувачем root замість користувача apache, тому я також повинен був створити файл, /etc/sudoers.d/що містить:

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

Для мене я думаю, що це спрацювало досить солідно. Монітор каталогів може бути налаштований для запуску і запуску мінімізований, і він може переглядати кілька різних папок


Також у Windows я не можу запустити git запускатись під LocalSystem, тому, якщо ви створите власну службу моніторингу, вам доведеться запускати її під користувачем, який фактично може запускати Git. Можливо, мені просто не вистачає деяких налаштувань / конфігурацій, але, мабуть, приємніше все-таки створити новий обліковий запис git-
комітету

8
#!/bin/bash
git commit -a -m "autoupdate `date +%F-%T`"
git push

автоматичне натискання на поточну дату та час.


8

Повідомлення дійсно звучить як правильний інструмент для роботи.

Є інструмент під назвою incron, який може бути саме тим, що ви шукаєте. Ви можете вказати файли або папки (і типи подій, такі як "змінити", "створити", "відключити") щось на зразок crontab, і команду, яку потрібно запустити, коли така подія відбувається.

На відміну від inotifywait (який був би аналогом хрону бідної людини sleep 10;do stuff), це охопить кожну подію, не лише першу.

Я сам не користувався цим, але з документації він не виглядає надто складним для налаштування.


7

Я написав програму GitPrime для надання автоматичного збереження для ваших локальних сховищ Git. Тепер легко відкотитись до того, як ви його розбили! Сховище Bitbucket .

Це має працювати на будь-якій платформі, яка підтримує bash shell, включаючи Windows + Cygwin.


+1 Я використовую це у Windows (CygWin) для автоматичного збереження змін, які я вношу у сховище git-tf кожні 10 хвилин, використовуючи заплановане завдання
Дарбіо,

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 просто поскаржиться, і вам доведеться ігнорувати цю помилку, окрім цього, корупції не буде.

На додаток до цього, ви хочете позначити ці файли як "автоматичні фіксації", щоб також можна було вчинити вручну. Таким чином, користувач може бачити автоматичні зміни, а також більші "логічні" зміни, які супроводжуються коментарями виконувати, щоб пояснити, що змінилося з моменту останньої вручної фіксації.

Наприклад, використовуйте "AUTOCOMMIT" як повідомлення про фіксацію. Пізніше ви можете написати інструмент для очищення цих комітетів за допомогою журналу git (щоб з’ясувати редакції для вбивства), або ви можете спробувати створити гілку AUTOCOMMIT, використовуючи стратегію вирішення зіткнення грубої сили, щоб забити «ручні коміти».

Інший варіант - використовувати команди git низького рівня для створення власного спеціалізованого сховища.

Нарешті, ви можете скопіювати файл до нового імені ("$ filename.ac"), виконуючи автоматичні зобов'язання, щоб розрізняти ручну та автоматичну версії.


1

Я впевнений, що вам потрібно підключити це до будь-якого редактора, який користуються ваші користувачі. Ви можете написати щось для опитування змін, але залежно від моделей використання частота опитування може бути неймовірно високою, щоб переконатися, що вона збирає окремі зміни замість кількох змін.


Крім того, опитування змін призведе до створення перегонових умов.
Bombe

1
Не з такими редакторами, як emacs і yi, які пишуть файли "транзакційно", щоб намагатися гарантувати, що дані не будуть втрачені після збоїв.
Робін Грін

1

Це здається, що ви шукаєте щось подібне до etckeeper , який призначений для автоматичної перевірки всіх ваших змін на / etc / * в git (або будь-який VCS, який ви хочете), але я не бачу причини, щоб його не можна було використовувати з файлами крім тих, що в / і т.д.

Якщо ви хочете мати справу лише з одним файлом, можливо, це не було б ідеально, але якщо ви хочете відслідковувати все в даному каталозі, я думаю, що це варто перевірити.


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 startd пропонує вам чудове рішення. він перегляне файл або каталог, і якщо є зміни, ви можете запустити додаток або щось інше ...


Див. "Моніторинг каталогу" тут: developer.apple.com/library/mac/#documentation/MacOSX/…
Kris


0

Це не задовольняє "ідеально" частини запитання, але це було найближче питання, яке я побачив до відповіді, яку я хотів, тому я зрозумів, що це може піти сюди. Хоча мій перший пост stackoverflow, тож вибачте, якщо помиляюсь.

Наведений нижче сценарій забезпечує автоматичні фіксації збережених змін, але не спонукає користувача до введення даних. (Я розумію, що мій сценарій трохи відрізняється від 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. Якщо ви не знаєте, як це зробити покроково, перегляньте цю статтю.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.