Identify all files a specific author contributed to on a branch vs its upstream, tracing code through renames. Use when asked who edited what, what code an author contributed, or to audit authorship before a merge. This skill should be run as a subagent — it performs many git operations and returns a concise table.
68
82%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
When asked to find all files a specific author contributed to on a branch (compared to main or another upstream), follow this procedure. The goal is to produce a simple table that both humans and LLMs can consume.
This skill involves many sequential git commands. Delegate it to a subagent with a prompt like:
Find every file that author "Full Name" contributed to on branch
<branch>compared to<upstream>. Trace contributions through file renames. Return a markdown table with columns: Status (DIRECT or VIA_RENAME), File Path, and Lines (+/-). Include a summary line at the end.
git log --format="%an <%ae>" <upstream>..<branch> | sort -uMatch the requested person to their exact --author= string. Do not guess — short usernames won't match full display names (resolve via git log or the GitHub MCP get_me tool).
git log --author="<Exact Name>" --format="%H" <upstream>..<branch>For each commit hash, extract touched files:
git diff-tree --no-commit-id --name-only -r <hash>Union all results into a set (author_files).
For every commit on the branch (not just the author's), extract renames:
git diff-tree --no-commit-id -r -M <hash>Parse lines with R status to build a map: new_path → {old_paths}.
git diff --name-only <upstream>..<branch>These are the files that will actually land when the branch merges.
For each file in step 4:
author_files → DIRECTauthor_files → VIA_RENAMEgit diff --stat <upstream>..<branch> -- <file1> <file2> ...Format the result as a markdown table:
| Status | File | +/- |
|--------|------|-----|
| DIRECT | src/vs/foo/bar.ts | +120/-5 |
| VIA_RENAME | src/vs/baz/qux.ts | +300 |
| ... | ... | ... |
**Total: N files, +X/-Y lines**.py script, run it, then delete it.--author does substring matching but you must verify the right person is matched (e.g., don't match "Joshua Smith" when looking for "Josh S."). Use the GitHub MCP get_me tool or git log output to resolve the correct full name.contrib/chat/ → agentSessions/ → sessions/. The rename map must be walked transitively.import subprocess, os
os.chdir('<repo_root>')
UPSTREAM = 'main'
AUTHOR = '<Author Name>' # Resolve via `git log` or GitHub MCP `get_me`
# Step 2: author's files
commits = subprocess.check_output(
['git', 'log', f'--author={AUTHOR}', '--format=%H', f'{UPSTREAM}..HEAD'],
text=True).strip().split('\n')
author_files = set()
for h in (c for c in commits if c):
files = subprocess.check_output(
['git', 'diff-tree', '--no-commit-id', '--name-only', '-r', h],
text=True).strip().split('\n')
author_files.update(f for f in files if f)
# Step 3: rename map from ALL commits
all_commits = subprocess.check_output(
['git', 'log', '--format=%H', f'{UPSTREAM}..HEAD'],
text=True).strip().split('\n')
rename_map = {} # new_name -> set(old_names)
for h in (c for c in all_commits if c):
out = subprocess.check_output(
['git', 'diff-tree', '--no-commit-id', '-r', '-M', h],
text=True, timeout=5).strip()
for line in out.split('\n'):
if not line:
continue
parts = line.split('\t')
if len(parts) >= 3 and 'R' in parts[0]:
rename_map.setdefault(parts[2], set()).add(parts[1])
# Step 4: merge diff
diff_files = subprocess.check_output(
['git', 'diff', '--name-only', f'{UPSTREAM}..HEAD'],
text=True).strip().split('\n')
# Step 5: classify
results = []
for f in (x for x in diff_files if x):
if f in author_files:
results.append(('DIRECT', f))
else:
# walk rename chain
chain, to_check = set(), [f]
while to_check:
cur = to_check.pop()
if cur in chain:
continue
chain.add(cur)
to_check.extend(rename_map.get(cur, []))
chain.discard(f)
if chain & author_files:
results.append(('VIA_RENAME', f))
# Step 6: stats
if results:
stat = subprocess.check_output(
['git', 'diff', '--stat', f'{UPSTREAM}..HEAD', '--'] +
[f for _, f in results], text=True)
print(stat)
# Step 7: table
for kind, f in sorted(results, key=lambda x: x[1]):
print(f'| {kind:12s} | {f} |')
print(f'\nTotal: {len(results)} files')After following the process above, run this script to cross-check files touched by an author against the branch diff. You can do this both with an without src/vs/sessions.
AUTHOR=""
# 1. Find commits by author on this branch (not on main)
git log main...HEAD --author="$AUTHOR" --format="%H"
# 2. Get unique files touched across all those commits, excluding src/vs/sessions/
git log main...HEAD --author="$AUTHOR" --format="%H" \
| xargs -I{} git diff-tree --no-commit-id -r --name-only {} \
| sort -u \
| grep -v '^src/vs/sessions/'
# 3. Cross-reference with branch diff to keep only files still changed vs main
git log main...HEAD --author="$AUTHOR" --format="%H" \
| xargs -I{} git diff-tree --no-commit-id -r --name-only {} \
| sort -u \
| grep -v '^src/vs/sessions/' \
| while read f; do git diff main...HEAD --name-only -- "$f" 2>/dev/null; done \
| sort -ub87c504
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.