| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -123,8 +123,9 @@ def _is_bot(name: str, email: str) -> bool: | |||
| 123 | 123 | def git_blame_porcelain(path: Path) -> dict[str, dict]: | |
| 124 | 124 | """Run ``git blame --porcelain`` and return a commit-hash → info map. | |
| 125 | 125 | ||
| 126 | - Each value is a dict with keys: ``name``, ``email``, ``subject``, and | ||
| 127 | - ``lines`` (a set of 1-based line numbers blamed to that commit). | ||
| 126 | + Each value is a dict with keys: ``name``, ``email``, ``subject``, | ||
| 127 | + ``author_time`` (unix timestamp, int), and ``lines`` (a set of 1-based | ||
| 128 | + line numbers blamed to that commit). | ||
| 128 | 129 | """ | |
| 129 | 130 | result = subprocess.run( | |
| 130 | 131 | [ | |
@@ -160,13 +161,26 @@ def git_blame_porcelain(path: Path) -> dict[str, dict]: | |||
| 160 | 161 | result_line = int(parts[2]) | |
| 161 | 162 | current_hash = h | |
| 162 | 163 | if h not in commits: | |
| 163 | - commits[h] = {"name": "", "email": "", "subject": "", "lines": set()} | ||
| 164 | + commits[h] = { | ||
| 165 | + "name": "", | ||
| 166 | + "email": "", | ||
| 167 | + "subject": "", | ||
| 168 | + "author_time": -1, | ||
| 169 | + "lines": set(), | ||
| 170 | + } | ||
| 164 | 171 | commits[h]["lines"].add(result_line) | |
| 165 | 172 | elif raw_line.startswith("author ") and current_hash: | |
| 166 | 173 | commits[current_hash]["name"] = raw_line[len("author ") :].strip() | |
| 167 | 174 | elif raw_line.startswith("author-mail ") and current_hash: | |
| 168 | 175 | email = raw_line[len("author-mail ") :].strip().strip("<>") | |
| 169 | 176 | commits[current_hash]["email"] = email.lower() | |
| 177 | + elif raw_line.startswith("author-time ") and current_hash: | ||
| 178 | + try: | ||
| 179 | + commits[current_hash]["author_time"] = int( | ||
| 180 | + raw_line[len("author-time ") :].strip() | ||
| 181 | + ) | ||
| 182 | + except ValueError: | ||
| 183 | + pass | ||
| 170 | 184 | elif raw_line.startswith("summary ") and current_hash: | |
| 171 | 185 | commits[current_hash]["subject"] = raw_line[len("summary ") :] | |
| 172 | 186 | ||
@@ -204,23 +218,25 @@ def real_author_for_lines( | |||
| 204 | 218 | """Return the git username of the most recent real (non-bot, non-mechanical) | |
| 205 | 219 | author who touched any of ``line_numbers``, or None. | |
| 206 | 220 | ||
| 207 | - ``git blame --porcelain`` outputs commits in file order, not | ||
| 208 | - chronologically. We pick the candidate whose blamed lines have the | ||
| 209 | - highest line number as a proxy for recency, which avoids an extra | ||
| 210 | - ``git log`` call per entry and is accurate enough for string-level work. | ||
| 221 | + Recency is determined by each candidate commit's ``author-time`` (a unix | ||
| 222 | + timestamp reported directly by ``git blame --porcelain``), not by line | ||
| 223 | + position in the file. Line number is not a valid proxy for edit time: a | ||
| 224 | + numerically later line is not necessarily edited more recently, so using | ||
| 225 | + it as a stand-in silently misattributes entries whose msgstr lines were | ||
| 226 | + last touched by different commits. | ||
| 211 | 227 | """ | |
| 212 | 228 | best_name: str | None = None | |
| 213 | - best_line: int = -1 | ||
| 229 | + best_time: int = -1 | ||
| 214 | 230 | ||
| 215 | 231 | for info in blame.values(): | |
| 216 | 232 | overlap = info["lines"] & line_numbers | |
| 217 | 233 | if not overlap: | |
| 218 | 234 | continue | |
| 219 | 235 | if _is_bot(info["name"], info["email"]) or _is_mechanical(info["subject"]): | |
| 220 | 236 | continue | |
| 221 | - candidate_line = max(overlap) | ||
| 222 | - if candidate_line > best_line: | ||
| 223 | - best_line = candidate_line | ||
| 237 | + candidate_time = info["author_time"] | ||
| 238 | + if candidate_time > best_time: | ||
| 239 | + best_time = candidate_time | ||
| 224 | 240 | best_name = info["name"] | |
| 225 | 241 | ||
| 226 | 242 | return best_name | |
| Back | FazBrowse Home | New Git URL |
0 commit comments