[Suggestion] Hooked Cleanups with Worktree Locking
While I love this plugin, I think I've found a way to accomplish what it does and have no loose objects (unpacked objects floating around). My issues with git repos in Dropbox involve the desktop client refusing to sync these local refs, which are lots of little files and lots of them change rapidly as you're doing git commands. By running git gc or some flavor of git repack, you can pack all those little files into a few big files that are far more Dropbox-friendly.
I don't particularly need concurrency safety, but I have found a way to guarantee it for repos in shared locations. Simply go to the bare repo (the /path/to/this.git of dropbox:///path/to/this.git that you have as your remote destination), inside the git folder itself (should see HEAD, objects, etc. in this folder). Then run git worktree add ../TEMP which will add a working tree wherever you tell it to (e.g. ../TEMP). If you're not sure what a work tree is, it's what bare repos typically don't have: a place with a working copy of the files. By creating a work tree, you've effectively checked out the main branch, and anyone who tries to push to the main branch will get a warning refusing to update checked-out branch (see git-config receive.denyCurrentBranch). You can do this for any branch by doing git worktree add <LOC> <BRANCH>
So, the idea is, before you push to a shared repo, checkout the branch you want to push to, effectively locking it. Once that syncs, pause your desktop client, remove the worktree git worktree remove <LOC> and push. Anyone who has the main copy of the remote repo synced will see the worktree error, telling them someone has briefly locked the repo for pushing.
So in summary:
- Go to
/your/remote/repo.git - run
git worktree add <branch's temp location> <BRANCH>for every branch you intend to update - Let the desktop client sync and then pause it.
- run
git worktree remove <branch's temp location>for each branch you "checked out" - Push your branch changes
- Optionally run
git gcto clean things up in therepo.git. - Turn your sync back on.
To make the transition even easier, consider adding something like
[url "/path/to/your/Dropbox/"]
insteadOf=dbx:
to your git config (globally for example at ~/.gitconfig). Now, you can simply replace dropbox:/// with dbx:. Useful hack to add any quick shortcut to any path within git! Plus it has the added benefit of if you define the url as necessary for two different machines (say windows D:/Dropbox and Mac /Users/user/LocalStorage/Dropbox/) then paths to repos in your dropbox become OS and platform agnostic!
Final super-hack: automate garbage collection with a hook.
Back in repo.git create a file called hooks/post-receive.sh and paste this in:
#!/bin/bash
# Run git gc
git gc
exit 0
This will run git gc after every push the remote repo receives. This will automatically pack all the loose objects into packfiles, which should happen faster than the Dropbox desktop client can even see the loose objects! Now your desktop client will no longer be littered with added 13/2847089130457916340975123 or deleted 14/13241yiojb2r1i2 etc.!