Zsar
Zsar

Reputation: 445

Weird submodule bug in git 2.39.5 on Debian 12 - help to reproduce

I managed to corrupt one of my local repositories into thinking a newer submodule commit was associated with several older commits, all created before the submodule commit itself.

This behaviour looks like a great way to silently corrupt one's work state (including, if it happens on a CI/CD server, potentially artifacts built from said state), so I'd consider it of pretty high impact. Unfortunately, I cannot make it happen again.

Three repositories were involved, 'library', 'app A', 'app B'. 'library' is a submodule in both 'app [A|B]' branches.
On each repository, a feature branch existed:

In both 'app-[a|b]-feature' branches, the submodule pointed to library/main at the moment of forking, as the library-feature is a soft dependency. (For testing, I checked out 'library-feature' but never committed it.)

For all commits of my 'app-[a|b]-feature' branches, the submodule commit was 12973e39da77f7efecfa30d016909d8b0c01badc, from the 'main' branch of the 'library'.

I merged my 'library-feature' branch, resulting in a new merge commit on 'main', d0542deed57e204e5ae74795aad77773f72734c0 . Before merging the 'app-[a|b]-feature' branches, I went to update their respective submodule, so they will actually use the library-feature when checked out.

In app A

  1. I rebased interactively to edit the commit where I first used the soft dependency
  2. in the submodule
    git checkout main
    git pull
  3. amended the commit with the resulting submodule change
  4. git rebase --continue
  5. git diff origin/app-a-feature..HEAD displayed, as expected, exactly the submodule change from 12973e39da77f7efecfa30d016909d8b0c01badc to d0542deed57e204e5ae74795aad77773f72734c0.

Here, all had gone well.

In app B

  1. Accidentally did step 2 first. I figured: None of my commits touches the submodule, so I can just rebase without restoring it.
  2. I rebased like I did in app A. Now git status showed no changes.
  3. In the submodule, I tried to git checkout main and git checkout d0542deed57e204e5ae74795aad77773f72734c0, but both concurred: I was already there. So did git log -1 in the submodule and the file changes themselves were also present.
  4. git rebase --abort - git status still showed no changes and yet the submodule was still on d0542deed57e204e5ae74795aad77773f72734c0.
  5. I checked out the first commit of 'app-b-feature', which had not even been included in the aborted rebase - git status still showed no changes and yet the submodule was still on d0542deed57e204e5ae74795aad77773f72734c0.

Somehow I got my index corrupted. Only by re-cloning the 'app B' repository did I manage to resolve the inconsistency - and unfortunately I brainfarted and deleted the original first, so I cannot git bugreport now.

I tried to MVE with local, empty repositories, but these steps do not reproduce the issue:

  1. git init application
    git init library
  2. cd library
    git commit --allow-empty -m init
    git checkout -b library-feature
    git commit --allow-empty -m 'feature change'
  3. cd ../application
    git commit --allow-empty -m init
    git submodule add -b master ../library library-module
    git commit -m 'add submodule'
    git commit --allow-empty -m 'unrelated change'
  4. cd library-module
    git checkout library-feature
    cd ..
  5. git rebase -i HEAD~1
    e <hash> unrelated change : empty
    git status - submodule change visible and unstaged
  6. git rebase --abort
    git status - submodule change visible and unstaged

With my newly cloned real 'app B' repository I then tried to reproduce the original fault "on real data", but this time everything simply worked fine.

Upvotes: 0

Views: 48

Answers (0)

Related Questions