Re: FW: Bug Report: changes to submodule's files can be silently lost forever
- From
Philippe Blain <levraiphilippeblain@gmail.com>
- Date
- Jan 21, 2021, 14:22 UTC
- Message-ID
- <af8020e6-fe8f-1a48-aba9-f3ad9d7084e4@gmail.com>
- In-Reply-To
- <PA4PR08MB60967539EC75C9AACC4C46A5A9A10@PA4PR08MB6096.eurprd08.prod.outlook.com>
Hi Tim!
Le 2021-01-21 à 08:48, Tim Yorke a écrit :
Show 10 quoted lines
> What did you do before the bug happened? (Steps to reproduce your issue) > > - I used the command "git config submodule.recurse true" in my top-level repository > - made a change to a file in a submodule (located within my top-level repository) > - performed a git checkout in the top-level repository to a commit that didn't have the submodule > - performed a git checkout in the top-level repository back to a commit that does have the submodule > > What did you expect to happen? (Expected behavior) > > When attempting the first checkout (i.e. to a commit without the submodule), I'd expect an warning telling me that the submodule was not up-to-date (uncommited changes).
That's indeed very sensible.
Show 11 quoted lines
> > What happened instead? (Actual behavior) > > The changes to the file in the submodule were lost forever without any warning > > What's different between what you expected and what actually happened? > > My uncommitted changes were silently lost forever, whereas I'd expect either > - to be warned before I could continue or > - the uncommited changes to be retained. >
Thanks for the report. This is a known problem ([1], [2], [3]), and I'm working on fixing it.
Just to be sure, the changes you lost were to a tracked file in the submodule, right ? It was not a new, untracked file ?
I'm not quite ready yet to submit my fixes, but if you want to compile Git from source in the meantime, the heart of the fix is this diff:
diff --git a/unpack-trees.c b/unpack-trees.c index 323280dd48..a3e3d98de1 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1872,7 +1872,7 @@ static int verify_uptodate_1(const struct cache_entry *ce, if (submodule_from_ce(ce)) { int r = check_submodule_move_head(ce, - "HEAD", oid_to_hex(&ce->oid), o); + "HEAD", empty_tree_oid_hex(), o); if (r) return add_rejected_path(o, error_type, ce->name); return 0; This should prevent Git from switching branches if any tracked files are modified in the submodule. Cheers, Philippe. [1] https://lore.kernel.org/git/570e77a07f0b4d4ea09307e5fa819d6f@fiveco.ch/t/#u [2] https://lore.kernel.org/git/20200525094019.22padbzuk7ukr5uv@overdrive.tratt.net/ [3] https://lore.kernel.org/git/CAHsG2VT4YB_nf8PrEmrHwK-iY-AQo0VDcvXGVsf8cEYXws4nig@mail.gmail.com/