diff --git a/README.md b/README.md index 8f8d6bf..3c8001b 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,22 @@ Merges the latest upstream changes into each midstream branch and pushes. Mergin For each repo it: fetches both remotes → resets the local branch to `midstream/` → merges `origin/` (no fast-forward edits) → updates submodules and commits them → -pushes to `midstream/`. Repos already up-to-date are skipped. +runs the repo's `scripts/post-sync.sh` hook if present (see below) → pushes to +`midstream/`. Repos already up-to-date are skipped. + +### Post-sync hook + +If a managed repo has an executable `scripts/post-sync.sh`, it runs after a successful +merge (or submodule update). Use it to regenerate files derived from upstream content — +e.g. hash-locked `requirements.txt` for Hermeto/Konflux builds, or other midstream-specific +build artifacts. Any tracked-file changes are committed as `post-sync: regenerate +generated files for `. Honors `--no-commit`. A non-zero exit aborts the push and +marks the repo failed. + +Often paired with a `.gitattributes merge=ours` rule so upstream's version of the +generated file doesn't fight the merge. `clone.sh` registers the `ours` driver +(`git config merge.ours.driver true`) on every clone so the attribute actually takes +effect — git ships the merge *strategy* but not the per-file *driver*. ### Flags diff --git a/clone.sh b/clone.sh index c7fa2c2..5e63f06 100755 --- a/clone.sh +++ b/clone.sh @@ -126,6 +126,11 @@ for REPO in $REPOS; do print_status "Using default SSH configuration" fi + # Register the `ours` merge driver so `.gitattributes merge=ours` actually + # takes effect on this clone (git ships the strategy but not the per-file + # driver). Used by overlays whose generated content is regenerated post-sync. + git config merge.ours.driver true + # Check if midstream remote exists if git remote | grep -q "^midstream$"; then print_status "Midstream remote already exists, updating URL..." diff --git a/sync-and-merge.sh b/sync-and-merge.sh index f54e4ff..b0474bb 100755 --- a/sync-and-merge.sh +++ b/sync-and-merge.sh @@ -408,6 +408,22 @@ for REPO in $REPOS; do update_submodules "$REPO" "$BRANCH" fi + # Run repo-specific post-sync hook if present (regenerate lock files, etc.) + if ([ "$NEEDS_UPDATE" = true ] || [ "$NEEDS_SUBMODULE_UPDATE" = true ]) && [ -x "scripts/post-sync.sh" ]; then + print_status "Running scripts/post-sync.sh..." + if ! ./scripts/post-sync.sh; then + print_error "scripts/post-sync.sh failed in $REPO" + cd .. + FAILED_REPOS="$FAILED_REPOS $REPO" + echo "" + continue + fi + if [ -n "$(git status --porcelain)" ] && $COMMIT_CHANGES; then + git add -u + git commit -m "post-sync: regenerate generated files for $BRANCH" + fi + fi + # Push changes if requested (only if we made changes) if [ "$NEEDS_UPDATE" = true ] || [ "$NEEDS_SUBMODULE_UPDATE" = true ]; then if $PUSH_CHANGES; then diff --git a/sync-and-rebase.sh b/sync-and-rebase.sh index ff5e528..fde10ed 100755 --- a/sync-and-rebase.sh +++ b/sync-and-rebase.sh @@ -407,6 +407,22 @@ for REPO in $REPOS; do update_submodules "$REPO" "$BRANCH" fi + # Run repo-specific post-sync hook if present (regenerate lock files, etc.) + if ([ "$NEEDS_UPDATE" = true ] || [ "$NEEDS_SUBMODULE_UPDATE" = true ]) && [ -x "scripts/post-sync.sh" ]; then + print_status "Running scripts/post-sync.sh..." + if ! ./scripts/post-sync.sh; then + print_error "scripts/post-sync.sh failed in $REPO" + cd .. + FAILED_REPOS="$FAILED_REPOS $REPO" + echo "" + continue + fi + if [ -n "$(git status --porcelain)" ] && $COMMIT_CHANGES; then + git add -u + git commit -m "post-sync: regenerate generated files for $BRANCH" + fi + fi + # Push changes if requested (only if we made changes) if [ "$NEEDS_UPDATE" = true ] || [ "$NEEDS_SUBMODULE_UPDATE" = true ]; then if $PUSH_CHANGES; then