Skip to content

Commit

Permalink
chore: use --force for running git checkout to prevent issues like #530
Browse files Browse the repository at this point in the history
… (#536)

Signed-off-by: Trong Nhan Mai <[email protected]>
  • Loading branch information
tromai authored Nov 3, 2023
1 parent ec4e190 commit 44c07b4
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 45 deletions.
5 changes: 5 additions & 0 deletions docs/source/pages/using.rst
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ An example configuration file for utilising this feature:
Analyzing a locally cloned repository
-------------------------------------

.. warning::
During the analysis, Macaron can check out different commits, which can reset the index and working tree of the repository.
Therefore, any uncommitted changes in the repository need to be backed up to prevent loss (these include unstaged changes, staged changes and untracked files).
However, Macaron will not modify the history of the repository.

If you have a local repository that you want to analyze, Macaron also supports running the analysis against a local repository.

Assume that the dir tree at the local repository has the following components:
Expand Down
4 changes: 0 additions & 4 deletions src/macaron/slsa_analyzer/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,10 +695,6 @@ def _prepare_repo(
logger.error("The target repository does not have any commit.")
return None

if not git_url.reset_git_repo(git_obj):
logger.error("Cannot reset the target repository.")
return None

# Checking out the specific branch or commit. This operation varies depends on the git service that the
# repository uses.
if not is_remote:
Expand Down
45 changes: 4 additions & 41 deletions src/macaron/slsa_analyzer/git_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,45 +25,6 @@
logger: logging.Logger = logging.getLogger(__name__)


def reset_git_repo(git_obj: Git, stash: bool = True, index: bool = True, working_tree: bool = True) -> bool:
"""Reset the index and working tree of the target repository.
Note that this method does not reset any untracked or ignored files.
Parameters
----------
git_obj : Git
The pydriller.Git object of the repository.
stash : bool
If True, any uncommitted changes will be stashed.
index : bool
If True, the index of the repository will be reset.
working_tree : bool
If True, the working tree will be forcefully adjusted to match HEAD, possibly overwriting uncommitted changes.
If working_tree is True, index must be true as well.
Returns
-------
bool
True if no errors encountered, else False.
"""
try:
if stash:
logger.info("Stashing any uncommitted changes.")
stash_out = git_obj.repo.git.stash(message="Stashing uncommitted changes by Macaron.")
logger.debug("\t Git CMD output: %s", stash_out)

logger.info("Forcefully reset the repository.")
git_obj.repo.head.reset(index=index, working_tree=working_tree)
return True
except GitCommandError as error:
logger.error("Error while trying to reset untracked changes in the repository: %s", error)
return False
except ValueError as error:
logger.error(error)
return False


def check_out_repo_target(git_obj: Git, branch_name: str = "", digest: str = "", offline_mode: bool = False) -> bool:
"""Checkout the branch and commit specified by the user.
Expand Down Expand Up @@ -123,7 +84,8 @@ def check_out_repo_target(git_obj: Git, branch_name: str = "", digest: str = "",

try:
# Switch to the target branch by running ``git checkout <branch_name>`` in the target repository.
git_obj.repo.git.checkout(res_branch)
# We need to use force checkout to prevent issues similar to https://github.com/oracle/macaron/issues/530.
git_obj.repo.git.checkout("--force", res_branch)
except GitCommandError as error:
logger.error("Cannot checkout branch %s. Error: %s", res_branch, error)
return False
Expand Down Expand Up @@ -153,8 +115,9 @@ def check_out_repo_target(git_obj: Git, branch_name: str = "", digest: str = "",

if digest:
# Checkout the specific commit that the user want by running ``git checkout <commit>`` in the target repository.
# We need to use force checkout to prevent issues similar to https://github.com/oracle/macaron/issues/530.
try:
git_obj.repo.git.checkout(digest)
git_obj.repo.git.checkout("--force", digest)
except GitCommandError as error:
logger.error(
"Commit %s cannot be checked out. Error: %s",
Expand Down

0 comments on commit 44c07b4

Please sign in to comment.