From: Philippe Blain Date: Thu, 21 Jan 2021 14:22:50 GMT Subject: Re: FW: Bug Report: changes to submodule's files can be silently lost forever Message-ID: In-Reply-To: Hi Tim! Le 2021-01-21 à 08:48, Tim Yorke a écrit : > 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. > > 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/