From 54f6595dd0ce39930288adf53bfb0fdfd531de89 Mon Sep 17 00:00:00 2001 From: Robert Lowry Date: Mon, 7 Sep 2020 19:22:27 -0500 Subject: [PATCH 1/5] scm: add "autostage" config option to stage files automatically Fixes #4330 --- dvc/config.py | 1 + dvc/repo/scm_context.py | 8 ++++++-- dvc/scm/base.py | 5 +++++ dvc/scm/git.py | 9 +++++++++ tests/unit/scm/test_scm.py | 17 +++++++++++++++++ 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/dvc/config.py b/dvc/config.py index 0f1bafac67..8a4904bd00 100644 --- a/dvc/config.py +++ b/dvc/config.py @@ -137,6 +137,7 @@ class RelPath(str): Optional("analytics", default=True): Bool, Optional("hardlink_lock", default=False): Bool, Optional("no_scm", default=False): Bool, + Optional("autostage", default=False): Bool, Optional("experiments", default=False): Bool, Optional("check_update", default=True): Bool, }, diff --git a/dvc/repo/scm_context.py b/dvc/repo/scm_context.py index c0b0ffb5b5..6e1516a42f 100644 --- a/dvc/repo/scm_context.py +++ b/dvc/repo/scm_context.py @@ -3,8 +3,12 @@ def run(repo, *args, **kw): try: result = method(repo, *args, **kw) repo.scm.reset_ignores() - repo.scm.remind_to_track() - repo.scm.reset_tracked_files() + auto_stage = repo.config.get("core", {}).get("autostage", False) + if auto_stage: + repo.scm.track_changed_files() + else: + repo.scm.remind_to_track() + repo.scm.reset_tracked_files() return result except Exception: repo.scm.cleanup_ignores() diff --git a/dvc/scm/base.py b/dvc/scm/base.py index 1bde8f7443..699c602e69 100644 --- a/dvc/scm/base.py +++ b/dvc/scm/base.py @@ -154,6 +154,11 @@ def remind_to_track(self): Method to remind user to track newly created files handled by scm """ + def track_changed_files(self): + """ + Method to stage files that have changed + """ + def track_file(self, path): """ Method to add file to mechanism that will remind user diff --git a/dvc/scm/git.py b/dvc/scm/git.py index b777488ac8..f743092713 100644 --- a/dvc/scm/git.py +++ b/dvc/scm/git.py @@ -381,6 +381,15 @@ def remind_to_track(self): "\tgit add {files}".format(files=files) ) + def track_changed_files(self): + if not self.files_to_track: + return + + self.add(self.files_to_track) + self.reset_tracked_files() + + logger.info("\nChanges staged to git.") + def track_file(self, path): self.files_to_track.add(path) diff --git a/tests/unit/scm/test_scm.py b/tests/unit/scm/test_scm.py index 4fb590fc54..3dd020966f 100644 --- a/tests/unit/scm/test_scm.py +++ b/tests/unit/scm/test_scm.py @@ -9,6 +9,7 @@ class TestScmContext(TestCase): def setUp(self): + self.repo_mock = mock.Mock(spec=Repo) self.scm_mock = mock.Mock(spec=NoSCM) self.repo_mock.scm = self.scm_mock @@ -17,6 +18,8 @@ def test_should_successfully_perform_method(self): method = mock.Mock() wrapped = scm_context(method) + config_noautostage_attrs = {"config": {"core": {"autostage": False}}} + self.repo_mock.configure_mock(**config_noautostage_attrs) wrapped(self.repo_mock) self.assertEqual(1, method.call_count) @@ -25,6 +28,20 @@ def test_should_successfully_perform_method(self): self.assertEqual(0, self.scm_mock.cleanup_ignores.call_count) + def test_should_check_autostage(self): + method = mock.Mock() + wrapped = scm_context(method) + + config_autostage_attrs = {"config": {"core": {"autostage": True}}} + self.repo_mock.configure_mock(**config_autostage_attrs) + wrapped(self.repo_mock) + + self.assertEqual(1, method.call_count) + self.assertEqual(1, self.scm_mock.reset_ignores.call_count) + self.assertEqual(1, self.scm_mock.track_changed_files.call_count) + + self.assertEqual(0, self.scm_mock.cleanup_ignores.call_count) + def test_should_throw_and_cleanup(self): method = mock.Mock(side_effect=Exception("some problem")) wrapped = scm_context(method) From 2ad1e51d71405d36e939e8e6f41ebbe6d653a03b Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Sun, 13 Sep 2020 04:14:06 +0300 Subject: [PATCH 2/5] Update tests/unit/scm/test_scm.py --- tests/unit/scm/test_scm.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/scm/test_scm.py b/tests/unit/scm/test_scm.py index 3dd020966f..e86dd3f140 100644 --- a/tests/unit/scm/test_scm.py +++ b/tests/unit/scm/test_scm.py @@ -9,7 +9,6 @@ class TestScmContext(TestCase): def setUp(self): - self.repo_mock = mock.Mock(spec=Repo) self.scm_mock = mock.Mock(spec=NoSCM) self.repo_mock.scm = self.scm_mock From 2fc37d2caf33280b0a25a76c3a6c14aa3326c25b Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Sun, 13 Sep 2020 04:23:14 +0300 Subject: [PATCH 3/5] Update tests/unit/scm/test_scm.py --- tests/unit/scm/test_scm.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/unit/scm/test_scm.py b/tests/unit/scm/test_scm.py index e86dd3f140..1121d4df5c 100644 --- a/tests/unit/scm/test_scm.py +++ b/tests/unit/scm/test_scm.py @@ -17,8 +17,7 @@ def test_should_successfully_perform_method(self): method = mock.Mock() wrapped = scm_context(method) - config_noautostage_attrs = {"config": {"core": {"autostage": False}}} - self.repo_mock.configure_mock(**config_noautostage_attrs) + self.repo_mock.configure_mock(config={}) wrapped(self.repo_mock) self.assertEqual(1, method.call_count) From 61aeeb9bc9ce2a1910af9ad94038f00aceaa66bd Mon Sep 17 00:00:00 2001 From: Robert Lowry Date: Sat, 12 Sep 2020 20:47:12 -0500 Subject: [PATCH 4/5] scm_context, git: call reset_tracked_files from scm_context, remove output message --- dvc/repo/scm_context.py | 2 +- dvc/scm/git.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/dvc/repo/scm_context.py b/dvc/repo/scm_context.py index 6e1516a42f..a1c06f2cdb 100644 --- a/dvc/repo/scm_context.py +++ b/dvc/repo/scm_context.py @@ -8,7 +8,7 @@ def run(repo, *args, **kw): repo.scm.track_changed_files() else: repo.scm.remind_to_track() - repo.scm.reset_tracked_files() + repo.scm.reset_tracked_files() return result except Exception: repo.scm.cleanup_ignores() diff --git a/dvc/scm/git.py b/dvc/scm/git.py index f743092713..a3317218ea 100644 --- a/dvc/scm/git.py +++ b/dvc/scm/git.py @@ -386,9 +386,6 @@ def track_changed_files(self): return self.add(self.files_to_track) - self.reset_tracked_files() - - logger.info("\nChanges staged to git.") def track_file(self, path): self.files_to_track.add(path) From c8531aef75bbbc67a4f7ba47c9675f9788aab0c2 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Sun, 13 Sep 2020 04:57:04 +0300 Subject: [PATCH 5/5] Update dvc/repo/scm_context.py --- dvc/repo/scm_context.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dvc/repo/scm_context.py b/dvc/repo/scm_context.py index a1c06f2cdb..ec9585bb7f 100644 --- a/dvc/repo/scm_context.py +++ b/dvc/repo/scm_context.py @@ -3,8 +3,8 @@ def run(repo, *args, **kw): try: result = method(repo, *args, **kw) repo.scm.reset_ignores() - auto_stage = repo.config.get("core", {}).get("autostage", False) - if auto_stage: + autostage = repo.config.get("core", {}).get("autostage", False) + if autostage: repo.scm.track_changed_files() else: repo.scm.remind_to_track()