From 8435b38a09c1abe1e37556f1ba993a70ca9ff763 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sat, 4 Nov 2017 16:09:53 -0700 Subject: [PATCH 1/2] dvc checkout fix. Close #287 --- dvc/command/checkout.py | 29 +++++++++++++++++++++++++++-- dvc/git_wrapper.py | 12 ++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/dvc/command/checkout.py b/dvc/command/checkout.py index b135642ab..bdc2dd93b 100644 --- a/dvc/command/checkout.py +++ b/dvc/command/checkout.py @@ -4,6 +4,7 @@ from dvc.command.base import CmdBase, DvcLock from dvc.logger import Logger from dvc.system import System + class CmdCheckout(CmdBase): def __init__(self, settings): super(CmdCheckout, self).__init__(settings) @@ -34,6 +35,30 @@ class CmdCheckout(CmdBase): def run(self): with DvcLock(self.is_locker, self.git): - items = self.settings.path_factory.all_existing_data_items() - self.checkout(items) + curr_commit = self.git.curr_commit + prev_items = [] + try: + self.git.checkout_previous() + prev_items = self.settings.path_factory.all_existing_data_items() + except Exception as ex: + Logger.error(u'Unable to get '.format(ex)) + return 1 + finally: + self.git.checkout(curr_commit) + + curr_items = self.settings.path_factory.all_existing_data_items() + self.checkout(curr_items) + + self.remove_files(list(set(prev_items) - set(curr_items))) return 0 + + @staticmethod + def remove_files(removed_items_set): + for item in removed_items_set: + Logger.info(u'Removing data file not from the current branch {}'.format(item.data.relative)) + os.remove(item.data.relative) + dir = os.path.dirname(item.data.relative) + if not os.listdir(dir): + Logger.info(u'Removing directory not from the current branch {}'.format(dir)) + os.removedirs(dir) + pass diff --git a/dvc/git_wrapper.py b/dvc/git_wrapper.py index e142bc8b6..391805ab4 100644 --- a/dvc/git_wrapper.py +++ b/dvc/git_wrapper.py @@ -299,6 +299,18 @@ class GitWrapper(GitWrapperI): Logger.debug('[dvc-git] Checkout file {} before last merge. Command: {}'.format(fname, cmd)) Executor.exec_cmd_only_success(cmd.split()) + @staticmethod + def checkout(commit): + Logger.debug('[dvc-git] Checkout {}'.format(commit)) + cmd = 'git checkout {}'.format(commit) + Executor.exec_cmd(cmd.split()) + + @staticmethod + def checkout_previous(): + Logger.debug('[dvc-git] Checkout previous') + cmd = 'git checkout -' + Executor.exec_cmd(cmd.split()) + def separate_dependency_files_and_dirs(self, code_dependencies): code_files = [] code_dirs = [] From b2f0a7654642c4e65b4520ed418476678ffec14f Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sat, 4 Nov 2017 17:14:44 -0700 Subject: [PATCH 2/2] Checkout branches, not commits if possible --- dvc/command/checkout.py | 6 +++--- dvc/git_wrapper.py | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/dvc/command/checkout.py b/dvc/command/checkout.py index bdc2dd93b..5e9fa3ab9 100644 --- a/dvc/command/checkout.py +++ b/dvc/command/checkout.py @@ -35,7 +35,7 @@ class CmdCheckout(CmdBase): def run(self): with DvcLock(self.is_locker, self.git): - curr_commit = self.git.curr_commit + curr_commit = self.git.curr_branch_or_commit prev_items = [] try: self.git.checkout_previous() @@ -55,10 +55,10 @@ class CmdCheckout(CmdBase): @staticmethod def remove_files(removed_items_set): for item in removed_items_set: - Logger.info(u'Removing data file not from the current branch {}'.format(item.data.relative)) + Logger.info(u'Remove \'{}\''.format(item.data.relative)) os.remove(item.data.relative) dir = os.path.dirname(item.data.relative) if not os.listdir(dir): - Logger.info(u'Removing directory not from the current branch {}'.format(dir)) + Logger.info(u'Remove directory \'{}\''.format(dir)) os.removedirs(dir) pass diff --git a/dvc/git_wrapper.py b/dvc/git_wrapper.py index 391805ab4..29e590dc3 100644 --- a/dvc/git_wrapper.py +++ b/dvc/git_wrapper.py @@ -189,16 +189,33 @@ class GitWrapper(GitWrapperI): raise ExecutorError('Unable to run git command: {}'.format(e)) pass - @property - def curr_commit(self): + def curr_commit(self, branches=False): Logger.debug('[dvc-git] Getting current git commit. Command: git rev-parse --short HEAD') - code, out, err = Executor.exec_cmd(['git', 'rev-parse', 'HEAD']) + if branches: + cmd = 'git rev-parse --abbrev-ref HEAD' + else: + cmd = 'git rev-parse HEAD' + + code, out, err = Executor.exec_cmd(cmd.split()) if code != 0: raise ExecutorError('[dvc-git] Commit command error - {}'.format(err)) Logger.debug('[dvc-git] Getting current git commit. Success.') return out + @property + def curr_branch_or_commit(self): + Logger.debug('[dvc-git] Getting current git branch or commit.') + + branch = self.curr_commit(branches=True) + if branch == '' or branch == 'HEAD': + result = self.curr_commit(branches=False) + else: + result = branch + + Logger.debug('[dvc-git] Getting current git branch or commit. Result {}. Success.'.format(result)) + return result + @staticmethod def commit_all_changes(message): Logger.debug('[dvc-git] Commit all changes. Commands: {} && {} && {}'.format( @@ -217,7 +234,7 @@ class GitWrapper(GitWrapperI): def commit_all_changes_and_log_status(self, message): statuses = self.commit_all_changes(message) Logger.debug('[dvc-git] A new commit {} was made in the current branch. ' - 'Added files:'.format(self.curr_commit)) + 'Added files:'.format(self.curr_commit())) for status, file in statuses: Logger.debug('[dvc-git]\t{} {}'.format(status, file)) pass