From 3dc333574e9ecb661861a5e55f7f0e119629a4f1 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Thu, 28 Jan 2021 19:33:10 +0100 Subject: Add script to merge remote patches --- gitmirror-merge.sh | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ gitmirror.sh | 12 ++++----- 2 files changed, 84 insertions(+), 7 deletions(-) create mode 100755 gitmirror-merge.sh diff --git a/gitmirror-merge.sh b/gitmirror-merge.sh new file mode 100755 index 0000000..d346602 --- /dev/null +++ b/gitmirror-merge.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +MIRROR_REMOTE="gitmirror_remote" +CLONE_URL_PATTERN="file://${PWD}/%s" + +msg() { + echo "==> $1" +} + +msg2() { + echo "--> $1" +} + +deepened_fetch() { + local fetch_spec="$1" + local exclude="$2" + if git fetch "${MIRROR_REMOTE}" "${fetch_spec}" \ + --shallow-exclude="${exclude}"; then + msg2 "Deepen fetch by 1" + git fetch "${MIRROR_REMOTE}" "${fetch_spec}" --deepen=1 + else + msg2 "Shallow request possibly empty, retry with depth=1" + git fetch "${MIRROR_REMOTE}" "${fetch_spec}" --depth=1 + fi +} + +merge_patches() { + if (( $# != 3 )); then + echo "Usage: $0 REPOSITORY REMOTE BRANCH" >&2 + exit 1 + fi + + local repository="$1" + local remote="$2" + local branch="$3" + + if [[ "${remote}" == "${MIRROR_REMOTE}" ]]; then + msg "REMOTE must not be ${MIRROR_REMOTE}" >&2 + exit 1 + fi + + local copy_name="${repository}-patch-${remote}-${branch}" + msg "Create working copy ${copy_name}" + rm -rf "${copy_name}" + mkdir "${copy_name}" + pushd "${copy_name}" > /dev/null + git init + local clone_url + # shellcheck disable=2059 + clone_url="$(printf "${CLONE_URL_PATTERN}" "${repository}")" + git remote add "${MIRROR_REMOTE}" "${clone_url}" + + local patch_branch="patch-for/${branch}" + msg "Fetch patch at ${patch_branch}" + local upstream_branch="${remote}/${branch}" + local remote_upstream_ref="refs/remotes/${upstream_branch}" + deepened_fetch "${patch_branch}" "${remote_upstream_ref}" + + msg "Fetch upstream at ${upstream_branch}" + local local_upstream_ref="refs/remotes/${MIRROR_REMOTE}/${upstream_branch}" + deepened_fetch "${remote_upstream_ref}:${local_upstream_ref}" \ + "refs/heads/${patch_branch}" + + msg "Merge ${patch_branch} into ${upstream_branch}" + git checkout -b "${branch}" --no-track "${local_upstream_ref}" + git merge "${MIRROR_REMOTE}/${patch_branch}" --no-ff \ + -m "Merge branch '${patch_branch}' into ${upstream_branch}" + + msg "Push ${branch} to ${MIRROR_REMOTE}" + git push --force "${MIRROR_REMOTE}" "${branch}:${branch}" + + popd > /dev/null + rm -rf "${copy_name}" +} + +if [[ "$0" == "${BASH_SOURCE[0]}" ]]; then + merge_patches "$@" +fi diff --git a/gitmirror.sh b/gitmirror.sh index 29503d9..53433dc 100755 --- a/gitmirror.sh +++ b/gitmirror.sh @@ -22,6 +22,8 @@ read_branches() { done < <(git for-each-ref "${prefix}**" \ --format=$'%(refname)\t%(objectname)' \ --color=never) + + local branch_name for branch_name in "${!read_branches_target[@]}"; do printf " %*s = %s\n" \ $((-max_length)) \ @@ -55,18 +57,14 @@ archive_if_needed() { } sync_mirror() { - if (( $# == 0 || $# > 2 )); then + if (( $# != 2 )); then echo "Usage: $0 REPOSITORY [REMOTE]" >&2 exit 1 fi local repository="$1" - local remote - if (( $# == 1 )); then - remote="origin" - else - remote="$2" - fi + local remote="$2" + local archive_prefix archive_prefix="$(TZ='UTC' printf 'archives/%(%Y%m%dT%H%M%S)TZ/')" -- cgit v1.2.3-54-g00ecf