MSDyn365BC.Sandbox.Code.History - Late Hotfix Handling
You might have noticed some divergent branch errors when trying to pull from the MSDyn365BC.Sandbox.Code.History repository lately. I am going to explain what the hell is going on, and how to solve it ;)
The Problem
As mentioned in Issue #4, tracking changes in the repository was becoming increasingly difficult. Microsoft occasionally releases hotfix versions with version numbers lower than already-published versions. For example:
- Version
27.1.40348
gets committed to the repository - A few days later, Microsoft releases version
27.0.40357
(a lower version number!) - The old script would just commit this chronologically, creating confusing history
This resulted in:
- Convoluted commit graphs with versions appearing out of semantic order
- Difficulty comparing changes between versions
- Massive diffs from out-of-order commits bloating the repository size
git blame
showing versions in illogical order
What Changed
I modified the automation scripts to detect late hotfixes and insert them at the correct position in git history using git rebase
.
How it works
When a new version arrives, the script now:
- Compares it against the current branch HEAD
- If the incoming version is lower than HEAD, it’s detected as a late hotfix
- Parses all existing versions on the branch to find the correct insertion point
- Checks out the commit this should come after
- Extracts and commits the hotfix at that position
- Rebases all subsequent commits onto the new hotfix commit
- Force-pushes with
--force-with-lease
to update the remote branch
This means:
- Git history now shows versions in proper semantic order
- Repository size is reduced by avoiding massive diffs from out-of-order commits
- Standard git operations like
git log
,git blame
, andgit diff
work as expected - The entire process runs automatically in both regular and vNext workflows
The History Was Rewritten
⚠️ IMPORTANT: Branch history may be rewritten when late hotfixes are released by Microsoft.
Since this uses git rebase
, branch history will be rewritten when late hotfixes are inserted. This is the same situation as when I previously updated the OnPrem repository with new features.
WARNING: Do not try this at home! Ehm.. I mean in your real git repository. :) Rewriting git commits and force pushing them is really bad practice and can be dangerous! But for a read-only tracking repository like this one, the benefits outweigh the trade-offs.
But How to Fix It?
If you have an existing clone and a branch gets rebased, your local copy will become outdated and git pull
will fail with “divergent branches” errors.
Automated Solution
I created convenient scripts to automatically update all your local branches:
Linux/macOS (one-liner):
curl -sSL https://raw.githubusercontent.com/StefanMaron/MSDyn365BC.Sandbox.Code.History/main/scripts/update-branches.sh | bash
Windows (PowerShell one-liner):
irm https://raw.githubusercontent.com/StefanMaron/MSDyn365BC.Sandbox.Code.History/main/scripts/Update-Branches.ps1 | iex
Both scripts:
- Automatically detect all your locally tracked branches
- Fetch latest changes from origin
- Reset each branch to match the remote
- Support wildcard patterns and dry-run mode
You can also download and run the scripts locally for more control:
# Update all tracked branches
.\Update-Branches.ps1
# Update specific branches
.\Update-Branches.ps1 -branches w1-24,w1-25,de-24
# Update using wildcards
.\Update-Branches.ps1 -branches w1-*
# Preview what would change
.\Update-Branches.ps1 -DryRun
Manual Fix for a Single Branch
Well, the easiest way would be to just delete your local clone and clone it again. But if you have only checked out a few branches and you really want to just reset those, then you can use this command:
git fetch origin
git checkout <branch-name>
git reset --hard origin/<branch-name>
The README
I tried to explain all the rest in the README of the repository.
https://github.com/StefanMaron/MSDyn365BC.Sandbox.Code.History/blob/main/README.md
Here are some parts I want to highlight:
Why Rewrite History?
- Maintains correct semantic version order in commit history
- Reduces repository size by avoiding large diffs from out-of-order commits
- Makes version comparison and git blame more intuitive
- This is acceptable for a read-only tracking repository
Partial Clone
To reduce the size of your local clone you can use those commands to clone only the branches you need:
git clone -b w1-24 --single-branch https://github.com/StefanMaron/MSDyn365BC.Sandbox.Code.History
Or use shallow clones to fetch only recent commits:
git clone -b w1-24 --depth 1 https://github.com/StefanMaron/MSDyn365BC.Sandbox.Code.History
I hope these improvements make the repository more useful for tracking BC version changes! If you encounter any issues or have suggestions, feel free to open an issue.