threads / bug / 47116

Bug report: git reset --hard does not fix submodule worktree

Subject: Bug report: git reset --hard does not fix submodule worktree

## tl;dr

2 messages between Nov 4, 2017 and Nov 6, 2017.

replies: 1people: 2as markdown or json

Billy O'Neal (VC LIBS)· Nov 4, 2017, 00:46 UTC · lore
Hello, Git folks. I managed to accidentally break the our test lab by attempting to git mv a directory with a submodule inside. It seems like if a reset does an undo on a mv, the workfold entry should be fixed to put the submodule in its old location. Consider the following sequence of commands:

Setup a git repo with a submodule: mkdir metaproject mkdir upstream cd metaproject git init cd ..\upstream git init echo hello > test.txt git add -A git commit -m "an example commit" cd ..\metapoject mkdir start git submodule add ../upstream start/upstream git add -A git commit -m "Add submodule in start/upstream."

Move the directory containing the submodule: git mv start target git add -A git commit -m "Moved submodule parent directory."

Check that the worktree got correctly fixed by git mv; this output is as expected:
type .git\modules\start\upstream\config
[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true
        worktree = ../../../../target/upstream
[remote "origin"]
        url = C:/Users/bion/Desktop/upstream
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
Now try to go back to the previous commit using git reset --hard:
git log --oneline
 1f560be (HEAD -> master) Moved submodule parent directory.
 a5977ce Add submodule in start/upstream.
git reset --hard a5977ce
 warning: unable to rmdir target/upstream: Directory not empty
 HEAD is now at a5977ce Add submodule in start/upstream.
Check that the worktree got fixed correctly; it did not:
type .git\modules\start\upstream\config
[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true
        worktree = ../../../../target/upstream
[remote "origin"]
        url = C:/Users/bion/Desktop/upstream
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
Is git reset intended to put the submodule in the right place? If not, is there a command we can run before/after reset to restore consistency?
Thanks folks!
Billy O'Neal
Stefan Beller· Nov 6, 2017, 20:50 UTC · re: Billy O'Neal (VC LIBS) · lore

Re: Bug report: git reset --hard does not fix submodule worktree

On Fri, Nov 3, 2017 at 5:46 PM, Billy O'Neal (VC LIBS) <bion@microsoft.com> wrote:

Show 68 quoted lines
> Hello, Git folks. I managed to accidentally break the our test lab by attempting to git mv a directory with a submodule inside. It seems like if a reset does an undo on a mv, the workfold entry should be fixed to put the submodule in its old location. Consider the following sequence of commands:
>
> Setup a git repo with a submodule:
> mkdir metaproject
> mkdir upstream
> cd metaproject
> git init
> cd ..\upstream
> git init
> echo hello > test.txt
> git add -A
> git commit -m "an example commit"
> cd ..\metapoject
> mkdir start
> git submodule add ../upstream start/upstream
> git add -A
> git commit -m "Add submodule in start/upstream."
>
> Move the directory containing the submodule:
> git mv start target
> git add -A
> git commit -m "Moved submodule parent directory."
>
> Check that the worktree got correctly fixed by git mv; this output is as expected:
> type .git\modules\start\upstream\config
> [core]
>         repositoryformatversion = 0
>         filemode = false
>         bare = false
>         logallrefupdates = true
>         symlinks = false
>         ignorecase = true
>         worktree = ../../../../target/upstream
> [remote "origin"]
>         url = C:/Users/bion/Desktop/upstream
>         fetch = +refs/heads/*:refs/remotes/origin/*
> [branch "master"]
>         remote = origin
>         merge = refs/heads/master
>
> Now try to go back to the previous commit using git reset --hard:
> git log --oneline
>  1f560be (HEAD -> master) Moved submodule parent directory.
>  a5977ce Add submodule in start/upstream.
> git reset --hard a5977ce
>  warning: unable to rmdir target/upstream: Directory not empty
>  HEAD is now at a5977ce Add submodule in start/upstream.
>
> Check that the worktree got fixed correctly; it did not:
> type .git\modules\start\upstream\config
> [core]
>         repositoryformatversion = 0
>         filemode = false
>         bare = false
>         logallrefupdates = true
>         symlinks = false
>         ignorecase = true
>         worktree = ../../../../target/upstream
> [remote "origin"]
>         url = C:/Users/bion/Desktop/upstream
>         fetch = +refs/heads/*:refs/remotes/origin/*
> [branch "master"]
>         remote = origin
>         merge = refs/heads/master
>
> Is git reset intended to put the submodule in the right place?
>
> Thanks folks!

git-reset sounds like it ought to put submodules back into another directory. Historically git-reset did not touch submodules at all; a recent release introduced the --recurse-submodules flag for git-reset, which would cover this situation. However that particular situation (with moving the submodules) seems to be not covered yet,

./t7112-reset-submodule.sh ... not ok 69 - git reset --hard: replace submodule with a directory must fail # TODO known breakage

> If not, is there a command we can run before/after reset to restore consistency?
The submodule "fix-it-all" command would be
    git submodule update --init --recursive
IMHO.

← back to recent threads