git-sync: also mirror every branch the fork shares with upstream
The fork's copies of long-lived branches (demo-20, totara-19, lms) drifted over a thousand commits behind upstream because only the default branch was ever synced. Fast-forward each branch present on both remotes straight from upstream's ref and push them in one go; skip and warn on divergence, and leave a local copy alone if it carries commits of its own. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
413f680e6e
commit
24cb4c110a
1 changed files with 36 additions and 4 deletions
40
bin/git-sync
40
bin/git-sync
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
# Bring the default branch up to date in a fork-model repo, and keep my fork's
|
||||
# copy of it aligned: fast-forward it from whichever remote owns it, then push
|
||||
# it to origin. Named git-sync and installed on the $PATH, so git finds it as
|
||||
# `git sync`.
|
||||
# it to origin. Then do the same, without checking anything out, for every
|
||||
# other branch the fork mirrors from upstream. Named git-sync and installed on
|
||||
# the $PATH, so git finds it as `git sync`.
|
||||
|
||||
set -e
|
||||
|
||||
|
|
@ -62,6 +63,37 @@ fi
|
|||
# something to look at, not something to paper over.
|
||||
git merge --ff-only $source_remote/$branch
|
||||
|
||||
if [[ $source_remote != origin ]]; then
|
||||
git push origin $branch
|
||||
if [[ $source_remote == origin ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git push origin $branch
|
||||
|
||||
# Every branch that exists on both remotes is one the fork mirrors (release
|
||||
# branches, demo branches), so keep those current too. Branches only on
|
||||
# upstream are colleagues' work, not mine to copy. Nothing is checked out here:
|
||||
# origin is updated straight from upstream's ref, and a local copy is
|
||||
# fast-forwarded in place if there is one.
|
||||
git fetch --prune origin
|
||||
|
||||
refspecs=()
|
||||
for other in $(git for-each-ref --format='%(refname:strip=3)' refs/remotes/$source_remote/); do
|
||||
[[ $other == $branch || $other == HEAD ]] && continue
|
||||
git show-ref --verify --quiet refs/remotes/origin/$other || continue
|
||||
|
||||
if git merge-base --is-ancestor origin/$other $source_remote/$other; then
|
||||
# Fast-forward a local copy too, but leave one with local commits
|
||||
# alone: that is my in-progress work, not drift.
|
||||
if git show-ref --verify --quiet refs/heads/$other &&
|
||||
git merge-base --is-ancestor $other $source_remote/$other; then
|
||||
git fetch . $source_remote/${other}:refs/heads/$other
|
||||
fi
|
||||
refspecs+=("$source_remote/${other}:refs/heads/$other")
|
||||
else
|
||||
echo "git sync: skipping $other - origin has diverged from $source_remote" >&2
|
||||
fi
|
||||
done
|
||||
|
||||
if (( ${#refspecs} )); then
|
||||
git push origin "${refspecs[@]}"
|
||||
fi
|
||||
|
|
|
|||
Loading…
Reference in a new issue