Fix detection of "new migrations" in omarchy-update (#219)

Previously, `omarchy-update` used the timestamp of the most recent git
commit to determine which migrations are "new" and should be executed.

Unfortunately, that strategy can (and did) fail in certain scenarios. If
a migration was generated at time T1 but not merged until time T3, and
meanwhile omarchy's `master` branch was updated to a new release with
commit timestamp T2 (where T1 < T2 < T3), then anyone who runs
`omarchy-update` between T2 and T3 would end up with `last_updated_at`
equal to T2; thus, on their next `omarchy-update` it would fail to
detect the migration with timestamp T1 as a "new" migration that should
be executed.

This commit changes the strategy for detecting "new" migrations to avoid
that problem. Rather than recording the most recent commit's timestamp,
we record its SHA. Then, after pulling the new changes, we can leverage
`git diff --name-only --diff-filter=A $SHA.. migrations/*.sh`
to return precisely the list of migration files that were introduced by
our `git pull`. It doesn't matter if any of those migrations have a
timestamp that was earlier than the timestamp of the commit we started
on - we will always execute *every* migration that didn't exist before
our `git pull`!
This commit is contained in:
Richard Macklin
2025-07-20 15:55:22 -07:00
committed by GitHub
parent dca7e9a8e8
commit f81983ec50

View File

@ -3,11 +3,11 @@
cd ~/.local/share/omarchy cd ~/.local/share/omarchy
if [[ $1 == "all" ]]; then if [[ $1 == "all" ]]; then
# Run all migrations # Run all migrations since the root commit
last_updated_at=1 migration_starting_point=$(git log --max-parents=0 --first-parent --format="%H")
else else
# Remember the version we're at before upgrading # Remember the commit we're at before upgrading in order to only run new migrations
last_updated_at=$(git log -1 --format=%cd --date=unix) migration_starting_point=$(git log -1 --format=%H)
fi fi
# Get the latest while trying to preserve any modifications # Get the latest while trying to preserve any modifications
@ -15,14 +15,12 @@ git pull --autostash
git diff --check || git reset --merge git diff --check || git reset --merge
# Run any pending migrations # Run any pending migrations
for file in migrations/*.sh; do for file in $(git diff --name-only --diff-filter=A $migration_starting_point.. migrations/*.sh); do
filename=$(basename "$file") filename=$(basename "$file")
migrate_at="${filename%.sh}" migrate_at="${filename%.sh}"
if [ $migrate_at -gt $last_updated_at ]; then
echo -e "\e[32m\nRunning migration ($migrate_at)\e[0m" echo -e "\e[32m\nRunning migration ($migrate_at)\e[0m"
source $file source $file
fi
done done
# Back to where we came from # Back to where we came from