Skip to content

Commit 3c3cc66

Browse files
feat(core): preserve staged files when editing renku config (#2871)
1 parent 07934a8 commit 3c3cc66

File tree

6 files changed

+45
-10
lines changed

6 files changed

+45
-10
lines changed

renku/command/command_builder/command.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ def with_commit(
414414
commit_if_empty: bool = False,
415415
raise_if_empty: bool = False,
416416
commit_only: Optional[bool] = None,
417+
skip_staging: bool = False,
417418
) -> "Command":
418419
"""Create a commit.
419420
@@ -426,7 +427,7 @@ def with_commit(
426427
"""
427428
from renku.command.command_builder.repo import Commit
428429

429-
return Commit(self, message, commit_if_empty, raise_if_empty, commit_only)
430+
return Commit(self, message, commit_if_empty, raise_if_empty, commit_only, skip_staging)
430431

431432
@check_finalized
432433
def lock_project(self) -> "Command":

renku/command/command_builder/repo.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def __init__(
3535
commit_if_empty: Optional[bool] = False,
3636
raise_if_empty: Optional[bool] = False,
3737
commit_only: Optional[bool] = None,
38+
skip_staging: bool = False,
3839
) -> None:
3940
"""__init__ of Commit.
4041
@@ -49,6 +50,7 @@ def __init__(
4950
self._commit_if_empty = commit_if_empty
5051
self._raise_if_empty = raise_if_empty
5152
self._commit_filter_paths = commit_only
53+
self._skip_staging: bool = skip_staging
5254

5355
def _pre_hook(self, builder: Command, context: dict, *args, **kwargs) -> None:
5456
"""Hook to create a commit transaction.
@@ -65,7 +67,9 @@ def _pre_hook(self, builder: Command, context: dict, *args, **kwargs) -> None:
6567
from renku.core.management.git import prepare_commit
6668

6769
self.diff_before = prepare_commit(
68-
context["client_dispatcher"].current_client, commit_only=self._commit_filter_paths
70+
context["client_dispatcher"].current_client,
71+
commit_only=self._commit_filter_paths,
72+
skip_staging=self._skip_staging,
6973
)
7074

7175
def _post_hook(self, builder: Command, context: dict, result: CommandResult, *args, **kwargs):
@@ -90,6 +94,7 @@ def _post_hook(self, builder: Command, context: dict, result: CommandResult, *ar
9094
commit_empty=self._commit_if_empty,
9195
raise_if_empty=self._raise_if_empty,
9296
commit_message=self._message,
97+
skip_staging=self._skip_staging,
9398
)
9499
except errors.RenkuException as e:
95100
result.error = e

renku/command/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def update_config():
100100
Command()
101101
.command(_update_config)
102102
.require_migration()
103-
.with_commit(commit_if_empty=False, commit_only=CONFIG_LOCAL_PATH)
103+
.with_commit(commit_if_empty=False, commit_only=CONFIG_LOCAL_PATH, skip_staging=True)
104104
.with_database()
105105
)
106106

renku/core/management/git.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@
3838
STARTED_AT = int(time.time() * 1e3)
3939

4040

41-
def prepare_commit(
42-
client,
43-
commit_only=None,
44-
skip_dirty_checks=False,
45-
):
41+
def prepare_commit(client, commit_only=None, skip_dirty_checks=False, skip_staging: bool = False):
4642
"""Gather information about repo needed for committing later on."""
4743
diff_before = set()
4844

45+
if skip_staging:
46+
if not isinstance(commit_only, list) or len(commit_only) == 0:
47+
raise errors.OperationError("Cannot use ``skip_staging`` without specifying files to commit.")
48+
4949
if commit_only == COMMIT_DIFF_STRATEGY:
5050
if len(client.repository.staged_changes) > 0 or len(client.repository.unstaged_changes) > 0:
5151
client.repository.reset()
@@ -73,6 +73,7 @@ def finalize_commit(
7373
raise_if_empty=False,
7474
commit_message=None,
7575
abbreviate_message=True,
76+
skip_staging: bool = False,
7677
):
7778
"""Commit modified/added paths."""
7879
from renku.infrastructure.repository import Actor
@@ -127,8 +128,10 @@ def finalize_commit(
127128
if abbreviate_message:
128129
commit_message = shorten_message(commit_message)
129130

131+
# NOTE: Only commit specified paths when skipping staging area
132+
paths = commit_only if skip_staging else []
130133
# Ignore pre-commit hooks since we have already done everything.
131-
client.repository.commit(commit_message + client.transaction_id, committer=committer, no_verify=True)
134+
client.repository.commit(commit_message + client.transaction_id, committer=committer, no_verify=True, paths=paths)
132135

133136

134137
def prepare_worktree(

renku/infrastructure/repository.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ def commit(
207207
committer: "Actor" = None,
208208
no_verify: bool = False,
209209
no_edit: bool = False,
210+
paths: Optional[List[Union[Path, str]]] = None,
210211
) -> "Commit":
211212
"""Commit added files to the VCS."""
212213
if self._repository is None:
@@ -217,7 +218,12 @@ def commit(
217218
if committer:
218219
env.update({"GIT_COMMITTER_NAME": committer.name, "GIT_COMMITTER_EMAIL": committer.email})
219220

220-
self.run_git_command("commit", message=message, no_verify=no_verify, amend=amend, no_edit=no_edit, env=env)
221+
# NOTE: Only commit specified paths
222+
args = ["--"] + [str(p) for p in paths] if paths else []
223+
224+
self.run_git_command(
225+
"commit", *args, message=message, no_verify=no_verify, amend=amend, no_edit=no_edit, env=env
226+
)
221227

222228
return Commit.from_commit(self._repository, self._repository.head.commit)
223229

tests/cli/test_config.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# See the License for the specific language governing permissions and
1717
# limitations under the License.
1818
"""Test ``config`` command."""
19+
import os
1920
import subprocess
2021
import sys
2122
from threading import Thread
@@ -272,3 +273,22 @@ def test_config_interpolation_is_disabled(client, runner, value):
272273

273274
assert 0 == result.exit_code, format_result_exception(result)
274275
assert f"{value}\n" == result.output
276+
277+
278+
def test_config_commit(client, runner, data_repository, global_config_dir):
279+
"""Test config changes only commits the renku config file."""
280+
commit_sha_before = client.repository.head.commit.hexsha
281+
282+
(client.path / "untracked").write_text("untracked")
283+
(client.path / "staged").write_text("staged")
284+
client.repository.add("staged")
285+
286+
result = runner.invoke(cli, ["config", "set", "key", "value"])
287+
288+
assert 0 == result.exit_code, format_result_exception(result)
289+
assert {os.path.join(".renku", "renku.ini")} == {f.a_path for f in client.repository.head.commit.get_changes()}
290+
assert {"untracked"} == set(client.repository.untracked_files)
291+
assert {"staged"} == {f.a_path for f in client.repository.staged_changes}
292+
293+
commit_sha_after = client.repository.head.commit.hexsha
294+
assert commit_sha_after != commit_sha_before

0 commit comments

Comments
 (0)