Remove unnecessary spaces quoting
[hvutilities.git] / scripts / git-hg-sub-import
index 41617d1..9d6ae49 100755 (executable)
@@ -7,30 +7,161 @@ set -o errexit
 # Uncomment to have verbose debug output
 #debug=1
 
+PROJRC_COUNT=0
+SUBPATHS_COUNT=0
+
 print_usage()
 {
     echo "$(basename $0) -- HG subrepository importer for git-remote-hg"
     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")
+# 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 [ -n ${subpaths} ]; then
-        sp_src=${subpaths//subpaths./}
-        sp_src=${sp_src//=*/}
-        sp_src=${sp_src//\\/} # Remove windows separator (LSI)
-        sp_dst=${subpaths//*=/}
+    if [ -f "${repo}/.hg/projrc" ]; then
 
-        if [ -n "${debug}" ]; then
-            echo "sp_src = $sp_src"
-            echo "sp_dst = $sp_dst"
-        fi
+        TMPF="/tmp/$(basename $0).projrc-$$.tmp"
+
+        # 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}
+
+        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
+}
+
+# We parse the Mercurial configuration, to check
+# for any SUBPATHS substitutions.
+#
+# 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 path="${*}"
+
+    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}]}
+
+            path=${path/${pattern}/${replacement}}
+        done
+    fi
+
+    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}]}
+
+            path=${path/${pattern}/${replacement}}
+        done
+    fi
+
+    echo "${path}"
+}
+
+# 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)
+#
+# 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"
+    fi
+
+    # Repo name can have spaces in it, hence the use of ${*}
+    local subrepo_orig="${*}"
+    local subrepo="${*}"
+
+    # Quote spaces
+    subrepo=${subrepo// /\\\\ }
+
+    asm=$(cat .git/config | grep "hg::" | sed "s/.*url = hg::\(.*\)/\1/")
+
+    local baserepo=$(basename "${subrepo}")
+
+    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}")
+    fi
+
+    echo "${projrc}"
+}
+
 # Map a revision to a branch name in HG subrepository
 # Use hg log (in original repo) to get branch name corresponding to that
 # revision.
@@ -78,7 +209,15 @@ if [ ! -f .gitignore ]; then
     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
@@ -89,8 +228,12 @@ 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// =*}"
@@ -102,11 +245,11 @@ while read sub; do
         rev=$(cat .hgsubstate | tr -d '\r' | grep "${id}" | sed "s/ .*//")
 
         if [ -n "${debug}" ]; then
-            echo "repo: ${src}"
-            echo "  id:     ${id}"
-            echo "  rev:    ${rev}"
-            echo "  src:    ${src}"
-            echo "  dest:   ${dest}"
+            echo "repo: ${repo}"
+            echo "  path:  ${srcpath}"
+            echo "  id:    ${id}"
+            echo "  local: ${dest}"
+            echo "  rev:   ${rev}"
         fi
 
         if [ ! -d "${dest}" ]; then
@@ -118,11 +261,22 @@ while read sub; do
             #   "BRANCH___-___NAME"
             branch="${branch// /___}"
 
+            if [ -n "${debug}" ]; then
+                echo "branch: ${branch}"
+            fi
+
             git clone "hg::${src}" "${dest}"
 
+            cd "${dest}"
+
+            if [ -x ${HOME}/scripts/git-set-local-author.sh ]; then
+                # Make sure commits have correct author for LSI
+                ${HOME}/scripts/git-set-local-author.sh
+            fi
+
             if [ "x${branch}" != "xdefault" ]; then
-                cd "${dest}"
-                git checkout "branches/${branch}"
+                # Make tracking branch
+                git checkout -f "branches/${branch}"
 
                 # Adjusting git tree to specific commit specified in
                 # .hgsubstate:
@@ -131,14 +285,17 @@ while read sub; do
                 # to a hash in git using the ${num} variable:
                 git_rev=$(git log --oneline | sed -n "${num}p" | awk '{print $1}')
                 git reset --hard ${git_rev}
-
-                cd ..
             fi
 
+            cd ..
+
             if ! grep -q "${dest}" .gitignore ; then
                 # Ignore subrepo in top-level git repository
                 echo "${dest}" >> .gitignore
             fi
         fi
     fi
-done < .hgsub
+done < ${HGSUB_TMP}
+
+rm ${HGSUB_TMP}
+