diff --git a/project.py b/project.py index 40ca116d..2ba2b766 100644 --- a/project.py +++ b/project.py @@ -1515,6 +1515,7 @@ class Project: self, syncbuf, force_sync=False, + force_checkout=False, submodules=False, errors=None, verbose=False, @@ -1602,7 +1603,7 @@ class Project: syncbuf.info(self, "discarding %d commits", len(lost)) try: - self._Checkout(revid, quiet=True) + self._Checkout(revid, force_checkout=force_checkout, quiet=True) if submodules: self._SyncSubmodules(quiet=True) except GitError as e: @@ -2857,10 +2858,12 @@ class Project: except OSError: return False - def _Checkout(self, rev, quiet=False): + def _Checkout(self, rev, force_checkout=False, quiet=False): cmd = ["checkout"] if quiet: cmd.append("-q") + if force_checkout: + cmd.append("-f") cmd.append(rev) cmd.append("--") if GitCommand(self, cmd).Wait() != 0: diff --git a/subcmds/sync.py b/subcmds/sync.py index c6682a5b..7acb6e5b 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py @@ -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 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 projects with uncommitted changes. WARNING: This may cause data to be 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 " "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( "--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) - 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 Args: 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. project: Project object for the project to checkout. @@ -1011,7 +1029,11 @@ later is required to fix a server side protocol bug. errors = [] try: 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() except GitError as e: @@ -1082,6 +1104,7 @@ later is required to fix a server side protocol bug. self._CheckoutOne, opt.detach_head, opt.force_sync, + opt.force_checkout, opt.verbose, ), projects,