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