]> git.cworth.org Git - nogit/blob - nogit
Fix emacs hook to not clobber match data
[nogit] / nogit
1 #!/bin/bash
2 set -e
3
4 NOGIT_DIR=.nogit
5 NOGIT_DIR_TMP=$NOGIT_DIR-tmp
6
7 usage_brief()
8 {
9     echo "Usage: nogit <command>"
10     echo ""
11     echo "Available commands are:"
12     echo ""
13     echo "    nogit clone"
14     echo "    nogit sync"
15     echo ""
16     echo "See 'nogit help' for more details"
17 }
18
19 usage()
20 {
21     echo "Usage: nogit <command>"
22     echo ""
23     echo "Possible commands are described below:"
24     echo ""
25     echo "nogit clone <command>"
26     echo ""
27     echo "    Clone a nogit repository into the current directory."
28     echo "    This differs from 'git clone' in that it will not create"
29     echo "    a new top-level directory but will instead clone the"
30     echo "    resulting files into the current directory (which may"
31     echo "    already be a local git repository). The object store for"
32     echo "    this newly-cloned repository will be a directory named"
33     echo "    .nogit rather than .git."
34     echo ""
35     echo "    The repository to be cloned should be a nogit repository"
36     echo "    in the sense that its files are intended to be managed"
37     echo "    according to nogit semantics. But other than that, the"
38     echo "    repository to be cloned is an actual git repository."
39     echo ""
40     echo "nogit sync"
41     echo ""
42     echo "    Synchronize local and remote changes"
43     echo ""
44     echo "    For all files managed by a previously-cloned nogit repository"
45     echo "    this command will:"
46     echo ""
47     echo "        * Commit local changes (auto-generated commit message)"
48     echo ""
49     echo "        * Pull down any new commits from the remote"
50     echo ""
51     echo "        * Auto-merge local and remote (keeping both sides and"
52     echo "          with an auto-generated commit message)"
53     echo ""
54     echo "        * Push out any new commits generated locally"
55     echo ""
56     echo "nogit log"
57     echo ""
58     echo "    Display a log of changes"
59 }
60
61 nogit_clone()
62 {
63     url="$1"
64
65     if [ -e $NOGIT_DIR ]; then
66         echo "Error: $NOGIT_DIR already exists. Cowardly refusing to re-clone."
67         return 1
68     fi
69
70     if [ -e $NOGIT_DIR_TMP ]; then
71         echo "Error: $NOGIT_DIR_TMP already exists. Was a previous clone interrupted?"
72         echo "You'll want to clean that up before trying again."
73         return 1
74     fi
75
76     # Clone the repository into a temporary directory
77     mkdir $NOGIT_DIR_TMP
78     cd $NOGIT_DIR_TMP
79     git clone "$url" tmp >/dev/null 2>&1
80
81     # Sanity check that we won't be overwriting any files
82     EXISTING=()
83     cd tmp
84     for file in $(find . -mindepth 1 -a -path ./.git -prune -o -print); do
85         if [ -e "../../$file" ]; then
86             EXISTING+=($(echo "$file" | sed -s 's,^\./,,'))
87         fi
88     done
89     cd ..
90
91     if [ ${#EXISTING[@]} -gt 0 ]; then
92         echo "Error: The following existing files would be overwritten:" >&2
93         echo "" >&2
94         for file in ${EXISTING[@]}; do
95             echo "    $file" >&2
96         done
97         echo "" >&2
98         echo "Cowardly refusing to clone" >&2
99         cd ..
100         rm -rf $NOGIT_DIR_TMP
101         false
102     fi
103
104     # Install the info/atttributes file that forces the "union" merge
105     # driver for all files, giving us the semantics of "keep both sides
106     # of all conflicts" that is at the heart of nogit.
107     mkdir -p tmp/.git/info
108     echo '* merge=union' > tmp/.git/info/attributes
109
110     # Install the config entry for the pretty format for "nogit log"
111     (cd tmp; git config pretty.nogit "format:%Cblue%h %an (%ad)%Creset")
112
113     # Now that we've passed the sanity check, install the cloned .git
114     # object store into $NOGIT_DIR, cleanup our temporary files, and
115     # checkout the (known to not be conflicting) files.
116     mv tmp/.git ../$NOGIT_DIR
117     cd ..
118     rm -rf $NOGIT_DIR_TMP
119     GIT_DIR=$NOGIT_DIR git reset --hard >/dev/null 2>&1
120
121     echo "Completed nogit clone of $url"
122 }
123
124 nogit_sync()
125 {
126     # First commit any locally modified nogit files
127     GIT_DIR=$NOGIT_DIR git commit -a -m "nogit-sync commit" >/dev/null 2>&1 || true
128
129     # Then, fetch and merge any upstream changes
130     GIT_DIR=$NOGIT_DIR git fetch >/dev/null 2>&1
131     GIT_DIR=$NOGIT_DIR git merge -m "nogit-sync merge" >/dev/null 2>&1
132
133     # Finally, push any new commits up to the upstream repository
134     GIT_DIR=$NOGIT_DIR git push >/dev/null 2>&1
135
136     echo "Completed nogit sync"
137 }
138
139 nogit_log()
140 {
141     GIT_DIR=$NOGIT_DIR git log -p --pretty=nogit
142 }
143
144 if [ $# -lt 1 ]; then
145     echo "Error: missing command name." >&2
146     echo ""
147     usage_brief >&2
148     exit 1
149 fi
150
151 cmd="$1"
152
153 case "$cmd" in
154     clone)
155         if [ $# -lt 2 ]; then
156             echo "Error: 'nogit clone' requires the URL of a repository to clone"
157             false;
158         fi
159         nogit_clone "$2"
160         ;;
161     sync)
162         nogit_sync
163         ;;
164     log)
165         nogit_log
166         ;;
167     help)
168         usage
169         true
170         ;;
171     *)
172         echo "Error: Unknown command: $cmd" >&2
173         echo ""
174         usage_brief >&2
175         false
176         ;;
177 esac
178
179 exit $?