f236b1448aa532fb26190df40026e24280b1a75e
[gregoa/movein.git] / movein
1 #!/bin/sh
2 #
3 # Copyright © 2008 Mike O'Connor <stew@vireo.org>
4 #
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2, or (at your option) any
8 # later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 # USA.  
19
20
21 set -e
22
23 usage() {
24     bn=$(basename $0)
25     cat <<EOF
26 $0: manage home directory using mr
27
28 NAME
29   $bn - a command to manage detached git repositories using mr
30
31 SYNOPSIS
32   $bn command [options]
33
34   $bn init
35   $bn ls
36   $bn list
37   $bn ls-r
38   $bn list-remote
39   $bn add repository_name
40   $bn new repository_name file1 [file2 file3...]
41   $bn login repository_name
42   $bn exec repository_name command [arg1 arg2...]
43
44 COMMANDS
45   init 
46       create ~/.moveinrc, create/update  ~/.mrconfig
47
48   ls
49   list
50       show a list of local repositories
51
52   ls-r
53   list-remote
54       show a list of remote repositories
55
56   add repository_name
57       checkout the repository from the remote host and add it to
58       mr's configuration
59
60   new repository_name file1 [file2 file3...]  
61       create a new repository on the remote host, and checkin the
62       listed files to the new repository.   Add the new repository
63       to mr's configuration
64
65   login repository_name
66       start a subshell in repository_name
67
68   exec repository_name command [arg1 arg2...]
69       execute a command in the context of repository_name, for example:
70         $bn exec myrepo git status
71         $bn exec myrepo git ls-files
72
73 EOF
74
75     exit 1
76 }
77
78 [ $# -ge 1 ] || usage
79
80 GIT_HOST=git.vireo.org
81 REMOTE_REPOS=~/git
82 LOCAL_REPOS=~/.movein
83 MRCONFIG=~/.mrconfig
84 MOVEINRC=~/.moveinrc
85
86 [ -e "$MOVEINRC" ] && . "$MOVEINRC"
87
88 init() {
89
90     if [ $# -ne 0 ]; then 
91         usage
92     fi
93     
94     if [ -e $MOVEINRC ]; then
95         echo $MOVEINRC already exists
96         exit 1
97     fi
98
99     echo -n "git server hostname? [git.vireo.org] " 
100     read GIT_HOST
101     if [ -z "$GIT_HOST" ]; then 
102         GIT_HOST=git.vireo.org
103     fi
104
105     echo -n "path to remote repositories? [~/git] " 
106     read REMOTE_REPOS
107     if [ -z "$REMOTE_REPOS" ]; then 
108         REMOTE_REPOS=~/git
109     fi
110
111     echo -n "Local repository directory? [~/.movein] " 
112     read LOCAL_REPOS
113     if [ -z "$LOCAL_REPOS" ]; then 
114         LOCAL_REPOS=~/.movein
115     fi
116
117     echo -n "Location of .mrconfig file? [~/.mrconfig] " 
118     read MRCONFIG
119     if [ -z "$MRCONFIG" ]; then 
120         MRCONFIG=~/.mrconfig
121     fi
122
123     cat <<EOF > $MOVEINRC
124 GIT_HOST=$GIT_HOST
125 REMOTE_REPOS=$REMOTE_REPOS
126 LOCAL_REPOS=$LOCAL_REPOS
127 MRCONFIG=$MRCONFIG
128 EOF
129
130     if [ ! -d "$LOCAL_REPOS" ]; then 
131         mkdir -p "$LOCAL_REPOS"
132     fi
133
134     mr -c "$MRCONFIG" config DEFAULT include="cat /usr/share/mr/git-fake-bare"
135     
136 }
137
138 login() {
139     if [ $# -ne 1 ]; then 
140         usage
141     fi
142
143     export GIT_DIR="$LOCAL_REPOS/${1}.git"
144     export GIT_WORK_TREE="$GIT_DIR/$(git config --get core.worktree)"
145
146     GIT_PS1_SHOWUNTRACKEDFILES= PSMOVEIN="movein:${1}" $SHELL -i || :
147 }
148
149 execin() {
150     local REPO
151     if [ $# -lt 1 ]; then
152         usage
153     fi
154
155     REPO=$1;shift
156
157     export GIT_DIR="$LOCAL_REPOS/${REPO}.git"
158     export GIT_WORK_TREE="$GIT_DIR/$(git config --get core.worktree)"
159
160     "$@"
161 }
162
163 add() {
164     if [ $# -ne 1 ]; then 
165         usage
166     fi
167     REPO_NAME=$1.git ; shift
168     LOCAL_REPO=$LOCAL_REPOS/$REPO_NAME
169     REPO_URL=ssh://$GIT_HOST/$REMOTE_REPOS/$REPO_NAME
170
171     if [ -e "$LOCAL_REPO" ]; then
172         echo $LOCAL_REPO already exists
173         exit 1
174     else
175         trap "rm -rf $LOCAL_REPO" 0
176         mkdir "$LOCAL_REPO"
177         export GIT_DIR="$LOCAL_REPO"
178         git init --bare
179         git remote add origin $REPO_URL
180         git config branch.master.remote origin
181         git config branch.master.merge refs/heads/master
182         git config core.bare false
183         git config core.worktree ../../
184         git config status.showUntrackedFiles no
185         GIT_WORK_TREE="$LOCAL_REPO/../../" git pull
186         trap - 0
187
188         mr -c "$MRCONFIG" config "$LOCAL_REPO" checkout="git_fake_bare_checkout '$REPO_URL' 'REPO_NAME' '../../'"
189     fi
190 }
191
192 list() {
193     find "${LOCAL_REPOS}" -mindepth 1 -maxdepth 1 -type d | sed 's,^.*/\([^/]*\).git$,\1,'
194 }
195
196 listremote() {
197     ssh $GIT_HOST "
198         find '${REMOTE_REPOS}' -mindepth 1 -maxdepth 1 -type d | sed 's,^.*/\([^/]*\).git$,\1,'
199     " </dev/null
200 }
201
202 new() {
203     if [ $# -lt 2 ]; then 
204         usage
205     fi
206     REPO_NAME=$1.git ; shift
207     LOCAL_REPO="$LOCAL_REPOS/$REPO_NAME"
208     REPO_URL="ssh://$GIT_HOST/$REMOTE_REPOS/$REPO_NAME"
209
210     if [ ! -e "$1" ]; then
211         echo $1 not found
212         exit 1
213     fi
214
215     if [ -e "$LOCAL_REPO" ]; then
216         echo $LOCAL_REPO already exists
217         exit 1
218     else
219         trap "rm -rf $LOCAL_REPO" 0
220         mkdir -p "$LOCAL_REPO"
221
222         ssh $GIT_HOST "
223                GIT_DIR=$REMOTE_REPOS/$REPO_NAME git --bare init
224         " </dev/null
225
226         export GIT_DIR="$LOCAL_REPO"
227         git init --bare
228         git remote add origin $REPO_URL
229         git config branch.master.remote origin
230         git config branch.master.merge refs/heads/master
231         git config core.bare false
232         git config core.worktree ../../
233         git config status.showUntrackedFiles no
234         export GIT_WORK_TREE="$LOCAL_REPO/../../"
235         git add "$@"
236         git commit -m "initial checkin"
237         git push --all
238         
239         trap - 0
240
241         mr -c "$MRCONFIG" config "$LOCAL_REPO" checkout="git_fake_bare_checkout '$REPO_URL' 'REPO_NAME' '../../'"
242     fi
243
244 }
245
246
247 command=$1 ; shift
248 case "$command" in 
249     init)
250         init $@
251         ;;
252     add)
253         add $@
254         ;;
255     new)
256         new $@
257         ;;
258     login)
259         login $@
260         ;;
261     exec)
262         execin "$@"
263         ;;
264     ls)
265         list
266         ;;
267     list)
268         list
269         ;;
270     ls-r)
271         listremote
272         ;;
273     list-remote)
274         listremote
275         ;;
276
277     *)
278         usage
279         exit 1
280         ;;
281 esac