Создание git auto-commit - PullRequest
       93

Создание git auto-commit

142 голосов
/ 07 января 2009

Я бы хотел использовать git для записи всех изменений в файл.

Есть ли способ, которым я могу включить git 'commit', чтобы он происходил автоматически каждый раз, когда файл обновляется - так что для каждого изменения файла есть новый коммит?

В идеале я бы хотел, чтобы мои пользователи даже не знали, что git работает за кулисами. Затем пользователь может потенциально «отменить» изменения в файле - и этого можно добиться, извлекая предыдущую версию из git.

Ответы [ 16 ]

115 голосов
/ 07 января 2009

В Linux вы можете использовать inotifywait для автоматического выполнения команды при каждом изменении содержимого файла.

Редактировать: следующая команда фиксирует файл file.txt, как только он будет сохранен:

inotifywait -q -m -e CLOSE_WRITE --format="git commit -m 'autocommit on change' %w" file.txt | sh
46 голосов
/ 08 июня 2009

Предыдущий ответ inotifywait великолепен, но не является полным решением. Как написано, это одноразовый коммит для одноразового изменения в файле. Это не работает в общем случае, когда редактирование файла создает новый индекс с исходным именем. inotifywait -m , очевидно, следует за файлами по индексу, а не по имени. Кроме того, после изменения файла он не ставится для git commit без git add или git commit -a . Внесение некоторых изменений, вот что я использую в Debian для отслеживания всех изменений в моем файле календаря:

/ и т.д. / rc.local:


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

/ дома / / бен / 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 при изменении файла.

25 голосов
/ 20 октября 2012

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

В результате получается сценарий , который в настоящее время называется gitwatch, так как именно это он и делает: он просматривает файл или папку на предмет изменений (используя inotifywait) и фиксирует их в хранилище git. *

Вы можете найти скрипт, дополнительную информацию и инструкции на github: https://github.com/nevik/gitwatch

16 голосов
/ 07 мая 2010

git-wip - отличное решение, которое мне подходит. «WIP» означает «работа в процессе». Каждый раз, когда вы запускаете 'git wip', изменения фиксируются в отдельной ветке. Его можно запустить из командной строки, но существуют расширения для vim и emacs для автоматического запуска git-wip при каждой записи файла.

11 голосов
/ 22 декабря 2012

Я хотел сделать это в Windows, и обнаружил, что наилучшим способом было бы использовать Directory Monitor для проверки изменений, а затем при обнаружении изменения запустить:

Программа: cmd.exe

Параметры: / C C: \ 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

Мне кажется, это сработало довольно хорошо. Монитор каталогов можно настроить для запуска при запуске и запуска в свернутом виде, а также он может просматривать несколько разных папок

8 голосов
/ 23 ноября 2011
#!/bin/bash
git commit -a -m "autoupdate `date +%F-%T`"
git push

автоматическое выдвижение с текущей датой и временем.

7 голосов
/ 16 октября 2012

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

Существует инструмент под названием incron , который может быть именно тем, что вы ищете. Вы можете указать файлы или папки (и типы событий, такие как «изменить», «создать», «отсоединить») в чем-то вроде crontab и команду для запуска, когда такое событие происходит.

В отличие от inotifywait (который был бы аналогом cron бедняка sleep 10;do stuff), он будет ловить каждое событие, а не только первое.

Я не использовал его сам, но из документации он не выглядит слишком сложным для установки.

7 голосов
/ 04 ноября 2011

Я написал программу GitPrime для автоматического сохранения локальных репозиториев Git. Теперь легко откатиться до того, как вы его разорили! Репозиторий Bitbucket .

Это должно работать на любой платформе, которая поддерживает оболочку bash, включая Windows + Cygwin.

6 голосов
/ 14 октября 2014

В случае, если кто-то попытается сделать это из 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"
3 голосов
/ 14 февраля 2015

Мне нравятся два решения: etckeeper - которые можно адаптировать к пользовательскому каталогу , отличному от /etc:

mkdir /foo
etckeeper -d /foo init`
etckeeper -d /foo commit 'message'

и gitwatch - особенно инструкции как его использовать с supervisord.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...