Skip to content

Instantly share code, notes, and snippets.

@kbdluv
Last active February 9, 2021 18:42
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kbdluv/0ad7effe175e5f52d79078f422eab463 to your computer and use it in GitHub Desktop.
Save kbdluv/0ad7effe175e5f52d79078f422eab463 to your computer and use it in GitHub Desktop.

My bash-fu is laughable and this took me days (yes, days!) to put together, so hope it helps.

It uses fswatch which you should have installed and is supposedly cross-platform, but I've only tested it on MacOS (brew install fswatch).

Dotfile Dropbox git auto-committer

This is my use case:

  • I keep my dotfiles in multiple git repos under ~/Dropbox/dotfiles.
  • I symlink them to wherever they need to be.
  • I want to edit a file, and, as soon as I save it, have it be added and commited to its repo.

Rationale

Naming things is hard, and so is "naming" file changes as commit messages. Often I take a piece of bash config from StackOverflow, and I paste the link to the answer as a comment in the file itself, so it'd be redundant to justify the change in a commit message.

Most of all, I don't want to carefully organize my commits for these things, just have a way to undo screw-ups.

Usage

  • Create a file (let's say, paths.txt) with one path per line of repositories you want to watch and auto-commit.
  • Make sure git-watch.sh and git-commit-unattended.sh are in your PATH. I symlink them to ~/usr/bin/.
  • Call git-watch.sh < /path/to/paths.txt.

Other use cases

Of course you can use this to track changes to any directory, not only one with dotfiles. I also add ~/Dropbox/org to my paths.txt file to keep track of changes to my org-mode files, for instance. It's a life-saver.

This is also not exclusive to Dropbox. It could be a mounted remote filesystem (who uses that?) or a local git repo with a post-commit-hook that pushes it to a remote.

Starting automatically on login

I'm still trying to figure out how to use launchd on MacOS to start this automatically, but it is proving harder than I thought😓. You'll find below my current (non-working) .plist file.

Starting it yourself by calling git-watch-my-paths-on-login.sh works though, so if that's good enough for you, you've got a watcher already!

Saying thanks

If this helped you, I'd love to know about it. Makes me want to share more stuff I patch together for myself. A star on the gist or a fave/RT on Twitter means the world to me 😊

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.user.gitWatchMyPathsOnLogin</string>
<key>ProgramArguments</key>
<array><string>/Users/kbdluv/Dropbox/dotfiles/scripts/git-watch-my-paths-on-login.sh</string></array>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/com.user.gitWatchMyPathsOnLogin.out</string>
<key>StandardErrorPath</key>
<string>/tmp/com.user.gitWatchMyPathsOnLogin.err</string>
</dict>
</plist>
#!/bin/bash
cd "$1" && git add . && git commit -m "unattended"
#!/bin/bash
# Exporting PATH here is because launchd doesn't pick it up from .bash_profile/.bashrc.
# Change these two paths below with the path where you added `git-commit-unattended.sh`
# and `git-watch.sh` and the one where you keep the paths of repositories you want to
# watch.
export PATH="$HOME/usr/bin:$PATH"
git-watch.sh < /Users/kbdluv/Dropbox/dotfiles/git-watch-paths.txt
#!/bin/bash
# PATH for launchd to find `fswatch`
export PATH="/usr/local/bin:$PATH"
while read -r line; do
{
fswatch -r "$line" | grep --line-buffered -v '.git' | xargs -n1 -I{} git-commit-unattended.sh "$line";
} &
done
@glassdimly
Copy link

Very helpful, thanks! I was trying to modify https://github.com/gitwatch/gitwatch to work on mac, but it's a little over-complicated.

@glassdimly
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment