Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making git auto-commit

Tags:

git

People also ask

What is git auto commit?

Automatically commits files which have been changed during the workflow run and push changes back to remote repository.

Does git automatically create commits?

It's called git-auto-commit. Once changes are detected, those are committed and pushed back to the GitHub repo. Some of the best products and services are built because that person had a need.

Can we automate git push?

Yes! you heard it right. One bash command can push entire repository from you local machine to github.


On Linux you could use inotifywait to automatically execute a command every time a file's content is changed.

Edit: the following command commits file.txt as soon as it is saved:

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

The earlier inotifywait answer is great, but it isn't quite a complete solution. As written, it is a one shot commit for a one time change in a file. It does not work for the common case where editing a file creates a new inode with the original name. inotifywait -m apparently follows files by inode, not by name. Also, after the file has changed, it is not staged for git commit without git add or git commit -a. Making some adjustments, here is what I am using on Debian to track all changes to my calendar file:

/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

This could be generalized to wait on a list of files and/or directories, and the corresponding inotifywait processes, and restart each inotifywait as a file is changed.


The previous answers recommending inotifywait for this job tipped me off in the right direction when I had this problem myself, so I wrote a little script. First this could only watch whole folders recursively (the opposite of Lester Buck's example), but then I also wanted to watch a file somewhere else, so I expanded it.

The result is a script currently called gitwatch, as that is what it does: it watches a file or folder for changes (using inotifywait), and commits them to a git repository.

You can find the script, more info and instructions over on github: https://github.com/nevik/gitwatch


git-wip is a great solution that works well for me. "WIP" stands for "work in progress". Every time you run 'git wip', the changes are commited to a separate branch. It can be run on the command line, but there are extensions for vim and emacs to automatically run git-wip each time a file is written.


I wanted to do this in windows, and found the best way was to use Directory Monitor to check for changes then when it detected a change have it run:

Program: cmd.exe

Params: /C C:\pathToBatchFile.bat

That batch file contained:

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

I also tried having another command in there to add files ("%PROGRAMFILES(X86)%\git\bin\sh.exe" --login -i -c "git add *.*"), but I don't think I got that working properly.

I also made a post-commit hook containing:

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

(If there were any conflicts then it would abort the pull and abort the push, but there wasn't any clear way to tell that had happened - in the end we abandoned the whole idea because of this one flaw.)

That curl command told my server that it needed to do a pull on the code. All that was needed to handle it in php was:

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

The only problem with that was it needed to be run by the root user instead of the apache user, so I also had to make a file in /etc/sudoers.d/ containing:

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

For me, I think that worked pretty solidly. Directory Monitor can be configured to run on startup and start minimized, and it can watch several different folders