I have a git branch which started to exhibit the inability to do even trivial rebases going back past a certain point, claiming that many commits had just vanished - and in debugging that issue, I found a simpler anomaly.
git log
gives me a perfectly consistent list of the commits I expect to see. And if I use git reset --hard HEAD^
to move backwards in the commits one at a time, everything works as expected - until suddenly I just back over a dozen commits with no warning at all.
I start from this commit with ID 367df61041c380b3e769177779cb7c8ab21630b4, and a git log that looks like:
367df61 fixing flake8/syntax errors
14210b8 Merge remote-tracking branch 'origin/dev' into dev
a6818d5 Merge pull request #55 from rec/fast-gamma
e8ffdf2 Tweak exit manager code (fix #56). Please enter the commit message for your changes. Lines starting
d1c464c Tweak masterBrightness.
975de68 Re-enable timedata end-to-end.
bf7e918 Add optional timedata.Renderer to driver_base.py.
b4daff6 Simplify _render slightly.
a306798 Stop slicing colors and add an offset instead.
b379f21 Move generate_header into util.
e50ec8c Simplify frame rendering slightly.
12cfc2d Extract data and functions into return_codes.py
764e4b9 Convert LDP8806.py from DOS line endings to Unix.
d3dc333 Remove old gamma tables.
5ae2934 Simplify gamma.py; prove backward compatibility.
bae1cf4 Temporarily disable timedata and simplify rendering.
c436f19 showing timedata usage
5228261 updating colors.py for py3
If I execute git reset --hard HEAD^
one time, I move to 14210b8 Merge remote-tracking branch 'origin/dev' into dev
, as I expect, and the git log
is consistent with the above.
But now, if I execute git reset --hard HEAD^
a second time, I move to c436f19 showing timedata usage
, near the bottom of the above list! All commits between a6818d5
and bae1cf4
inclusive just vanish.
My suspicious eye is drawn to the commit a6818d5a2 which seems to include all those vanished changes.
How did this happen? Perhaps by merging from the wrong base branch or commit ID... but exactly what did we do wrong?
Left to my own devices, I'd revert to some known good commit, and then cherry-pick commits one at a time, skipping the merge completely. It wouldn't be huge amounts of work but I feel there must be a better way.
What's going on? Is this a reasonable state for a branch to be in, and I'm making a mistake using git, or is something "broken"?
If it's broken, how do I fix it? And how do we change our workflow to avoid breaking a branch again?
If it isn't broken, how do we change our git workflow to handle this case?
My answer to 3. - disallow merge commits.
All of these boil down to the single question - given that I have these merges, how do I rebase over them?