chris@241
|
1 #!/bin/sh
|
chris@241
|
2
|
chris@242
|
3 mirrordir="/var/mirror"
|
Chris@1336
|
4 hg="/usr/bin/hg"
|
chris@242
|
5
|
chris@241
|
6 project="$1"
|
chris@241
|
7 local_repo="$2"
|
chris@241
|
8 remote_repo="$3"
|
chris@241
|
9
|
chris@241
|
10 if [ -z "$project" ] || [ -z "$local_repo" ] || [ -z "$remote_repo" ]; then
|
chris@241
|
11 echo "Usage: $0 <project> <local-repo-path> <remote-repo-url>"
|
chris@241
|
12 exit 2
|
chris@241
|
13 fi
|
chris@241
|
14
|
chris@241
|
15 # We need to handle different source repository types separately.
|
chris@241
|
16 #
|
chris@241
|
17 # The convert extension cannot convert directly from a remote git
|
chris@241
|
18 # repo; we'd have to mirror to a local repo first. Incremental
|
chris@241
|
19 # conversions do work though. The hg-git plugin will convert
|
chris@241
|
20 # directly from remote repositories, but not via all schemes
|
chris@241
|
21 # (e.g. https is not currently supported). It's probably easier to
|
chris@241
|
22 # use git itself to clone locally and then convert or hg-git from
|
chris@241
|
23 # there.
|
chris@241
|
24 #
|
chris@241
|
25 # We can of course convert directly from remote Subversion repos,
|
chris@241
|
26 # but we need to keep track of that -- you can ask to convert into a
|
chris@241
|
27 # repo that has already been used (for Mercurial) and it'll do so
|
chris@241
|
28 # happily; we don't want that.
|
chris@241
|
29 #
|
chris@241
|
30 # Converting from a remote Hg repo should be fine!
|
chris@241
|
31 #
|
chris@241
|
32 # One other thing -- we can't actually tell the difference between
|
chris@241
|
33 # the various SCM types based on URL alone. We have to try them
|
chris@241
|
34 # (ideally in an order determined by a guess based on the URL) and
|
chris@241
|
35 # see what happens.
|
chris@241
|
36
|
chris@242
|
37 project_mirror="$mirrordir/$project"
|
chris@242
|
38 mkdir -p "$project_mirror"
|
chris@242
|
39 project_repo_mirror="$project_mirror/repo"
|
chris@241
|
40
|
chris@242
|
41 # Some test URLs:
|
chris@242
|
42 #
|
chris@242
|
43 # http://aimc.googlecode.com/svn/trunk/
|
chris@242
|
44 # http://aimc.googlecode.com/svn/
|
chris@242
|
45 # http://vagar.org/git/flam
|
chris@242
|
46 # https://github.com/wslihgt/IMMF0salience.git
|
chris@242
|
47 # http://hg.breakfastquay.com/dssi-vst/
|
chris@242
|
48 # git://github.com/schacon/hg-git.git
|
chris@242
|
49 # http://svn.drobilla.net/lad (externals!)
|
chris@242
|
50
|
chris@242
|
51 # If we are importing from another distributed system, then our aim is
|
chris@242
|
52 # to create either a Hg repo or a git repo at $project_mirror, which
|
chris@242
|
53 # we can then pull from directly to the Hg repo at $local_repo (using
|
chris@242
|
54 # hg-git, in the case of a git repo).
|
chris@242
|
55
|
chris@242
|
56 # Importing from SVN, we should use hg convert directly to the target
|
chris@242
|
57 # hg repo (or should we?) but keep a record of the last changeset ID
|
chris@242
|
58 # we brought in, and test each time whether it matches the last
|
chris@242
|
59 # changeset ID actually in the repo
|
chris@242
|
60
|
chris@242
|
61 success=""
|
chris@242
|
62
|
Chris@436
|
63 # If we have a record of the last successfully updated remote repo
|
Chris@436
|
64 # URL, check it against our current remote URL: if it has changed, we
|
Chris@436
|
65 # will need to start again with a new clone rather than pulling
|
Chris@436
|
66 # updates into the existing local mirror
|
Chris@436
|
67
|
Chris@436
|
68 successfile="$project_mirror/last_successful_url"
|
Chris@436
|
69 if [ -f "$successfile" ]; then
|
Chris@436
|
70 last=$(cat "$successfile")
|
chris@437
|
71 if [ x"$last" = x"$remote_repo" ]; then
|
Chris@436
|
72 echo "$$: Remote URL is unchanged from last successful update"
|
Chris@436
|
73 else
|
Chris@436
|
74 echo "$$: Remote URL has changed since last successful update:"
|
Chris@436
|
75 echo "$$: Last URL was $last, current is $remote_repo"
|
Chris@436
|
76 suffix="$$.$(date +%s)"
|
Chris@436
|
77 echo "$$: Moving existing repos to $suffix suffix and starting afresh"
|
Chris@436
|
78 mv "$project_repo_mirror" "$project_repo_mirror"."$suffix"
|
Chris@436
|
79 mv "$local_repo" "$local_repo"."$suffix"
|
Chris@436
|
80 mv "$successfile" "$successfile"."$suffix"
|
chris@437
|
81 touch "$project_mirror/url_changed"
|
Chris@436
|
82 fi
|
Chris@436
|
83 fi
|
Chris@436
|
84
|
chris@242
|
85 if [ -d "$project_repo_mirror" ]; then
|
chris@242
|
86
|
chris@242
|
87 # Repo mirror exists: update it
|
chris@242
|
88 echo "$$: Mirror for project $project exists at $project_repo_mirror, updating" 1>&2
|
chris@242
|
89
|
chris@242
|
90 if [ -d "$project_repo_mirror/.hg" ]; then
|
Chris@433
|
91 "$hg" --config extensions.convert= convert --datesort "$remote_repo" "$project_repo_mirror" && success=true
|
chris@439
|
92 if [ -z "$success" ]; then
|
chris@439
|
93 ( cd "$project_repo_mirror" && "$hg" pull "$remote_repo" ) && success=true
|
chris@439
|
94 fi
|
chris@242
|
95 elif [ -d "$project_repo_mirror/.git" ]; then
|
Chris@431
|
96 ( cd "$project_repo_mirror" && git pull "$remote_repo" master ) && success=true
|
chris@242
|
97 else
|
chris@242
|
98 echo "$$: ERROR: Repo mirror dir $project_repo_mirror exists but is not an Hg or git repo" 1>&2
|
chris@242
|
99 fi
|
chris@242
|
100
|
chris@242
|
101 else
|
chris@242
|
102
|
chris@242
|
103 # Repo mirror does not exist yet
|
chris@242
|
104 echo "$$: Mirror for project $project does not yet exist at $project_repo_mirror, trying to convert or clone" 1>&2
|
chris@242
|
105
|
chris@242
|
106 case "$remote_repo" in
|
chris@242
|
107 *git*)
|
chris@242
|
108 git clone "$remote_repo" "$project_repo_mirror" ||
|
Chris@433
|
109 "$hg" --config extensions.convert= convert --datesort "$remote_repo" "$project_repo_mirror"
|
chris@242
|
110 ;;
|
chris@242
|
111 *)
|
Chris@433
|
112 "$hg" --config extensions.convert= convert --datesort "$remote_repo" "$project_repo_mirror" ||
|
chris@299
|
113 git clone "$remote_repo" "$project_repo_mirror" ||
|
Chris@433
|
114 "$hg" clone "$remote_repo" "$project_repo_mirror"
|
chris@242
|
115 ;;
|
chris@242
|
116 esac && success=true
|
chris@242
|
117
|
chris@242
|
118 fi
|
chris@242
|
119
|
chris@242
|
120 echo "Success=$success"
|
chris@242
|
121
|
chris@242
|
122 if [ -n "$success" ]; then
|
chris@242
|
123 echo "$$: Update successful, pulling into local repo at $local_repo"
|
Chris@436
|
124 if [ ! -d "$local_repo" ]; then
|
Chris@436
|
125 "$hg" init "$local_repo"
|
Chris@436
|
126 fi
|
chris@242
|
127 if [ -d "$project_repo_mirror/.git" ]; then
|
Chris@1599
|
128 ( cd "$local_repo" && "$hg" --config extensions.git= pull "$project_repo_mirror" ) && echo "$remote_repo" > "$successfile"
|
chris@242
|
129 else
|
Chris@436
|
130 ( cd "$local_repo" && "$hg" pull "$project_repo_mirror" ) && echo "$remote_repo" > "$successfile"
|
chris@242
|
131 fi
|
chris@242
|
132 fi
|