5748872 [rkeene@sledge /home/rkeene/projects/scripts]$ cat -n svn-to-fossil.sh
  1 #! /bin/bash
  2 
  3 SVN_URL="$1"
  4 FOSSIL_REPO="$2"
  5 WORKDIR="${TMPDIR:-/var/tmp}/svn-to-fossil.workdir-$$${RANDOM}${RANDOM}${RANDOM}"
  6 
  7 if [ -z "${SVN_URL}" -o -z "${FOSSIL_REPO}" ]; then
  8     echo 'Usage: svn-to-fossil <svn-url> <fossil-repo>' >&2
  9 
 10     exit 1
 11 fi
 12 
 13 # Create working directory
 14 mkdir -p "${WORKDIR}/svn" || exit 1
 15 mkdir -p "${WORKDIR}/fossil" || exit 1
 16 chmod 700 "${WORKDIR}" || exit 1
 17 
 18 # Create a list of revisions
 19 SVN_REVS="$(
 20     (
 21         svn log -g "${SVN_URL}" 2>/dev/null || \
 22         svn log "${SVN_URL}" 2>/dev/null
 23     ) | grep '^r[0-9][0-9]* | .*' | awk '{ print $1 }' | sed 's@^r@@' | tac
 24 )"
 25 
 26 # Determine root of repository and directory within repository for renames
 27 SVN_ROOT="$(svn info "${SVN_URL}" | grep '^Repository Root:' | sed 's@^Repository Root: @@')"
 28 SVN_PROJ="$(echo "${SVN_URL}" | sed "s@^${SVN_ROOT}@@")"
 29 
 30 # Create the fossil repository
 31 touch "${FOSSIL_REPO}"
 32 FOSSIL_REPO="$(readlink -f "${FOSSIL_REPO}")"
 33 rm -f "${FOSSIL_REPO}"
 34 
 35 # For each revision, sync with fossil
 36 for rev in ${SVN_REVS}; do
 37     (
 38         echo "Processing r${rev}..."
 39         svnrevlog="$(svn log -r"${rev}" "${SVN_URL}")"
 40 
 41         
 42         commituser="$(echo "${svnrevlog}" | head -n 2 | tail -n 1 | cut -f 2 -d '|' | sed 's@ @@g')"
 43         committime="$(echo "${svnrevlog}" | head -n 2 | tail -n 1 | cut -f 3 -d '|' | sed 's@^  *@@;s@(.*$@@;s@  *$@@')"
 44         committime_sec="$(date -d "${committime}" +%s)"
 45         committime_ps="$(echo "puts [clock format \"[expr {$committime_sec - 1}]\" -format {%Y-%m-%d %H:%M:%S}]" |
	tclsh)"
 46         committime="$(echo "puts [clock format \"$committime_sec\" -format {%Y-%m-%d %H:%M:%S}]" | tclsh)"
 47 
 48         # Create the fossil repo if needed
 49         if [ ! -f "${FOSSIL_REPO}" ]; then
 50             fossil new "${FOSSIL_REPO}" -date-override "$committime_ps"
 51 
 52             (
 53                 cd "${WORKDIR}/svn" || exit 1
 54                 fossil open "${FOSSIL_REPO}"
 55             )
 56         fi
 57 
 58         if [ -d "${WORKDIR}/svn" ]; then
 59             svnrevlog_v="$(svn log -v -r"${rev}" "${SVN_URL}")"
 60 
 61             # Attempt to perform renames
 62             echo "${svnrevlog_v}" | grep '^   A .* (from ' | sed 's@^   A @@;s@ (from @|@;s@:[0-9]*)$@@' | while read
	pathnames; do
 63                 src_pathname_raw="$(echo "${pathnames}" | cut -f 2 -d '|')"
 64                 src_pathname="$(echo "${pathnames}" | cut -f 2 -d '|' | sed "s@^${SVN_PROJ}/@@")"
 65                 dst_pathname="$(echo "${pathnames}" | cut -f 1 -d '|' | sed "s@^${SVN_PROJ}/@@")"
 66 
 67                 if echo "${src_pathname}" | grep '^/' >/dev/null; then
 68                     src_pathname=""
 69                 fi
 70 
 71                 if echo "${dst_pathname}" | grep '^/' >/dev/null; then
 72                     dst_pathname=""
 73                 fi
 74 
 75                 if [ -n "${src_pathname}" -a -n "${dst_pathname}" ]; then
 76                     cd "${WORKDIR}/svn" || exit 1
 77 
 78                     if echo "${svnrevlog_v}" | grep "^   D ${src_pathname_raw} *$" >/dev/null 2>/dev/null; then
 79                         # Copy + Delete = Rename
 80                         echo "Handling move \"${src_pathname}\" -> \"${dst_pathname}\""
 81 
 82                         fossil mv "${src_pathname}" "${dst_pathname}"
 83                     else
 84                         # Simple copy...
 85                         echo "Handling copy \"${src_pathname}\" -> \"${dst_pathname}\""
 86 
 87                         cp "${src_pathname}" "${dst_pathname}"
 88 
 89                         sleep 2
 90                         fossil add "${dst_pathname}"
 91                         fossil ci -date-override "${committime_ps}" -m "Subversion to Fossil Copy Commit.  Please
	Ignore.  Recording copying ${src_pathname} to ${dst_pathname}." "${dst_pathname}"
 92                     fi
 93                 fi
 94             done
 95         fi
 96 
 97         # Preserve fossil repo information
 98         mv "${WORKDIR}/svn"/_FOSSIL_ "${WORKDIR}/fossil/"
 99 
100         ## These files are apparently optional now...
101         for save_file in "${WORKDIR}/svn"/manifest "${WORKDIR}/svn"/manifest.uuid; do
102             if [ -f "${save_file}" ]; then
103                 mv "${save_file}" "${WORKDIR}/fossil/"
104             fi
105         done
106 
107         # Cleanup working directory
108         rm -rf "${WORKDIR}/svn"
109         mkdir -p "${WORKDIR}/svn"
110         cd "${WORKDIR}/svn" || exit 1
111 
112         # Restore fossil repo information
113         mv "${WORKDIR}/fossil"/* "${WORKDIR}/svn/"
114 
115         # Check out the appropriate version
116         ## We can't use an update, since it will break on renames
117         svn checkout --ignore-externals -r"${rev}" "${SVN_URL}" . >/dev/null 2>/dev/null || exit 1
118 
119         # Remove things that should not go in the repository
120         find . -type d -name .svn | xargs rm -rf
121 
122         # Add new files to fossil
123         fossil extras --dotfiles | while read filename; do
124             fossil add "${filename}"
125         done
126 
127         # Delete files from fossil
128         fossil status | grep '^MISSING' | sed 's@^MISSING@@' | while read filename; do
129             fossil rm "${filename}"
130         done
131 
132         # Find commit message
133         commit_msg="$(echo "${svnrevlog}" | tail -n +4 | head -n -1)"
134         if [ -z "${commit_msg}" ]; then
135             commit_msg="(no message specified)"
136         fi
137 
138         # Commit
139         fossil commit -date-override "${committime}" -user-override "${commituser}" -m "${commit_msg}" || (
140             if fossil commit -date-override "${committime}" -user-override "${commituser}"-m "${commit_msg}" 2>&1 | grep
	'nothing has changed'; then
141                 exit 0
142             fi
143 
144             exit 1
145         ) || exit 1
146     ) || exit 1
147 done
148 
149 # Find ignore glob (end result is the only one that matters since fossil doesn't revision control the settings)
150 (
151     cd "${WORKDIR}/svn" || exit 1
152     ignores="$(find . -type d | grep -v '/\.svn/' | while read dirname; do
153         if svn proplist "${dirname}" 2>/dev/null | grep 'svn:ignore' >/dev/null; then
154             svn propget svn:ignore "${dirname}" 2>/dev/null | grep -v '^ *$' | sed "s@^@${dirname}/@;"'s@^\./@@'
155         fi
156     done | sed 'p;s@$@/*@' | sort -u | tr "\n" ',' | sed 's@,$@@')"
157     fossil settings ignore-glob "${ignores}"
158 )
159 
160 # Cleanup
161 (
162     cd "${WORKDIR}/svn" || exit 1
163 
164     fossil close 
165 )
166 rm -rf "${WORKDIR}"
167 
168 exit 0

svn-to-fossil.sh is a script to convert a (portion of) a Subversion repository to a Fossil repository.
5748873 [rkeene@sledge /home/rkeene/projects/scripts]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2010-10-29 05:26:44