diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2e3b23c..4f112ea 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,13 +17,17 @@ jobs: cd "$base" # Source repo carrying GitHub-style hidden refs (refs/pull/*, - # refs/github-services/*) next to a regular branch, tag and note. + # refs/github-services/*) next to regular branches, tags and a note. + # Includes nested (slashed) branch and tag names, which must still be + # mirrored. git init -q --bare source.git work="$(mktemp -d)" git clone -q source.git "$work" git -C "$work" -c user.email=t@t -c user.name=t commit -q --allow-empty -m init git -C "$work" push -q origin HEAD:main + git -C "$work" push -q origin HEAD:refs/heads/feature/foo git -C "$work" push -q origin HEAD:refs/tags/v1 + git -C "$work" push -q origin HEAD:refs/tags/release/1.0.0 c="$(git --git-dir=source.git rev-parse refs/heads/main)" git --git-dir=source.git update-ref refs/pull/1/head "$c" git --git-dir=source.git update-ref refs/github-services/pull/1/head "$c" @@ -48,7 +52,8 @@ jobs: cd "$workdir" sh "$GITHUB_WORKSPACE/git-mirror.sh" "$base/source.git" "$base/dest.git" false - # The destination must contain exactly the branch and the tag. + # The destination must contain exactly the branches and tags, + # including the nested (slashed) ones, and nothing else. got="$(git --git-dir="$base/dest.git" for-each-ref --format '%(refname)' | sort | tr '\n' ' ')" echo "Destination refs: $got" - test "$got" = "refs/heads/main refs/tags/v1 " + test "$got" = "refs/heads/feature/foo refs/heads/main refs/tags/release/1.0.0 refs/tags/v1 " diff --git a/CHANGELOG.md b/CHANGELOG.md index 6510978..308f857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.3.1] - 2026-07-21 + +### Fixed +* Mirror branches and tags with slashes in their name (e.g. `feature/foo`), which 1.3.0 unintentionally dropped. + ## [1.3.0] - 2026-07-20 ### Changed @@ -19,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added * Initial release. +[1.3.1]: https://github.com/wearerequired/git-mirror-action/compare/v1.3.0...v1.3.1 [1.3.0]: https://github.com/wearerequired/git-mirror-action/compare/v1.2.0...v1.3.0 [1.0.1]: https://github.com/wearerequired/git-mirror-action/compare/v1.0.0...v1.1.0 [1.0.0]: https://github.com/wearerequired/git-mirror-action/compare/26c99373bfd4beb7811a3fd8a068ec944dadedcc...v1.0.0 diff --git a/git-mirror.sh b/git-mirror.sh index 66dfe57..4f76b0c 100755 --- a/git-mirror.sh +++ b/git-mirror.sh @@ -19,8 +19,13 @@ git fetch -p origin # Only mirror branches and tags. GitHub advertises additional hidden refs # (e.g. refs/pull/*, refs/github-services/*) that destinations such as GitLab, # Bitbucket or Codeup reject, which fails the whole mirror push. +# +# The exclude patterns are given without a glob so they match the whole +# namespace: a bare "refs/heads" matches every ref below it, whereas +# "refs/heads/*" would only match one level and drop nested refs such as +# refs/heads/feature/foo. git for-each-ref --format 'delete %(refname)' \ - --exclude 'refs/heads/*' --exclude 'refs/tags/*' refs \ + --exclude refs/heads --exclude refs/tags refs \ | git update-ref --stdin if [ "$DRY_RUN" = "true" ]