Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 "
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
7 changes: 6 additions & 1 deletion git-mirror.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]
Expand Down