Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defend against the waking nightmare that is git submodules #60

Merged
merged 5 commits into from
Jan 4, 2017
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions git.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (s GitRepo) Vcs() Type {

// Get is used to perform an initial clone of a repository.
func (s *GitRepo) Get() error {
out, err := s.run("git", "clone", s.Remote(), s.LocalPath())
out, err := s.run("git", "clone", "--recursive", s.Remote(), s.LocalPath())

// There are some windows cases where Git cannot create the parent directory,
// if it does not already exist, to the location it's trying to create the
Expand Down Expand Up @@ -151,7 +151,8 @@ func (s *GitRepo) Update() error {
if err != nil {
return NewRemoteError("Unable to update repository", err, string(out))
}
return nil

return s.defendAgainstSubmodules()
}

// UpdateVersion sets the version of a package currently checked out via Git.
Expand All @@ -160,6 +161,30 @@ func (s *GitRepo) UpdateVersion(version string) error {
if err != nil {
return NewLocalError("Unable to update checked out version", err, string(out))
}

return s.defendAgainstSubmodules()
}

// defendAgainstSubmodules tries to keep repo state sane in the event of
// submodules. Or nested submodules. What a great idea, submodules.
func (s *GitRepo) defendAgainstSubmodules() error {
// First, update them to whatever they should be, if there should happen to be any.
out, err := s.RunFromDir("git", "submodule", "update", "--init", "--recursive")
if err != nil {
return NewLocalError("Unexpected error while defensively updating submodules", err, string(out))
}
// Now, do a special extra-aggressive clean in case changing versions caused
// one or more submodules to go away.
out, err = s.RunFromDir("git", "clean", "-x", "-d", "-f", "-f")
if err != nil {
return NewLocalError("Unexpected error while defensively cleaning up after possible derelict submodule directories", err, string(out))
}
// Then, repeat just in case there are any nested submodules that went away.
out, err = s.RunFromDir("git", "submodule", "foreach", "--recursive", "clean", "-x", "-d", "-f", "-f")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you experience the issue where a nested submodule wen't away from the git clean? I'm curious of the motivation to run this command again.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the same command, but run against all submodules, recursively. If we submodule A@v1, and A@v1 submodules B. If we switch our version to something that submodules A@v2, which does NOT submodule B, then there'll be a derelict A/B dir that needs to be cleaned up. The first git clean won't get it, because it doesn't recurse - only this second one will.

if err != nil {
return NewLocalError("Unexpected error while defensively cleaning up after possible derelict nested submodule directories", err, string(out))
}

return nil
}

Expand Down Expand Up @@ -359,6 +384,12 @@ func (s *GitRepo) ExportDir(dir string) error {
if err != nil {
return NewLocalError("Unable to export source", err, string(out))
}
// and now, the horror of submodules
out, err = s.RunFromDir("git", "submodule", "foreach", "--recursive", "'git checkout-index -f -a --prefix=\""+filepath.Join(dir, "$path")+"\"'")
s.log(out)
if err != nil {
return NewLocalError("Error while exporting submodule sources", err, string(out))
}

return nil
}
Expand Down