dvc: add 'merge' command

Fixes #246

Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
Ruslan Kuprieiev
2017-10-17 16:15:15 +03:00
parent 4e98ce38bf
commit 51cce677ce
3 changed files with 79 additions and 0 deletions
+8
View File
@@ -16,6 +16,7 @@ from dvc.command.show_workflow import CmdShowWorkflow
from dvc.command.instance_create import CmdInstanceCreate
from dvc.command.config import CmdConfig
from dvc.command.show_pipeline import CmdShowPipeline
from dvc.command.merge import CmdMerge
from dvc import VERSION
@@ -407,6 +408,13 @@ def parse_args(argv=None):
workflow_parser.set_defaults(func=CmdShowWorkflow)
# Merge
merge_parser = subparsers.add_parser(
'merge',
parents=[parent_parser],
help='Merge')
merge_parser.set_defaults(func=CmdMerge)
if isinstance(argv, str):
argv = argv.split()
+55
View File
@@ -0,0 +1,55 @@
import json
from dvc.command.base import CmdBase, DvcLock
from dvc.logger import Logger
from dvc.state_file import StateFile
from dvc.path.data_item import NotInDataDirError
class CmdMerge(CmdBase):
def __init__(self, settings):
super(CmdMerge, self).__init__(settings)
def print_info(self, targets):
for fname in targets:
Logger.info('Restored original data after merge:')
Logger.info(' {}'.format(fname))
def collect_targets(self):
targets = []
flist = self.git.get_last_merge_changed_files()
for fname in flist:
try:
item = self.settings.path_factory.data_item(fname)
except NotInDataDirError:
continue
try:
state = StateFile.load(item, self.git)
except Exception as ex:
Logger.error('Failed to load state file for {}'.format(fname), exc_info=True)
return None
if not state.command == StateFile.COMMAND_IMPORT_FILE:
continue
targets.append(fname)
return targets
def checkout_targets(self, targets):
for fname in targets:
self.git.checkout_file_before_last_merge(fname)
msg = 'DVC merge files: {}'.format(' '.join(targets))
self.commit_if_needed(msg)
def run(self):
with DvcLock(self.is_locker, self.git):
targets = self.collect_targets()
if not targets:
return 1
self.checkout_targets(targets)
self.print_info(targets)
return 0
+16
View File
@@ -253,6 +253,22 @@ class GitWrapper(GitWrapperI):
except ExecutorError:
return None
@staticmethod
def get_last_merge_changed_files():
cmd = 'git diff --name-only @{1}'
Logger.debug('[dvc-git] Get last merge changed files. Command: {}'.format(cmd))
try:
fstr = Executor.exec_cmd_only_success(cmd.split())
return fstr.split('\n')
except ExecutorError:
return None
@staticmethod
def checkout_file_before_last_merge(fname):
cmd = 'git checkout @{1} -- ' + fname
Logger.debug('[dvc-git] Checkout file {} before last merge. Command: {}'.format(fname, cmd))
Executor.exec_cmd_only_success(cmd.split())
def separate_dependency_files_and_dirs(self, code_dependencies):
code_files = []
code_dirs = []