bisect-kit: delete unexpected files in source tree
cros_mark_as_stable may make the tree dirty. We should recover the tree
state otherwise further bisections may fail forever.
BUG=b:131459909, b:131803654, b:139040320
TEST=switch_cros_localbuild.py R75-12107.0.0 twice
Change-Id: I1d7d271786f5c52c946be06f1df84f497585142e
Reviewed-on: https://chromium-review.googlesource.com/1782358
Tested-by: Kuang-che Wu <kcwu@chromium.org>
Commit-Ready: Kuang-che Wu <kcwu@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Chung-yih Wang <cywang@google.com>
diff --git a/bisect_kit/git_util.py b/bisect_kit/git_util.py
index 59d9565..d40f69a 100644
--- a/bisect_kit/git_util.py
+++ b/bisect_kit/git_util.py
@@ -8,6 +8,7 @@
import logging
import os
import re
+import shutil
import subprocess
import time
@@ -406,6 +407,68 @@
return result or None
+def reset_hard(git_repo):
+ """Restore modified and deleted files.
+
+ This is simply wrapper of "git reset --hard".
+
+ Args:
+ git_repo: path of git repo.
+ """
+ util.check_call('git', 'reset', '--hard', cwd=git_repo)
+
+
+def list_untracked(git_repo, excludes=None):
+ """List untracked files and directories.
+
+ Args:
+ git_repo: path of git repo.
+ excludes: files and/or directories to ignore, relative to git_repo
+
+ Returns:
+ list of paths, relative to git_repo
+ """
+ exclude_flags = []
+ if excludes:
+ for exclude in excludes:
+ assert not os.path.isabs(exclude), 'should be relative'
+ exclude_flags += ['--exclude', '/' + re.escape(exclude)]
+
+ result = []
+ for path in util.check_output(
+ 'git',
+ 'ls-files',
+ '--others',
+ '--exclude-standard',
+ *exclude_flags,
+ cwd=git_repo).splitlines():
+ # Remove the trailing slash, which means directory.
+ path = path.rstrip('/')
+ result.append(path)
+ return result
+
+
+def distclean(git_repo, excludes=None):
+ """Clean up git repo directory.
+
+ Restore modified and deleted files. Delete untracked files.
+
+ Args:
+ git_repo: path of git repo.
+ excludes: files and/or directories to ignore, relative to git_repo
+ """
+ reset_hard(git_repo)
+
+ # Delete untracked files.
+ for untracked in list_untracked(git_repo, excludes=excludes):
+ path = os.path.join(git_repo, untracked)
+ logger.debug('delete untracked: %s', path)
+ if os.path.isdir(path):
+ shutil.rmtree(path)
+ else:
+ os.unlink(path)
+
+
def get_history(git_repo,
path,
branch=None,