Skip to content

Commit 89c435e

Browse files
draft of branch warning
1 parent bc30467 commit 89c435e

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

branches.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
branch-wise-lastmod = 2025-12-06T13:37:15.466566+00:00
1+
branch-wise-lastmod = 2025-12-06T13:57:12.846499+00:00

syrinx/branches.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from syrinx.exceptions import UnknownBranchError
88
if TYPE_CHECKING:
99
from syrinx.config import BuildMetaInfo
10+
from syrinx.node import ContentNode
1011
logger = logging.getLogger(__name__)
1112

1213
def read_branches(root_dir: str) -> Branches:
@@ -60,6 +61,8 @@ class Branches:
6061

6162
def __init__(self, inner: Dict[str, datetime]) -> None:
6263
self.inner = inner
64+
self.active = None
65+
self.changed_files = set()
6366

6467
def get_lastmodified(self, branch_name: str) -> datetime:
6568
"""Get the last modified datetime for a specific branch.
@@ -87,6 +90,7 @@ def update(self, meta: BuildMetaInfo, root_dir: str) -> None:
8790
Uses git to determine the current branch name and records the build timestamp
8891
for that branch. If no branch is found, does nothing.
8992
Updates the internal branch dictionary and persists changes to branches.toml.
93+
Also caches the list of changed files for use in warnIfModifiedNodeHasOutdatedBranch.
9094
9195
Args:
9296
meta: BuildMetaInfo object containing timestamp and other build metadata
@@ -99,9 +103,20 @@ def update(self, meta: BuildMetaInfo, root_dir: str) -> None:
99103
# Detached HEAD state, no branch name available
100104
return
101105
branch_name = repo.active_branch.name
106+
107+
# Cache changed files (both staged and unstaged, plus untracked)
108+
try:
109+
self.changed_files = set(repo.untracked_files)
110+
self.changed_files.update(item.a_path for item in repo.index.diff(None) if item.a_path)
111+
self.changed_files.update(item.a_path for item in repo.index.diff('HEAD') if item.a_path)
112+
except (AttributeError, TypeError):
113+
# Unable to get changed files (e.g., in tests with mocked repo)
114+
self.changed_files = set()
115+
102116
except (InvalidGitRepositoryError, ValueError, TypeError):
103117
# Not a git repository or unable to determine branch
104118
return
119+
self.active = branch_name
105120

106121
# Update the branch with the current build timestamp
107122
self.inner[branch_name] = meta.timestamp
@@ -111,3 +126,35 @@ def update(self, meta: BuildMetaInfo, root_dir: str) -> None:
111126
# Write the updated branches to file if we have any entries
112127
if self.inner:
113128
write_branches(self.inner, root_dir)
129+
130+
def warnIfModifiedNodeHasOutdatedBranch(self, node: ContentNode, branch: str):
131+
"""Check if a modified node's file has uncommitted changes on a different branch.
132+
133+
If the node's file has uncommitted changes and the specified branch doesn't
134+
match the currently active branch, logs a warning.
135+
Uses cached changed_files populated by update() for efficiency.
136+
137+
Args:
138+
node: The ContentNode to check
139+
branch: The branch name specified in the node's LastModifiedBranch
140+
"""
141+
# Only check if we have an active branch to compare against
142+
if self.active is None:
143+
return
144+
145+
# If the branch matches the active branch, no warning needed
146+
if branch == self.active:
147+
return
148+
149+
# Construct the file path relative to the repo root
150+
# node.path is the directory path, node.name is the filename
151+
file_path = join(node.path.lstrip('/'), node.name)
152+
if file_path.startswith('./'):
153+
file_path = file_path[2:]
154+
155+
# Check if the file is in the cached changed files
156+
if file_path in self.changed_files:
157+
logger.warning(
158+
f"File '{node.name}' at '{node.path}' has uncommitted changes "
159+
f"but references LastModifiedBranch '{branch}' while currently on branch '{self.active}'"
160+
)

syrinx/node.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ def lastModified(self) -> Optional[datetime]:
6868
# If not present, check for LastModifiedBranch entry
6969
if 'LastModifiedBranch' in self.front:
7070
branch_name = self.front['LastModifiedBranch']
71+
# warn if modified, but on new branch
72+
self.config.branches.warnIfModifiedNodeHasOutdatedBranch(self, branch_name)
7173
# Return datetime object directly from branches
7274
return self.config.branches.get_lastmodified(branch_name)
7375

0 commit comments

Comments
 (0)