Plunge is a command-line utility for Windows and Linux that is used to synchronize sets of files. (Don't just sync; Plunge!) It is a native application (written in C), and its only dependency is the C standard library. It is free, open-source software (FOSS), distributed under the MIT License. (In a nutshell, you can do whatever you want with it, so long as it retains the copyright notice.)
Plunge may be thought of as an extremely lightweight, portable version of Rsync. The typical use case is as follows: You have two sets of files that you wish to keep synchronized. One (the source) is the "master" set that you edit regularly and is generally up to date. The other (the destination) is a redundant set (e.g., a backup). From time to time, you'd like to run a command that compares each file in the one set to its counterpart in the other set, detects changes in size and timestamp, and copies each file from the source to the destination as necessary to bring the two sets in sync.
plunge [OPTION]... SOURCE DEST
SOURCE
and DEST
are the full pathnames of the source and destination directories (respectively). Each pathname may or may not end with a path separator (\
or /
). Plunge then reads standard input (stdin) for a list of file pathnames relative to the source and destination directories. When end-of-file (EOF) is reached, each file in SOURCE
is compared with its counterpart in DEST
. If the SOURCE
file is newer than the DEST
file, or if the DEST
file does not exist, the DEST
file is overwritten with the SOURCE
file; otherwise, no action is taken.
-h, --help
-n, --dry-run
-p, --purge
-v, --verbose
Let's say you're developing a QGIS plugin (such as the PipelineML GeoPackager). You might have the following set of files for the GitHub repository:
C:\Users\Jeff\Documents\GitHub\pml-geopackager\__init__.py C:\Users\Jeff\Documents\GitHub\pml-geopackager\algorithm.py C:\Users\Jeff\Documents\GitHub\pml-geopackager\metadata.txt C:\Users\Jeff\Documents\GitHub\pml-geopackager\plugin.py C:\Users\Jeff\Documents\GitHub\pml-geopackager\provider.py C:\Users\Jeff\Documents\GitHub\pml-geopackager\img\icon.svg C:\Users\Jeff\Documents\GitHub\pml-geopackager\img\pml.svg
In order to test the plugin, you need a copy of each of these files in your QGIS plugin path:
C:\Users\Jeff\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\pml_geopackager\__init__.py C:\Users\Jeff\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\pml_geopackager\algorithm.py C:\Users\Jeff\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\pml_geopackager\metadata.txt C:\Users\Jeff\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\pml_geopackager\plugin.py C:\Users\Jeff\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\pml_geopackager\provider.py C:\Users\Jeff\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\pml_geopackager\img\icon.svg C:\Users\Jeff\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\pml_geopackager\img\pml.svg
After making changes to these files, you might run:
plunge -v C:\Users\Jeff\Documents\GitHub\pml-geopackager C:\Users\Jeff\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\pml_geopackager < plunge.txt
The contents of plunge.txt
would be:
__init__.py algorithm.py metadata.txt plugin.py provider.py img/icon.svg img/pml.svg
Typical output might be:
Pathname Status Action -------------------------------------------------- ------------------ ------ __init__.py . . . . . . . . . . . . . . . . . . . . Same age . . . . . . Skip algorithm.py. . . . . . . . . . . . . . . . . . . . Src newer & larger . Copy metadata.txt. . . . . . . . . . . . . . . . . . . . Src newer. . . . . . Copy plugin.py . . . . . . . . . . . . . . . . . . . . . Same age . . . . . . Skip provider.py . . . . . . . . . . . . . . . . . . . . Src newer. . . . . . Copy img\icon.svg. . . . . . . . . . . . . . . . . . . . Dst not found. . . . Copy img\pml.svg . . . . . . . . . . . . . . . . . . . . Dst not found. . . . Copy
Without the verbose (-v
) option, output would be:
Pathname Status ---------------------------------------------------------- ------------------ algorithm.py. . . . . . . . . . . . . . . . . . . . . . . . Newer and larger metadata.txt. . . . . . . . . . . . . . . . . . . . . . . . Newer (not larger) provider.py . . . . . . . . . . . . . . . . . . . . . . . . Newer (not larger) img\icon.svg. . . . . . . . . . . . . . . . . . . . . . . . New img\pml.svg . . . . . . . . . . . . . . . . . . . . . . . . New
Plunge can be downloaded from its GitHub repository, where there are instructions on how to build it from source code.