Skip to content

Commit e416520

Browse files
committed
New files not part of dfetch diff generated patch
Fixes #886
1 parent 782b36c commit e416520

3 files changed

Lines changed: 70 additions & 4 deletions

File tree

dfetch/project/svn.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
in_directory,
1818
safe_rm,
1919
)
20-
from dfetch.vcs.patch import filter_patch
20+
from dfetch.vcs.patch import combine_patches, filter_patch, unified_diff_new_file
2121

2222
logger = get_logger(__name__)
2323

@@ -379,8 +379,40 @@ def get_diff(
379379
with in_directory(self.local_path):
380380
patch_text = run_on_cmdline(logger, cmd).stdout
381381

382-
return filter_patch(patch_text, ignore)
382+
filtered = filter_patch(patch_text, ignore)
383+
384+
if new_revision:
385+
return filtered
386+
387+
patches: list[bytes] = [filtered.encode("utf-8")] if filtered else []
388+
with in_directory(self.local_path):
389+
for file_path in self._untracked_not_ignored("."):
390+
diff = unified_diff_new_file(pathlib.Path(file_path))
391+
if diff:
392+
patch = [f"Index: {file_path}", "=" * 67] + diff
393+
394+
print(patch)
395+
patches.append("\n".join(patch).encode("utf-8"))
396+
397+
return combine_patches(patches)
383398

384399
def get_default_branch(self) -> str:
385400
"""Get the default branch of this repository."""
386401
return self.DEFAULT_BRANCH
402+
403+
@staticmethod
404+
def _untracked_not_ignored(path: str) -> list[str]:
405+
result = (
406+
run_on_cmdline(
407+
logger,
408+
["svn", "status", "--no-ignore", path],
409+
)
410+
.stdout.decode()
411+
.splitlines()
412+
)
413+
414+
files = []
415+
for line in result:
416+
if line.startswith("?"):
417+
files.append(line[1:].strip())
418+
return files

dfetch/vcs/patch.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Various patch utilities for VCS systems."""
22

3+
import difflib
34
from collections.abc import Sequence
5+
from pathlib import Path
46

57
import patch_ng
68

@@ -35,3 +37,28 @@ def dump_patch(patch_set: patch_ng.PatchSet) -> str:
3537
for line in h.text:
3638
patch_lines.append(line.rstrip(b"\n").decode("utf-8"))
3739
return "\n".join(patch_lines)
40+
41+
42+
def unified_diff_new_file(path: Path) -> list[str]:
43+
"""Create a unified diff for a new file."""
44+
with path.open("r", encoding="utf-8", errors="replace") as new_file:
45+
lines = new_file.readlines()
46+
47+
return list(
48+
difflib.unified_diff(
49+
[], lines, fromfile="/dev/null", tofile=str(path), lineterm=""
50+
)
51+
)
52+
53+
54+
def combine_patches(patches: Sequence[bytes]) -> str:
55+
"""Combine multiple patches into a single patch."""
56+
if not patches:
57+
return ""
58+
59+
final_patchset = patch_ng.PatchSet()
60+
for patch in patches:
61+
for patch_obj in patch_ng.fromstring(patch) or []:
62+
final_patchset.items += [patch_obj]
63+
64+
return dump_patch(final_patchset)

features/diff-in-svn.feature

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Feature: Diff in svn
2121
"""
2222
An important sentence for the README!
2323
"""
24-
When I run "dfetch -v diff SomeProject" in MySvnProject
24+
When I run "dfetch diff SomeProject" in MySvnProject
2525
Then the patch file 'MySvnProject/SomeProject.patch' is generated
2626
"""
2727
Index: README.md
@@ -39,6 +39,7 @@ Feature: Diff in svn
3939
"""
4040
A completely new untracked file.
4141
"""
42+
And "SomeProject/NEW_UNCOMMITTED_FILE.md" in MySvnProject is created
4243
And "SomeProject/IGNORE_ME.tmp" in MySvnProject is created
4344
When I run "dfetch diff SomeProject" in MySvnProject
4445
Then the patch file 'MySvnProject/SomeProject.patch' is generated
@@ -49,6 +50,12 @@ Feature: Diff in svn
4950
+++ NEWFILE.md
5051
@@ -0,0 +1,1 @@
5152
+A completely new untracked file.
53+
Index: NEW_UNCOMMITTED_FILE.md
54+
===================================================================
55+
--- /dev/null
56+
+++ NEW_UNCOMMITTED_FILE.md
57+
@@ -0,0 +1,1 @@
58+
+Some content
5259
"""
5360

5461
Scenario: No change is present
@@ -78,7 +85,7 @@ Feature: Diff in svn
7885

7986
Scenario: Metadata is not part of diff
8087
Given the metadata file ".dfetch_data.yaml" of "MySvnProject/SomeProject" is changed
81-
When I run "dfetch diff SomeProject"
88+
When I run "dfetch diff SomeProject" in MySvnProject
8289
Then the output shows
8390
"""
8491
Dfetch (0.10.0)

0 commit comments

Comments
 (0)