nogit: Using git to track files without the user using git Summary ======= Let's see, nogit is a very simple tool that uses git under the hood to allow for collaboration on files, but without requiring the collaborators to invoke git commands. Any time a user might invoke "git commit", or "git push", or "git pull", etc. the user instead just invokes "nogit sync". And the user will not be prompted to fill out a commit message or to resolve conflicts, etc. This is not intended as an alternative to git. If you're already using git, please continue to do so, (creating clean code history with detailed commit messages, etc.). Instead, nogit is intended for text files that you otherwise wouldn't have even put into git. And specifically, it's only suitable for text files where a naive "union merge" is the right thing. To be precise, a nogit merge will always silently give you "both sides" of any merge conflict, and will not provide any conflict markers, (it won't even indicate that any conflict happened). It also won't give any predictable behavior on the ordering of lines in cases like this. So if your data isn't safe against that kind of corruption, then you'll probably not want to use it with nogit. The original data for which nogit was invented for was a simple TODO list where different people were adding items they wanted to work on, then removing them when they completed them. These people wanted to keep each other informed about their activities, so they wanted to share items in a single file. But there was no functional significance to the order of items. Finally, it was unlikely that two people would edit any one item in two different ways, (and even if they did it would be trivial and painless to sort this out after the fact). Installation ============ The nogit implementation is a simple bash script named "nogit". To install it, simply copy it to a directory on your PATH. Or, if you'd like to be able to follow along with nogit changes from a git repository, you might create a symlink from a directory on your PATH to the nogit script in the git repostiory. Usage ===== Presumably, you've been pointed to a repository which is intended to be used with nogit. These repositories are often paired with a "parent" repository that is being tracked with git. If so, the procedure for cloning should look something like this: git clone /url/of/parent cd parent nogit clone /url/of/nogit/child And after that, you can run "nogit sync" whenever convenient, (when you've made changes or you think there might be upstream changes to the files being tracked in the nogit repository). Note that "nogit sync" should not ever ask for user input, so it's appropriate to call "nogit sync" from an autoamted system, (such as a text editor's hook when saving a file). Integration with emacs ====================== If you're an emacs user, here is some code you could put into your .emacs file to have "nogit sync" called automatically for you for any nogit-controlled files whenever you open one, begin editing it, or save it: ; Run "nogit sync" if there is a .noggit directory here. ; ; Note: There is an important protection built into this implementation: ; ; We bind 'in-nogit-sync and test whether it's bound to avoid ; infinite recursion. This could otherwise come about because ; the revert-buffer function could trigger the find-file-hook ; and recurse. (defun nogit-sync-if-configured () (interactive) (save-match-data (if (and (buffer-file-name) (file-exists-p (format "%s/../.nogit" (buffer-file-name))) (not (boundp 'in-nogit-sync)) ) (let ((in-nogit-sync t)) (message (substring (shell-command-to-string "nogit sync") 0 -1)) (revert-buffer nil t) ) ) ) ) ; Arrange to run "nogit sync" when the user loads a nogit-controlled file, ; starts editing it for the first time, or saves it. (add-hook 'find-file-hook 'nogit-sync-if-configured) (add-hook 'first-change-hook 'nogit-sync-if-configured) (add-hook 'after-save-hook 'nogit-sync-if-configured) Preparing git repositories for use with nogit ============================================= If you're interested in setting up a parent and child repository for use with nogit, there's almost nothing to it. In the child repository, just put all of the files you want to be treated with nogit's semantics. You don't need to fiddle with any .gitattributes or merge=union configuration. The nogit clone will do everything necessary for you so you get those semantics. Then, in the parent repository, you'll simply want to augment your .gitignore file to ignore all nogit-managed files from the child repository as well as the ".nogit" directory itself. Motivation ========== I originally came up with nogit when I started maintaining a simple TODO file for a project which had a code implementation split across multiple code repositories. I was intentionally keeping my TODO file outside of revision control to be lightweight in a couple of ways: 1. Many TODO items required implementing a feature in multiple repositories (both client and server, say), so having a separate TODO file meant I didn't need to decide which repository to add the TODO file to. And I also didn't need to add the same entriy to TODO files in each of multiple repositories. 2. TODO items are self-descriptive. Any commit message I might have written when adding a TODO item would be adequate as "Add " and similarly for "Remove " so there's inherently no advantage to commit messages for these changes. Of course, a significant disadvantage of my approach was that my TODO file was totally private. I was missing out on the collaborative features that git provides. So, nogit was conceived of as a way to keep my lightweight process of maintaining the TODO file, (simply editing the file and doing nothing more), while also allowing for distributed editing of the file.