sync: introduce --force-checkout

In some cases (e.g. in a CI system), it's desirable to be able to
instruct repo to force checkout. This flag passes --force flag to `git
checkout` operations.

Bug: b/327624021
Change-Id: I579edda546fb8147c4e1a267e2605fcf6e597421
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/411518
Commit-Queue: Josip Sokcevic <sokcevic@google.com>
Reviewed-by: Gavin Mak <gavinmak@google.com>
Reviewed-by: George Engelbrecht <engeg@google.com>
Tested-by: Josip Sokcevic <sokcevic@google.com>
This commit is contained in:
Josip Sokcevic 2024-02-29 09:48:37 -08:00 committed by LUCI
parent 96edb9b573
commit edadb25c02
2 changed files with 31 additions and 5 deletions

View File

@ -1515,6 +1515,7 @@ class Project:
self, self,
syncbuf, syncbuf,
force_sync=False, force_sync=False,
force_checkout=False,
submodules=False, submodules=False,
errors=None, errors=None,
verbose=False, verbose=False,
@ -1602,7 +1603,7 @@ class Project:
syncbuf.info(self, "discarding %d commits", len(lost)) syncbuf.info(self, "discarding %d commits", len(lost))
try: try:
self._Checkout(revid, quiet=True) self._Checkout(revid, force_checkout=force_checkout, quiet=True)
if submodules: if submodules:
self._SyncSubmodules(quiet=True) self._SyncSubmodules(quiet=True)
except GitError as e: except GitError as e:
@ -2857,10 +2858,12 @@ class Project:
except OSError: except OSError:
return False return False
def _Checkout(self, rev, quiet=False): def _Checkout(self, rev, force_checkout=False, quiet=False):
cmd = ["checkout"] cmd = ["checkout"]
if quiet: if quiet:
cmd.append("-q") cmd.append("-q")
if force_checkout:
cmd.append("-f")
cmd.append(rev) cmd.append(rev)
cmd.append("--") cmd.append("--")
if GitCommand(self, cmd).Wait() != 0: if GitCommand(self, cmd).Wait() != 0:

View File

@ -278,6 +278,11 @@ directories if they have previously been linked to a different
object directory. WARNING: This may cause data to be lost since object directory. WARNING: This may cause data to be lost since
refs may be removed when overwriting. refs may be removed when overwriting.
The --force-checkout option can be used to force git to switch revs even if the
index or the working tree differs from HEAD, and if there are untracked files.
WARNING: This may cause data to be lost since uncommitted changes may be
removed.
The --force-remove-dirty option can be used to remove previously used The --force-remove-dirty option can be used to remove previously used
projects with uncommitted changes. WARNING: This may cause data to be projects with uncommitted changes. WARNING: This may cause data to be
lost since uncommitted changes may be removed with projects that no longer lost since uncommitted changes may be removed with projects that no longer
@ -375,6 +380,14 @@ later is required to fix a server side protocol bug.
"point to a different object directory. WARNING: this " "point to a different object directory. WARNING: this "
"may cause loss of data", "may cause loss of data",
) )
p.add_option(
"--force-checkout",
dest="force_checkout",
action="store_true",
help="force checkout even if it results in throwing away "
"uncommitted modifications. "
"WARNING: this may cause loss of data",
)
p.add_option( p.add_option(
"--force-remove-dirty", "--force-remove-dirty",
dest="force_remove_dirty", dest="force_remove_dirty",
@ -991,12 +1004,17 @@ later is required to fix a server side protocol bug.
return _FetchMainResult(all_projects) return _FetchMainResult(all_projects)
def _CheckoutOne(self, detach_head, force_sync, verbose, project): def _CheckoutOne(
self, detach_head, force_sync, force_checkout, verbose, project
):
"""Checkout work tree for one project """Checkout work tree for one project
Args: Args:
detach_head: Whether to leave a detached HEAD. detach_head: Whether to leave a detached HEAD.
force_sync: Force checking out of the repo. force_sync: Force checking out of .git directory (e.g. overwrite
existing git directory that was previously linked to a different
object directory).
force_checkout: Force checking out of the repo content.
verbose: Whether to show verbose messages. verbose: Whether to show verbose messages.
project: Project object for the project to checkout. project: Project object for the project to checkout.
@ -1011,7 +1029,11 @@ later is required to fix a server side protocol bug.
errors = [] errors = []
try: try:
project.Sync_LocalHalf( project.Sync_LocalHalf(
syncbuf, force_sync=force_sync, errors=errors, verbose=verbose syncbuf,
force_sync=force_sync,
force_checkout=force_checkout,
errors=errors,
verbose=verbose,
) )
success = syncbuf.Finish() success = syncbuf.Finish()
except GitError as e: except GitError as e:
@ -1082,6 +1104,7 @@ later is required to fix a server side protocol bug.
self._CheckoutOne, self._CheckoutOne,
opt.detach_head, opt.detach_head,
opt.force_sync, opt.force_sync,
opt.force_checkout,
opt.verbose, opt.verbose,
), ),
projects, projects,