From 8e77a30d6f6101363bbf88720035789be4575b74 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 5 Jan 2019 11:57:13 -0500 Subject: [PATCH] Remove submodule 3dr-yocto-bsp-base --- .gitmodules | 3 - 3dr-yocto-bsp-base | 1 - git-submodule-rewrite.sh | 226 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+), 4 deletions(-) delete mode 160000 3dr-yocto-bsp-base create mode 100755 git-submodule-rewrite.sh diff --git a/.gitmodules b/.gitmodules index 557cdf0..42ad63f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,9 +25,6 @@ [submodule "solo-builder"] path = solo-builder url = https://github.com/OpenSolo/solo-builder.git -[submodule "3dr-yocto-bsp-base"] - path = 3dr-yocto-bsp-base - url = https://github.com/OpenSolo/3dr-yocto-bsp-base.git [submodule "dronekit-python-solo"] path = dronekit-python-solo url = https://github.com/dronekit/dronekit-python-solo.git diff --git a/3dr-yocto-bsp-base b/3dr-yocto-bsp-base deleted file mode 160000 index 8bbd0a6..0000000 --- a/3dr-yocto-bsp-base +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8bbd0a61034f8348b58513dfc7d8ee46a3546d4f diff --git a/git-submodule-rewrite.sh b/git-submodule-rewrite.sh new file mode 100755 index 0000000..404fbd9 --- /dev/null +++ b/git-submodule-rewrite.sh @@ -0,0 +1,226 @@ +#!/usr/bin/env bash + +# This script builds on the excellent work by Lucas Jenß, described in his blog +# post "Integrating a submodule into the parent repository", but automates the +# entire process and cleans up a few other corner cases. +# https://x3ro.de/2013/09/01/Integrating-a-submodule-into-the-parent-repository.html + +function usage(){ + echo "Usage: $0 []" + echo "Merge a single branch of into a repo, retaining file history." + echo "If provided then will be merged, otherwise master." + echo "" + echo "options:" + echo " -h, --help Print this message" + echo " -v, --verbose Display verbose output" +} + +function abort { + echo "$(tput setaf 1)$1$(tput sgr0)" + exit 1 +} + +function request_confirmation { + read -p "$(tput setaf 4)$1 (y/n) $(tput sgr0)" + [ "$REPLY" == "y" ] || abort "Aborted!" +} + +function warn() { + cat << EOF + This script will convert your "${sub}" git submodule into + a simple subdirectory in the parent repository while retaining all + contents, file history and its own submodules. + + The script will: + * delete the ${sub} submodule configuration from .gitmodules and + .git/config and commit it. + * rewrite the entire history of the ${sub} submodule so that all + paths are prefixed by ${path}. + This ensures that git log will correctly follow the original file + history. + * merge the submodule into its parent repository and commit it. + * reinstate any of the submodule's own submodules as part of the parent + repository + + NOTE: This script might completely garble your repository, so PLEASE apply + this only to a fresh clone of the repository where it does not matter if + the repo is destroyed. It would be wise to keep a backup clone of your + repository, so that you can reconstitute it if need be. You have been + warned. Use at your own risk. + +EOF + + request_confirmation "Do you want to proceed?" +} + +function git_version_lte() { + OP_VERSION=$(printf "%03d%03d%03d%03d" $(echo "$1" | tr '.' '\n' | head -n 4)) + GIT_VERSION=$(git version) + GIT_VERSION=$(printf "%03d%03d%03d%03d" $(echo "${GIT_VERSION#git version }" | sed -E "s/([0-9.]*).*/\1/" | tr '.' '\n' | head -n 4)) + echo -e "${GIT_VERSION}\n${OP_VERSION}" | sort | head -n1 + [ ${GIT_VERSION} -le ${OP_VERSION} ] +} + +# Convert a url to an absolute url +# +# Parameters: +# $1: The url to check +# $2: The base url to use if $1 is a relative path +# +# Returns an absolute url +function absolute_url { + local url=$1 + local base=$2 + + if [[ $url =~ \.\. ]]; then + echo "$base/$(basename $url)" + else + echo $url + fi +} + +function main() { + + warn + + if [ "${verbose}" == "true" ]; then + set -x + fi + + # Remove submodule and commit + git config -f .gitmodules --remove-section "submodule.${sub}" + if git config -f .git/config --get "submodule.${sub}.url"; then + git config -f .git/config --remove-section "submodule.${sub}" + fi + rm -rf "${path}" + git add -A . + git commit -m "Remove submodule ${sub}" + rm -rf ".git/modules/${sub}" + + # Rewrite submodule history + local tmpdir="$(mktemp -d -t submodule-rewrite-XXXXXX)" + git clone -b "${branch}" "${url}" "${tmpdir}" + pushd "${tmpdir}" + local tab="$(printf '\t')" + local filter="git ls-files -s | sed \"s:${tab}:${tab}${path}/:\" | GIT_INDEX_FILE=\${GIT_INDEX_FILE}.new git update-index --index-info && mv \${GIT_INDEX_FILE}.new \${GIT_INDEX_FILE} || true" + git filter-branch --index-filter "${filter}" HEAD + popd + + # Merge in rewritten submodule history + git remote add "${sub}" "${tmpdir}" + git fetch "${sub}" + + if git_version_lte 2.8.4 + then + # Previous to git 2.9.0 the parameter would yield an error + ALLOW_UNRELATED_HISTORIES="" + else + # From git 2.9.0 this parameter is required + ALLOW_UNRELATED_HISTORIES="--allow-unrelated-histories" + fi + + git merge -s ours --no-commit ${ALLOW_UNRELATED_HISTORIES} "${sub}/${branch}" + rm -rf tmpdir + + # Add submodule content + git clone -b "${branch}" "${url}" "${path}" + + # Transfer its own submodules to the parent + add_submod_cmds="" + if [ -f ${path}/.gitmodules ]; then + sub_names=$(git config -f ${path}/.gitmodules --get-regex path | sed 's/.* \(.*\)$/\1/g') + + for sub_name in ${sub_names}; do + sub_branch=$(git config -f ${path}/.gitmodules --get "submodule.${sub_name}.branch") || true + [ -n "${sub_branch}" ] && sub_branch="-b ${sub_branch}" + sub_path=$(git config -f ${path}/.gitmodules --get "submodule.${sub_name}.path") + sub_url=$(git config -f ${path}/.gitmodules --get "submodule.${sub_name}.url") + + # remove the sub-submodule (which should be empty) and cache the command to reinstate it + rmdir ${path}/${sub_path} + add_submod_cmds="$add_submod_cmds git submodule add ${sub_branch} --name ${sub_name} -- ${sub_url} ${path}/${sub_path} ; " + done + fi + + rm -rf "${path}/.git" "${path}/.gitmodules" + git add "${path}" + if [ -n "${add_submod_cmds}" ]; then + bash -c "${add_submod_cmds}" + fi + + git commit -m "Merge submodule contents for ${sub}/${branch}" + git config -f .git/config --remove-section "remote.${sub}" + + set +x + echo "$(tput setaf 2)Submodule merge complete. Push changes after review.$(tput sgr0)" +} + +set -euo pipefail + +declare verbose=false +while [ $# -gt 0 ]; do + case "$1" in + (-h|--help) + usage + exit 0 + ;; + (-v|--verbose) + verbose=true + ;; + (*) + break + ;; + esac + shift +done + +declare sub="${1:-}" +declare branch="${2:-master}" + +if [ -z "${sub}" ]; then + >&2 echo "Error: No submodule specified" + usage + exit 1 +fi + +shift + +if [ -n "${1:-}" ]; then + shift +fi + +if [ -n "${1:-}" ]; then + >&2 echo "Error: Unknown option: ${1:-}" + usage + exit 1 +fi + +if ! [ -d ".git" ]; then + >&2 echo "Error: No git repository found. Must be run from the root of a git repository" + usage + exit 1 +fi + +declare path="$(git config -f .gitmodules --get "submodule.${sub}.path")" +declare superproject_dir="$(dirname $(git config --get remote.origin.url))" +declare url=$(absolute_url $(git config -f .gitmodules --get "submodule.${sub}.url") $superproject_dir) + +if [ -z "${path}" ]; then + >&2 echo "Error: Submodule not found: ${sub}" + usage + exit 1 +fi + +if [ -z "${superproject_dir}" ]; then + >&2 echo "Error: Could not determine the remote origin for this superproject: ${superproject_dir}" + usage + exit 1 +fi + +if ! [ -d "${path}" ]; then + >&2 echo "Error: Submodule path not found: ${path}" + usage + exit 1 +fi + +main