On project cleanup, don't remove nested projects

When there are nested projects in a manifest, like on AOSP right now:

<project path="build" name="platform/build" />
<project path="build/blueprint" name="platform/build/blueprint" />
<project path="build/kati" name="platform/build/kati" />
<project path="build/soong" name="platform/build/soong" />

And the top "build" project is removed (or renamed to remove the
nesting), repo just wipes away everything under build/ and re-creates
the projects that are still there. But it only checks to see if the
build/ project is dirty, so if there are dirty files in a nested
project, they'll just be blown away, and a fresh worktree checked out.

Instead, behave similarly to how `git clean -dxf` behaves and preserve
any subdirectories that have git repositories in them. This isn't as
strict as git -- it does not check to see if the '.git' entry is a
readable gitdir, just whether an entry named '.git' exists.

If it encounters any errors removing files, we'll print them all out to
stderr and tell the user that we were unable to clean up the obsolete
project, that they should clean it up manually, then sync again.

Change-Id: I2f6a7dd205a8e0b7590ca5369e9b0ba21d5a6f77
1 file changed
tree: d28ada6016b8c95898a05bc328267a038566129b
  1. .flake8
  2. .gitattributes
  3. .gitignore
  4. .mailmap
  5. .project
  6. .pydevproject
  8. README.md
  10. color.py
  11. command.py
  12. docs/
  13. editor.py
  14. error.py
  15. git_command.py
  16. git_config.py
  17. git_refs.py
  18. git_ssh
  19. gitc_utils.py
  20. hooks/
  21. main.py
  22. manifest_xml.py
  23. pager.py
  24. progress.py
  25. project.py
  26. pyversion.py
  27. repo
  28. subcmds/
  29. tests/
  30. trace.py
  31. wrapper.py


Repo is a tool built on top of Git. Repo helps manage many Git repositories, does the uploads to revision control systems, and automates parts of the development workflow. Repo is not meant to replace Git, only to make it easier to work with Git. The repo command is an executable Python script that you can put anywhere in your path.