# http://felipec.wordpress.com/2012/11/13/git-remote-hg-bzr-2/
# Uncomment to have verbose debug output
-debug=1
+#debug=1
+
+PROJRC_COUNT=0
+SUBPATHS_COUNT=0
print_usage()
{
echo "Usage: $(basename $0) [OPTIONS...]"
}
-# git-remote-hg doesn't work with Mercurial subpaths extension,
-# so use it manually
-hg_subpaths_config() {
- subpaths=$(hg showconfig | grep "subpaths" | grep "HG_REPO")
+# We parse the projrc file in the assembly (on the server), to check
+# for any projrc substitutions.
+#
+# Arg 1: repository (path and name)
+#
+# Return the substitution key/values in arrays:
+# PROJRC_KEY
+# PROJRC_VAL
+# PROJRC_COUNT will be greater than zero if any substitutions were found.
+hg_parse_projrc() {
+ if [ ${#} -lt 1 ]; then
+ echo "Missing repository name"
+ fi
+
+ # Repo name can have spaces in it, hence the use of ${*}
+ local repo="${*}"
+
+ if [ -f "${repo}/.hg/projrc" ]; then
- echo "subpaths = ${subpaths}"
+ TMPF="/tmp/$(basename $0).projrc-$$.tmp"
- if [ -n ${subpaths} ]; then
- sp_src=${subpaths//subpaths./}
- sp_src=${sp_src//=*/}
- sp_src=${sp_src//\\/} # Remove windows separator (LSI)
- sp_dst=${subpaths//*=/}
+ # Create temporary copy to replace backslashes with slashes.
+ # Make sure to only replace path backslashes, not backslashes for
+ # quoting spaces.
+ # \\[^ ] Match a backslash, not followed by a space
+ cat "${repo}/.hg/projrc" | sed 's/\\\([^ ]\)/\/\1/g' > ${TMPF}
- if [ -n "${debug}" ]; then
- echo "sp_src = $sp_src"
- echo "sp_dst = $sp_dst"
- fi
+ while read p; do
+ if echo ${p} | grep -q "\s=\s"; then
+ local key=$(echo ${p} | sed 's/^\(.*\) = .*/\1/')
+ local val=$(echo ${p} | sed 's/.* = \(.*\)/\1/')
+
+ PROJRC_KEY[${PROJRC_COUNT}]="${key}"
+ PROJRC_VAL[${PROJRC_COUNT}]="${val}"
+
+ if [ -n "${debug}" ]; then
+ echo "Parsing PROJRC entry: ${p}"
+ echo " key: ${key}"
+ echo " val: ${val}"
+ fi
+
+ PROJRC_COUNT=$((PROJRC_COUNT + 1))
+ fi
+ done < ${TMPF}
+
+ rm ${TMPF}
fi
}
-# git-remote-hg doesn't work with Mercurial projrc extension,
-# so use it manually.
-# We parse the projrc file in the assembly (on the server), to check
-# for any projrc substitutions.
-#
-# Arg 1: subproject (path and name)
+# We parse the Mercurial configuration, to check
+# for any SUBPATHS substitutions.
#
-# Return the new substitution name if found, and original subrepo name if not
-# (with the path stripped)
-hg_check_projrc_config() {
- if [ ${#} -lt 1 ]; then
- echo "Missing subrepos name"
+# Return the substitution key/values in arrays:
+# SUBPATHS_KEY
+# SUBPATHS_VAL
+# SUBPATHS_COUNT will be greater than zero if any substitutions were found.
+hg_parse_subpaths() {
+ subpaths=$(hg showconfig subpaths)
+
+ if [ -n "${subpaths}" ]; then
+ for p in ${subpaths}; do
+ local key=$(echo ${p} | sed 's/^subpaths\.\(.*\)=.*/\1/')
+ local val=$(echo ${p} | sed 's/.*=\(.*\)/\1/')
+
+ # Replace '\\' with '/'
+ key=${key//\\\\/\/}
+ # ^^ replace multiple times
+
+ val=${val//\\\\/\/}
+
+ SUBPATHS_KEY[${SUBPATHS_COUNT}]="${key}"
+ SUBPATHS_VAL[${SUBPATHS_COUNT}]="${val}"
+
+ if [ -n "${debug}" ]; then
+ echo "Parsing SUBPATHS entry: ${p}"
+ echo " key: ${key}"
+ echo " val: ${val}"
+ fi
+
+ SUBPATHS_COUNT=$((SUBPATHS_COUNT + 1))
+ done
fi
+}
+# Replace the given path with either entries from PROJRC or SUBPATHS
+# Arg 1: path
+apply_substitutions() {
# Repo name can have spaces in it, hence the use of ${*}
- local subrepo_orig="${*}"
- local subrepo="${*}"
+ local path="${*}"
- # Quote spaces
- subrepo=${subrepo// /\\\\ }
+ if [ ${PROJRC_COUNT} -ne 0 ]; then
+ for s in $(seq 0 $((${PROJRC_COUNT} - 1))); do
+ local pattern=${PROJRC_KEY[${s}]}
+ local replacement=${PROJRC_VAL[${s}]}
- asm=$(cat .git/config | grep "hg::" | sed "s/.*url = hg::\(.*\)/\1/")
+ path=${path/${pattern}/${replacement}}
+ done
+ fi
- local baserepo=$(basename "${subrepo}")
+ if [ ${SUBPATHS_COUNT} -ne 0 ]; then
+ for s in $(seq 0 $((${SUBPATHS_COUNT} - 1))); do
+ local pattern=${SUBPATHS_KEY[${s}]}
+ local replacement=${SUBPATHS_VAL[${s}]}
- if cat "${asm}/.hg/projrc" | grep -q "${baserepo}" ; then
- projrc=$(cat "${asm}/.hg/projrc" | grep "${baserepo}" | sed "s/.*= \(.*\)/\1/")
- else
- # No substitution, return same name as original
- projrc=$(basename "${subrepo_orig}")
+ path=${path/${pattern}/${replacement}}
+ done
fi
- echo "${projrc}"
+ echo "${path}"
}
# Map a revision to a branch name in HG subrepository
echo ".gitignore" > .gitignore
fi
-hg_subpaths_config
+asm=$(cat .git/config | grep "hg::" | sed "s/.*url = hg::\(.*\)/\1/")
+hg_parse_projrc ${asm}
+
+hg_parse_subpaths
+
+HGSUB_TMP="/tmp/$(basename $0).hgsub-$$.tmp"
+
+# Create temporary copy to replace backslashes with slashes.
+cat .hgsub | sed 's/\\/\//g' > ${HGSUB_TMP}
# Read lines from .hgsub
while read sub; do
# Get subrepository URL
src="${sub//*= /}"
- # Replace using subpaths extension content
- src=${src/${sp_src}/${sp_dst}}
+ # Replace using Mercurial subpaths substitutions (either projrc or from hgrc)
+ src=$(apply_substitutions ${src})
+
+ # Original name
+ repo=$(basename "${src}")
+ srcpath=$(dirname "${src}")
# Get subrepository local alias or label
dest="${sub// =*}"
# Get revision of subrepository (remove CR from .hgsubstate)
rev=$(cat .hgsubstate | tr -d '\r' | grep "${id}" | sed "s/ .*//")
- # Original name
- repo=$(basename "${src}")
- srcpath=$(dirname "${src}")
-
- projrc_sub=$(hg_check_projrc_config "${src}")
- src="${srcpath}/${projrc_sub}"
-
if [ -n "${debug}" ]; then
echo "repo: ${repo}"
- echo " path: ${srcpath}"
- echo " id: ${id}"
- echo " src: ${projrc_sub}"
- echo " dest: ${dest}"
- echo " rev: ${rev}"
+ echo " path: ${srcpath}"
+ echo " id: ${id}"
+ echo " local: ${dest}"
+ echo " rev: ${rev}"
fi
if [ ! -d "${dest}" ]; then
fi
fi
fi
-done < .hgsub
+done < ${HGSUB_TMP}
+
+rm ${HGSUB_TMP}
+