diff --git a/bin/josh-sync b/bin/josh-sync index 460821a..cc5414b 100755 --- a/bin/josh-sync +++ b/bin/josh-sync @@ -214,6 +214,18 @@ _sync_direction() { local prev_filter prev_filter=$(echo "$state" | jq -r '.last_forward.josh_filter // empty') + # If no filter stored (pre-v1.2 state) but a previous sync exists, + # the old filter was the simple :/subfolder (before exclude was added) + if [ -z "$prev_filter" ]; then + local prev_mono_sha + prev_mono_sha=$(echo "$state" | jq -r '.last_forward.mono_sha // empty') + if [ -n "$prev_mono_sha" ]; then + local subfolder + subfolder=$(echo "$TARGET_JSON" | jq -r '.subfolder') + prev_filter=":/${subfolder}" + fi + fi + if [ -n "$prev_filter" ] && [ "$prev_filter" != "$JOSH_FILTER" ]; then log "WARN" "Josh filter changed — reconciling histories" log "INFO" "Old: ${prev_filter}" @@ -225,6 +237,13 @@ _sync_direction() { else result=$(reverse_sync) fi + # If forward sync hit unrelated histories, fall back to reconciliation + if [ "$result" = "unrelated" ]; then + log "WARN" "Unrelated histories detected — falling back to filter reconciliation" + result=$(reconcile_filter_change) + log "INFO" "Reconciliation result: ${result}" + fi + log "INFO" "Result: ${result}" # Handle warnings @@ -234,6 +253,7 @@ _sync_direction() { fi if [ "$result" = "conflict" ]; then echo "::warning::Target ${target_name}, branch ${branch}: merge conflict — PR created on subrepo" + continue fi if [ "$result" = "josh-rejected" ]; then echo "::error::Target ${target_name}, branch ${branch}: josh rejected push — check proxy logs" diff --git a/lib/sync.sh b/lib/sync.sh index 48b2136..b2ff277 100644 --- a/lib/sync.sh +++ b/lib/sync.sh @@ -11,7 +11,7 @@ # ─── Forward Sync: Monorepo → Subrepo ────────────────────────────── # -# Returns: fresh | skip | clean | lease-rejected | conflict +# Returns: fresh | skip | clean | lease-rejected | conflict | unrelated forward_sync() { local mono_branch="$SYNC_BRANCH_MONO" @@ -97,7 +97,14 @@ ${BOT_TRAILER}: forward/${mono_branch}/$(date -u +%Y-%m-%dT%H:%M:%SZ)" >&2 fi else - # Conflict! + # Check: unrelated histories (filter change) vs normal merge conflict + if ! git merge-base "subrepo/${subrepo_branch}" "$mono_head" >/dev/null 2>&1; then + log "INFO" "No common ancestor — histories are unrelated (filter change?)" + echo "unrelated" + return + fi + + # Normal merge conflict local conflicted conflicted=$(git diff --name-only --diff-filter=U 2>/dev/null || echo "(unknown)") git merge --abort