better error handling (thanks Joseph Liu)
[gregoa/movein.git] / README
1 movein - a script to help maintain a direcotry with multiple overlayed
2 git repositories.
3
4 The latest version should be avaliable from http://stew.vireo.org/movein
5
6 My goal has been to keep my home directory in a version control system
7 effectively.  I have a number of constraints however.  I want the
8 system to be modular.  I don't always need X related config files in
9 my home directory.  Sometimes I want just my zsh related files and my
10 emacs related files.  I have multiple machines I check email from, and
11 on those want to keep my notmuch/offlineimap files in sync, but I
12 don't need these on every machine I'm on, expecially since those
13 configurations have more sensitive data.  I played around with
14 [laysvn](http://laysvn.alioth.debian.org/) for a while, but it never
15 really seemed comfortable.  I more recently discovered that
16 [madduck](http://madduck.net/) had started a
17 "[vcs-home](http://vcs-home.madduck.net/)" website and mailing list,
18 talking about doing what I'm trying to do.
19
20 I'm now going with madduck's idea of using git with detached work
21 trees, so that I can have multiple git repositories all using $HOME as
22 their $GIT_WORK_TREE.  I have a script inspired by his
23 [vcsh](http://git.madduck.net/v/etc/zsh.git?a=blob;f=.zsh/func/vcsh;hb=HEAD)
24 script that will create a subshell where the GIT_DIR, GIT_WORK_TREE
25 variables are set for me.  I can do my git operations related to just
26 one git repository in that shell, while still operating directly on my
27 config files in $HOME, and avoiding any kind of nasty symlinking or
28 hardlinking.  Since I am usually using my script to allow me to
29 quickly "move in" to a new host, I named my script "movein".  It can
30 be found [here](http://git.vireo.org/movein.git/).  Here's how I'll
31 typically use it:
32
33
34             stew@guppy:~$ movein init
35             git server hostname? git.vireo.org
36             path to remote repositories? [~/git] 
37             Local repository directory? [~/.movein] 
38             Location of .mrconfig file? [~/.mrconfig] 
39             stew@guppy:~$ 
40         
41 This is just run once.  It asks me questions about how to setup the
42 'movein' environment.  Now I should have a .moveinrc storing the
43 answers I gave above, I have a stub of a .mrconfig, and an empty
44 .movein directory.  Next thing to do is to add some of my
45 repositories.  The one I typically add on all machines is my "shell"
46 repository.  It has a .bashrc/.zshrc, an .alias that both source and
47 other zsh goodies I'll generally wish to be around:
48
49             stew@guppy:~$ ls .zshrc
50             ls: cannot access .zshrc: No such file or directory
51             stew@guppy:~$ movein add shell
52             Initialized empty Git repository in /home/stew/.movein/shell.git/
53             remote: Counting objects: 42, done.
54             remote: Compressing objects: 100% (39/39), done.
55             remote: Total 42 (delta 18), reused 0 (delta 0)
56             Unpacking objects: 100% (42/42), done.
57             From ssh://git.vireo.org//home/stew/git/shell
58              * [new branch]      master     -> origin/master
59             stew@guppy:~$ ls .zshrc
60             .zshrc
61         
62 So what happened here is that the ssh://git.vireo.org/~/git/shell.git
63 repository was cloned with GIT_WORK_TREE=~ and
64 GIT_DIR=.movein/shell.git.  My .zshrc (along with a bunch of other
65 files) has appeared. Next perhaps I'll add my emacs config files:
66
67             stew@guppy:~$ movein add emacs       
68             Initialized empty Git repository in /home/stew/.movein/emacs.git/
69             remote: Counting objects: 77, done.
70             remote: Compressing objects: 100% (63/63), done.
71             remote: Total 77 (delta 10), reused 0 (delta 0)
72             Unpacking objects: 100% (77/77), done.
73             From ssh://git.vireo.org//home/stew/git/emacs
74              * [new branch]      emacs21    -> origin/emacs21
75              * [new branch]      master     -> origin/master
76             stew@guppy:~$ ls .emacs
77             .emacs
78             stew@guppy:~$ 
79         
80 My remote repositry has a master branch, but also has an emacs21
81 branch, which I can use when checking out on older machines which
82 don't yet have newer versions of emacs.
83
84 Let's say I have made changes to my .zshrc file, and I want to check
85 them in.  Since we are working with detached work trees, git can't
86 immediately help us:
87
88             stew@guppy:~$ git status
89             fatal: Not a git repository (or any of the parent directories): .git
90
91 The movein script allows me to "login" to one of the repositories.  It
92 will create a subshell with GIT_WORK_TREE and GIT_DIR set.  In that
93 subshell, git operations operate as one might expect:
94
95             stew@guppy:~ $ movein login shell
96             stew@guppy:~ (shell:master>*) $ echo >> .zshrc
97             stew@guppy:~ (shell:master>*) $ git add .zshrc                                       
98             stew@guppy:~ (shell:master>*) $ git commit -m "adding a newline to the end of .zshrc"
99             [master 81b7311] adding a newline to the end of .zshrc
100              1 files changed, 1 insertions(+), 0 deletions(-)
101             stew@guppy:~ (shell:master>*) $ git push
102             Counting objects: 8, done.
103             Delta compression using up to 2 threads.
104             Compressing objects: 100% (6/6), done.
105             Writing objects: 100% (6/6), 546 bytes, done.
106             Total 6 (delta 4), reused 0 (delta 0)
107             To ssh://git.vireo.org//home/stew/git/shell.git
108                d24bf2d..81b7311  master -> master
109             stew@guppy:~ (shell:master*) $ exit
110             stew@guppy:~ $ 
111
112 If I want to create a brand new repository from files in my home directory.  I can:
113
114             stew@guppy:~ $ touch methere
115             stew@guppy:~ $ touch mealsothere
116             stew@guppy:~ $ movein new oohlala methere mealsothere
117             Initialized empty Git repository in /home/stew/git/oohlala.git/
118             Initialized empty Git repository in /home/stew/.movein/oohlala.git/
119             [master (root-commit) 7abe5ba] initial checkin
120              0 files changed, 0 insertions(+), 0 deletions(-)
121              create mode 100644 mealsothere
122              create mode 100644 methere
123             Counting objects: 3, done.
124             Delta compression using up to 2 threads.
125             Compressing objects: 100% (2/2), done.
126             Writing objects: 100% (3/3), 224 bytes, done.
127             Total 3 (delta 0), reused 0 (delta 0)
128             To ssh://git.vireo.org//home/stew/git/oohlala.git
129              * [new branch]      master -> master
130             
131 Above, the command <code>movein new oohlala methere mealsothere</code>
132 says "create a new repository containing two files: methere,
133 mealsothere".  A bare repository is created on the remote machine, a
134 repository is created in the .movein directory, the files are
135 committed, and the new commit is pushed to the remote repository.  New
136 on some other machine, I could run <code>movein add oohlala</code> to get these
137 two new files.
138
139 The movein script maintains a .mrconfig file, so that joeyh's
140 [mr](http://kitenet.net/~joey/code/mr/) tool can be used to manage the repositories in bulk.  Commands
141 like "mr update", "mr commit", "mr push" will act on all the known
142 repositories.  Here's an example:
143
144             stew@guppy:~ $ cat .mrconfig
145             [DEFAULT]
146             include = cat /usr/share/mr/git-fake-bare
147             
148             [/home/stew/.movein/emacs.git]
149             checkout = git_fake_bare_checkout 'ssh://git.vireo.org//home/stew/git/emacs.git' 'emacs.git' '../../'
150             
151             [/home/stew/.movein/shell.git]
152             checkout = git_fake_bare_checkout 'ssh://git.vireo.org//home/stew/git/shell.git' 'shell.git' '../../'
153             
154             [/home/stew/.movein/oohlala.git]
155             checkout = git_fake_bare_checkout 'ssh://git.vireo.org//home/stew/git/oohlala.git' 'oohlala.git' '../../'
156
157             stew@guppy:~ $ mr update
158             mr update: /home/stew//home/stew/.movein/emacs.git
159             From ssh://git.vireo.org//home/stew/git/emacs
160              * branch            master     -> FETCH_HEAD
161             Already up-to-date.
162             
163             mr update: /home/stew//home/stew/.movein/oohlala.git
164             From ssh://git.vireo.org//home/stew/git/oohlala
165              * branch            master     -> FETCH_HEAD
166             Already up-to-date.
167             
168             mr update: /home/stew//home/stew/.movein/shell.git
169             From ssh://git.vireo.org//home/stew/git/shell
170              * branch            master     -> FETCH_HEAD
171             Already up-to-date.
172             
173             mr update: finished (3 ok)
174             stew@guppy:~ $ mr update        
175
176 There are still issues I'd like to address.  The big one in my mind is
177 that there is no .gitignore.  So when you "movein login
178 somerepository" then run "git status", It tells you about hundreds of
179 untracked files in your home directory.  Ideally, I just want to know
180 about the files which are already associated with the repository I'm
181 logged into.