MCPcopy Create free account
hub / github.com/FSoft-AI4Code/CodeWiki / _detect_via_git

Function _detect_via_git

codewiki/mcp/tools/analysis.py:90–189  ·  view source on GitHub ↗

Detect changes via git. Returns None if not in a git repo or if no previous commit is recorded (so the caller can fall through to mtime). Checks committed changes (diff against stored commit_id), staged changes (``index.diff('HEAD')``), and unstaged/untracked changes.

(
    repo_path: Path,
    metadata: Dict[str, Any],
    output_dir: Path | None = None,
)

Source from the content-addressed store, hash-verified

88
89
90def _detect_via_git(
91 repo_path: Path,
92 metadata: Dict[str, Any],
93 output_dir: Path | None = None,
94) -> Optional[Dict[str, Any]]:
95 """Detect changes via git. Returns None if not in a git repo or if no
96 previous commit is recorded (so the caller can fall through to mtime).
97
98 Checks committed changes (diff against stored commit_id), staged changes
99 (``index.diff('HEAD')``), and unstaged/untracked changes.
100 """
101 try:
102 import git
103 repo = git.Repo(repo_path, search_parent_directories=True)
104 except Exception:
105 return None
106
107 prev_commit = metadata.get("generation_info", {}).get("commit_id")
108 if not prev_commit:
109 return None # No baseline to compare; let mtime fallback handle it
110
111 try:
112 current_commit = repo.head.commit.hexsha
113 except Exception:
114 return None
115
116 # Compute subpath prefix for monorepo support.
117 # Git diff returns paths relative to the git root, but component IDs
118 # use paths relative to repo_path. Strip the prefix so they align.
119 git_root = Path(repo.working_dir).resolve()
120 repo_root = repo_path.resolve()
121 try:
122 subpath = repo_root.relative_to(git_root).as_posix()
123 except ValueError:
124 subpath = ""
125 if subpath == ".":
126 subpath = ""
127
128 # Output-dir prefix (relative to repo_path) so generated docs, metadata
129 # and session workspace files never count as source changes.
130 output_dir_rel = ""
131 if output_dir is not None:
132 try:
133 output_dir_rel = Path(output_dir).resolve().relative_to(repo_root).as_posix()
134 if output_dir_rel == ".":
135 output_dir_rel = ""
136 except (ValueError, TypeError):
137 pass
138
139 def _normalize(p: str) -> Optional[str]:
140 """Strip the monorepo subpath and drop generated/non-source paths."""
141 if subpath:
142 if not p.startswith(subpath + "/"):
143 return None # outside target subdirectory
144 p = p[len(subpath) + 1:]
145 if p.startswith(".codewiki/"):
146 return None
147 if output_dir_rel and (p == output_dir_rel or p.startswith(output_dir_rel + "/")):

Callers 1

_detect_changesFunction · 0.85

Calls 4

_addFunction · 0.85
getMethod · 0.80
resolveMethod · 0.80
warningMethod · 0.80

Tested by

no test coverage detected