Check that mr is installed before using it
[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     if ! which mr > /dev/null; then
100         echo '"mr" not found in the PATH'
101         exit 1
102     fi
103
104     echo -n "git server hostname? [git.vireo.org] " 
105     read GIT_HOST
106     if [ -z "$GIT_HOST" ]; then 
107         GIT_HOST=git.vireo.org
108     fi
109
110     echo -n "path to remote repositories? [~/git] " 
111     read REMOTE_REPOS
112     if [ -z "$REMOTE_REPOS" ]; then 
113         REMOTE_REPOS=~/git
114     fi
115
116     echo -n "Local repository directory? [~/.movein] " 
117     read LOCAL_REPOS
118     if [ -z "$LOCAL_REPOS" ]; then 
119         LOCAL_REPOS=~/.movein
120     fi
121
122     echo -n "Location of .mrconfig file? [~/.mrconfig] " 
123     read MRCONFIG
124     if [ -z "$MRCONFIG" ]; then 
125         MRCONFIG=~/.mrconfig
126     fi
127
128     cat <<EOF > $MOVEINRC
129 GIT_HOST=$GIT_HOST
130 REMOTE_REPOS=$REMOTE_REPOS
131 LOCAL_REPOS=$LOCAL_REPOS
132 MRCONFIG=$MRCONFIG
133 EOF
134
135     if [ ! -d "$LOCAL_REPOS" ]; then 
136         mkdir -p "$LOCAL_REPOS"
137     fi
138
139     mr -c "$MRCONFIG" config DEFAULT include="cat /usr/share/mr/git-fake-bare"
140     
141 }
142
143 login() {
144     if [ $# -ne 1 ]; then 
145         usage
146     fi
147
148     export GIT_DIR="$LOCAL_REPOS/${1}.git"
149     export GIT_WORK_TREE="$GIT_DIR/$(git config --get core.worktree)"
150
151     GIT_PS1_SHOWUNTRACKEDFILES= PSMOVEIN="movein:${1}" $SHELL -i || :
152 }
153
154 execin() {
155     local REPO
156     if [ $# -lt 1 ]; then
157         usage
158     fi
159
160     REPO=$1;shift
161
162     export GIT_DIR="$LOCAL_REPOS/${REPO}.git"
163     export GIT_WORK_TREE="$GIT_DIR/$(git config --get core.worktree)"
164
165     "$@"
166 }
167
168 add() {
169     if [ $# -ne 1 ]; then 
170         usage
171     fi
172     REPO_NAME=$1.git ; shift
173     LOCAL_REPO=$LOCAL_REPOS/$REPO_NAME
174     REPO_URL=ssh://$GIT_HOST/$REMOTE_REPOS/$REPO_NAME
175
176     if [ -e "$LOCAL_REPO" ]; then
177         echo $LOCAL_REPO already exists
178         exit 1
179     else
180         trap "rm -rf $LOCAL_REPO" 0
181         mkdir "$LOCAL_REPO"
182         export GIT_DIR="$LOCAL_REPO"
183         git init --bare
184         git remote add origin $REPO_URL
185         git config branch.master.remote origin
186         git config branch.master.merge refs/heads/master
187         git config core.bare false
188         git config core.worktree ../../
189         git config status.showUntrackedFiles no
190         GIT_WORK_TREE="$LOCAL_REPO/../../" git pull
191         trap - 0
192
193         mr -c "$MRCONFIG" config "$LOCAL_REPO" checkout="git_fake_bare_checkout '$REPO_URL' 'REPO_NAME' '../../'"
194     fi
195 }
196
197 list() {
198     find "${LOCAL_REPOS}" -mindepth 1 -maxdepth 1 -type d | sed 's,^.*/\([^/]*\).git$,\1,'
199 }
200
201 listremote() {
202     ssh $GIT_HOST "
203         find '${REMOTE_REPOS}' -mindepth 1 -maxdepth 1 -type d | sed 's,^.*/\([^/]*\).git$,\1,'
204     " </dev/null
205 }
206
207 new() {
208     if [ $# -lt 2 ]; then 
209         usage
210     fi
211     REPO_NAME=$1.git ; shift
212     LOCAL_REPO="$LOCAL_REPOS/$REPO_NAME"
213     REPO_URL="ssh://$GIT_HOST/$REMOTE_REPOS/$REPO_NAME"
214
215     if [ ! -e "$1" ]; then
216         echo $1 not found
217         exit 1
218     fi
219
220     if [ -e "$LOCAL_REPO" ]; then
221         echo $LOCAL_REPO already exists
222         exit 1
223     else
224         trap "rm -rf $LOCAL_REPO" 0
225         mkdir -p "$LOCAL_REPO"
226
227         ssh $GIT_HOST "
228                GIT_DIR=$REMOTE_REPOS/$REPO_NAME git --bare init
229         " </dev/null
230
231         export GIT_DIR="$LOCAL_REPO"
232         git init --bare
233         git remote add origin $REPO_URL
234         git config branch.master.remote origin
235         git config branch.master.merge refs/heads/master
236         git config core.bare false
237         git config core.worktree ../../
238         git config status.showUntrackedFiles no
239         export GIT_WORK_TREE="$LOCAL_REPO/../../"
240         git add "$@"
241         git commit -m "initial checkin"
242         git push --all
243         
244         trap - 0
245
246         mr -c "$MRCONFIG" config "$LOCAL_REPO" checkout="git_fake_bare_checkout '$REPO_URL' 'REPO_NAME' '../../'"
247     fi
248
249 }
250
251
252 command=$1 ; shift
253 case "$command" in 
254     init)
255         init $@
256         ;;
257     add)
258         add $@
259         ;;
260     new)
261         new $@
262         ;;
263     login)
264         login $@
265         ;;
266     exec)
267         execin "$@"
268         ;;
269     ls)
270         list
271         ;;
272     list)
273         list
274         ;;
275     ls-r)
276         listremote
277         ;;
278     list-remote)
279         listremote
280         ;;
281
282     *)
283         usage
284         exit 1
285         ;;
286 esac