B u s L o g i c:- prolog, code, chatter.

A simple script to backup remote git repositories

I had a problem where I wanted to mirror a set of git repositories so that the work that I put onto github and other places would not get lost.

A simple script can do this and Prolog is a great scripting language. In fact, in SWI-Prolog there is a library dedicated to doing just these types of task, the achelois library.

In order to achieve the backup, the first thing to do is to clone all of the repositories that I want to keep in sync to a single folder, and set the user/password for each so that we don't have to enter it each time.

Now the script:

First step is to install the pack:

?- pack_install(achelois).

Then the code can be written

First Import the achelois library

:- use_module(library(achelois)).

Then create a predicate that returns folders for the current directory. This script will live in the same directory but is not a folder so all good.

dir_to_update(Dir) :-
        list_files('.', Files),
        member(Dir, Files),
        exists_directory(Dir).

list_files/1 will populate Files as a list of names for all files, but for this task only directories are required. To achieve this, use member to inspect each of the list entries, and test if the entry is a directory. This predicate is backtrackable, and each time it is called, then next directory will be revealed, until no more are left.

Now that the directories can be retieved, loop over all the directories and do a git pull command. achelois has a set of git related predicates that can be used.

update :-
        forall(dir_to_update(Dir),
        (
            format('Updating ~w~n', Dir),
            git_pull(Dir, origin, master)
        )).

This is pretty simple to understand really, and it works!

The last step is to set the update/1 predicate to run when opening the file, then all that needs to be done is double click on the file whenever a sync is required.

:- initialization(update).

Note that this only syncs one way, and is designed for backing up, not updating the remote repository. This could be done, but it wasn't what I was after in this case.