Making git auto-commit

Viewed 102177

I'd like to use git to record all the changes to a file.

Is there a way I can turn git 'commit' on to automatically happen every time a file is updated - so there is a new commit for every change to a file?

Ideally I'd like my users to not even know that git is running behind the scenes. A user could then potentially "undo" changes to a file - and this could be achieved by pulling a previous version out of git.

21 Answers

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.

If you know the name of the file and you want to monitor only one (or a few files), you can simply call "git commit" every few minutes to achieve this. If the file hasn't changed, git will just complain and you'll have to ignore this error but other than that, there will be no corruption.

In addition to that, you'll want to mark these files as "auto commit" in order to be able to commit manually as well. This way, the user can see the automatic changes and also the bigger "logical" changes which are accompanied by commit comments to explain that has changed since the last manual commit.

For example, use "AUTOCOMMIT" as the commit message. Later, you can write a tool to purge these commits using git log (to find out the revisions to kill) or you can try to create a branch AUTOCOMMIT using a brute force collision resolve strategy to hammer in the "manual commits".

Another option is to use the git low-level commands to build your own specialized repository.

Lastly, you could copy the file to a new name ("$filename.ac") while doing auto commits to distinguish between the manual and automatic versions.

For Windows

According to this article about autocommit, you shou create .bat file with content:

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

and execute with Task Scheduler. If you don't know how to do step-by-step, refer that article.

I'm pretty sure you'd need to hook that into whatever editor your users are using. You could write something to poll for changes, but depending on usage patterns, the polling frequency might need to be incredibly high to make sure it was picking up individual changes instead of multiple changes.

i had the same problem and on mac launchd provides you with a great solution. it will watch a file or a directory and if there are changes you can run an app or anything else...

This does not satisfy the "Ideally" part of the question, but this was the closest question I saw to the answer I wanted, so I figured it could go here. My first stackoverflow post though, so apologies if I'm mistaken.

The following script ensures automatic commits on saved changes, but does prompt the user for commit input. (I realise my scenario is a little different to git-noob's).


# 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

There are several alternatives:

  • There is git-etc for committing changes automatically on predefined interval of time.
  • Also there is a watchman
  • And gitwatch
  • git file (autocommit.sh)

    • `git add .
       git commit -am "auto commit"
       git push`
      
  • batch file (*.bat)

    • %windir%\system32\CMD.exe /k git-bash.exe c:/yourapp/autocommit.sh
  • windows Task Scheduler

    • create task

for me it works hope it will help some

A more modern take on the inotifywait approach is to use entr. You can do something simple like:

find . | entr git commit -avm "msg"

which will automatically commit any change that you make to files known to git.

Related