Deepen PracticeOrdered learning track

Forensic Playbook for Unknown Repository

Learn Git In Action - Part 086

A practical forensic playbook for safely inspecting an unfamiliar Git repository, reconstructing topology, release state, workflow, ownership, and risk.

13 min read2443 words
PrevNext
Lesson 86126 lesson track69–103 Deepen Practice
#git#version-control#software-engineering#forensics+3 more

Part 086 — Forensic Playbook for Unknown Repository

You inherit a repository.

Maybe it is a production system. Maybe it is an old internal service. Maybe it is a vendor fork. Maybe it is the repo behind a regulatory case management platform that nobody fully owns anymore.

Your job is not to immediately refactor it.

Your job is first to answer:

What is this repository, what state is it in, what history matters, what risks exist, and what must not be touched casually?

This part gives a practical forensic playbook.

The mindset:

  • observe before changing,
  • preserve evidence before cleanup,
  • understand topology before merging,
  • understand release identity before deploying,
  • understand ownership before approving changes,
  • understand workflow before enforcing policy.

1. Prime Directive: Start Read-Only

Do not begin with:

git gc
git clean -fdx
git reset --hard
git pull --rebase
git push --force
git filter-repo
git tag -d
git branch -D

Those commands may destroy forensic evidence, local work, dangling commits, untracked artifacts, or release identity.

Start with observation:

git status --porcelain=v2 -b
git rev-parse --show-toplevel
git rev-parse --git-dir
git rev-parse HEAD
git branch --show-current || true
git remote -v

If the repository matters, create a forensic snapshot before changing anything.


2. Investigation Layers

A good repository investigation is layered. Do not try to understand everything at once.

Each layer should produce notes. If you cannot explain a layer, you are not ready to make destructive changes.


3. The First 10 Minutes: Identify the Repository

Run:

pwd
git rev-parse --show-toplevel
git rev-parse --git-dir
git rev-parse --is-inside-work-tree
git rev-parse --is-bare-repository
git rev-parse --show-superproject-working-tree || true
git rev-parse --show-prefix

Interpretation:

SignalMeaning
--show-toplevel prints pathYou are inside a worktree
--is-bare-repository trueNo normal working tree; likely server/mirror/admin repo
--show-superproject-working-tree prints pathYou are inside a submodule
.git is a file, not directoryWorktree/submodule/gitfile layout
No branch nameDetached HEAD or unborn branch

Check Git version and config origin:

git --version
git config --list --show-origin --show-scope | sed -n '1,120p'

Why config matters:

  • aliases may hide dangerous behavior,
  • hooks path may be custom,
  • pull/rebase policy may be set locally,
  • LFS/filter behavior may be configured,
  • partial clone/sparse checkout may be active,
  • credential helpers/remotes may reveal topology.

4. Capture a Forensic Snapshot

Create a directory outside the repository:

mkdir -p ../repo-forensics
OUT="../repo-forensics/$(basename "$(pwd)")-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$OUT"

Capture read-only state:

{
  echo '# Identity'
  pwd
  git --version
  git rev-parse --show-toplevel || true
  git rev-parse --git-dir || true
  git rev-parse HEAD || true
  git branch --show-current || true

  echo '# Status'
  git status --porcelain=v2 -b || true

  echo '# Remotes'
  git remote -v || true

  echo '# Branches'
  git branch -vv --all || true

  echo '# Tags recent'
  git tag --sort=-creatordate | head -50 || true

  echo '# Recent log'
  git log --graph --decorate --oneline --all -100 || true
} > "$OUT/snapshot.txt" 2>&1

# Separate files for machine parsing
git status --porcelain=v2 -b > "$OUT/status-porcelain-v2.txt" 2>&1 || true
git show-ref > "$OUT/show-ref.txt" 2>&1 || true
git reflog --date=iso > "$OUT/reflog-head.txt" 2>&1 || true
git config --list --show-origin --show-scope > "$OUT/config.txt" 2>&1 || true

Do this before cleanup. Especially before reset --hard, clean, gc, or prune.


5. Current State Triage

Run:

git status --porcelain=v2 -b

Classify state:

StateMeaningFirst response
Clean working treeSafe to inspect deeperContinue
Modified tracked filesLocal work or generated changesDo not reset yet
Untracked filesCould be build artifacts or uncommitted workInventory before clean
Unmerged entriesIn-progress merge/rebase/cherry-pickInspect operation state
Ahead/behind upstreamLocal branch divergedDo not pull blindly
Detached HEADBuild/release checkout or manual inspectionIdentify target ref
Sparse checkoutWorking tree incomplete by designDo not assume missing files absent
Shallow cloneHistory incompleteFetch may be needed for analysis

More detail:

git diff --stat
git diff --cached --stat
git ls-files -u
git stash list
git worktree list

Do not run git stash automatically. Stash changes the repo state and can hide the evidence you need to understand.


6. Detect In-Progress Operations

Git records operation state under .git/.

Check:

git rev-parse --git-path MERGE_HEAD
git rev-parse --git-path REBASE_HEAD
git rev-parse --git-path CHERRY_PICK_HEAD
git rev-parse --git-path REVERT_HEAD

test -f "$(git rev-parse --git-path MERGE_HEAD)" && echo "merge in progress"
test -d "$(git rev-parse --git-path rebase-merge)" && echo "interactive rebase in progress"
test -d "$(git rev-parse --git-path rebase-apply)" && echo "am/rebase apply in progress"
test -f "$(git rev-parse --git-path CHERRY_PICK_HEAD)" && echo "cherry-pick in progress"
test -f "$(git rev-parse --git-path REVERT_HEAD)" && echo "revert in progress"

If an operation is in progress, inspect before aborting:

git status
git ls-files -u
git diff
git diff --cached

Abort only after you understand whether the in-progress operation belongs to someone else or to a CI/release script.


7. Topology: Branches, Remotes, and Refs

List remotes:

git remote -v

Inspect fetch/push refspecs:

git config --get-all remote.origin.fetch
git config --get-all remote.origin.push || true

List branches with tracking:

git branch -vv --all

List refs by recency:

git for-each-ref --sort=-committerdate \
  --format='%(committerdate:iso8601)%09%(refname:short)%09%(objectname:short)%09%(authorname)' \
  refs/heads refs/remotes | head -80

List tags by creator date:

git for-each-ref --sort=-creatordate \
  --format='%(creatordate:iso8601)%09%(refname:short)%09%(objecttype)%09%(objectname:short)' \
  refs/tags | head -80

Interpretation questions:

  • Which remote is canonical?
  • Is origin a fork or upstream?
  • Are there multiple push destinations?
  • Are release branches local only or remote tracked?
  • Are tags present and recent?
  • Are there hidden refs, PR refs, or vendor refs?
  • Does branch naming imply environment branches?

8. Default Branch and Integration Line

Do not assume main or master is the integration line.

Check remote HEAD:

git remote show origin

Check symbolic refs:

git symbolic-ref refs/remotes/origin/HEAD || true

Look at recent activity:

git for-each-ref --sort=-committerdate \
  --format='%(committerdate:short)%09%(refname:short)' \
  refs/remotes/origin | head -20

Candidate integration branches:

  • main,
  • master,
  • develop,
  • trunk,
  • release/*,
  • production,
  • protected branch from platform settings,
  • branch referenced by CI deploy workflow.

You may need platform data to know branch protection. A clone alone usually does not tell you required reviews/checks/merge queues.


9. History Shape Scan

Start with recent graph:

git log --graph --decorate --oneline --all -80

Then inspect mainline:

git log --first-parent --decorate --oneline origin/main -80 2>/dev/null || true
git log --first-parent --decorate --oneline origin/master -80 2>/dev/null || true

Classify shape:

ShapeSignal
Mostly merge commitsPR merge workflow, first-parent useful
Mostly linear commitsrebase/fast-forward/squash workflow
Giant squash commitsGit may hide PR iteration details
Many long-lived branchesIntegration debt risk
Frequent revert commitsMainline instability or release discipline
Many hotfix branchesSupport matrix complexity
Tags sparse/inconsistentRelease identity risk
Environment branchesDeployment-model confusion possible

Use graph shape to decide which later commands are meaningful.


10. Release State Reconstruction

Find tags:

git tag --sort=-creatordate | head -50

Inspect a tag:

git show --stat v1.2.3

Verify tag if signed:

git tag -v v1.2.3

Find release branches:

git branch -a --list '*release*' '*hotfix*' '*support*' '*maintenance*'

Find commits after latest tag:

LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true)
if [ -n "$LATEST_TAG" ]; then
  git log --oneline "$LATEST_TAG..HEAD"
fi

Questions:

  • What was the latest release tag?
  • Is the tag annotated or lightweight?
  • Is the tag signed?
  • Does CI build from tag, branch, or commit SHA?
  • Are artifacts traceable to commit SHA?
  • Are release branches forward-ported?
  • Were tags moved or recreated?
  • Are there RC tags?
  • Is SemVer followed consistently?

Release identity matters because deployment and audit depend on it.


11. Repository Health and Storage

Start safe:

git count-objects -vH

Check object integrity without immediately repairing:

git fsck --full

Inspect large blobs carefully:

git rev-list --objects --all \
  | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
  | awk '$1 == "blob" { print $3, $2, substr($0, index($0,$4)) }' \
  | sort -nr \
  | head -50

Check packfiles:

find "$(git rev-parse --git-dir)/objects/pack" -maxdepth 1 -type f -print

Check commit graph and multi-pack-index if present:

find "$(git rev-parse --git-dir)/objects/info" -maxdepth 2 -type f -print 2>/dev/null || true
find "$(git rev-parse --git-dir)/objects/pack" -maxdepth 1 -name 'multi-pack-index*' -print 2>/dev/null || true

Interpretation:

SignalMeaning
Many loose objectsRecent activity, failed maintenance, or interrupted operations
Huge packfilesLarge history or binaries
Very large blobsGit performance and clone risk
Dangling commitsMay be recoverable work or normal post-rewrite residue
fsck errorsTreat as possible corruption until explained
Missing objectsPartial clone, promisor remote, corruption, or broken alternates

Do not run aggressive cleanup until you know whether dangling objects matter.


12. Detect Shallow, Partial, Sparse, LFS, Submodule, Worktree

These features change what “complete repository” means.

# Shallow clone
test -f "$(git rev-parse --git-dir)/shallow" && echo "shallow clone"

# Partial clone / promisor remote
git config --get remote.origin.promisor || true
git config --get remote.origin.partialclonefilter || true

# Sparse checkout
git sparse-checkout list 2>/dev/null || true
git config --get core.sparseCheckout || true
git config --get index.sparse || true

# Git LFS
git lfs env 2>/dev/null || true
git lfs ls-files 2>/dev/null | head || true

# Submodules
test -f .gitmodules && cat .gitmodules
git submodule status --recursive 2>/dev/null || true

# Worktrees
git worktree list 2>/dev/null || true

Failure if ignored:

FeatureWrong assumption
Shallow clone“History does not contain that commit”
Partial clone“Object is missing, repo corrupt”
Sparse checkout“File was deleted”
Git LFS“Pointer file is actual content”
Submodule“Directory content is part of superproject tree”
Worktree“Only one checkout uses this .git database”

13. Workflow Discovery from Files

Look for workflow control files:

find . -maxdepth 3 \( \
  -name CODEOWNERS -o \
  -name .gitignore -o \
  -name .gitattributes -o \
  -name .gitmodules -o \
  -name Makefile -o \
  -name justfile -o \
  -name package.json -o \
  -name pom.xml -o \
  -name build.gradle -o \
  -name go.mod -o \
  -name Cargo.toml -o \
  -name pyproject.toml -o \
  -name Dockerfile -o \
  -name docker-compose.yml \
\) -print

CI/CD:

find .github .gitlab .circleci .azure-pipelines .buildkite Jenkinsfile* -maxdepth 4 -type f -print 2>/dev/null || true

Read these before running build scripts. Build scripts may deploy, mutate files, install hooks, or fetch secrets.

Workflow clues:

FileClue
CODEOWNERSReview/ownership model
.gitattributesEOL, diff/merge drivers, LFS patterns
.gitmodulesExternal Git dependency pins
.github/workflows/*CI, release, deploy paths
Makefile / justfileDeveloper command surface
lockfilesDependency resolution boundary
migration directoriesData evolution model
DockerfileRuntime packaging
charts/, k8s/, terraform/Deployment ownership

14. Security and Trust Scan

Start with Git-level trust:

# Signed tag verification, if tags are expected to be signed
git tag --sort=-creatordate | head -20 | while read -r tag; do
  git tag -v "$tag" >/dev/null 2>&1 && echo "verified $tag" || echo "not verified $tag"
done

# Recent signed commit metadata display
git log --show-signature -5

Sensitive file scan by history:

git log --all --name-only --format='' \
  | grep -Ei '(^|/)(\.env|id_rsa|secret|credential|token|private-key|keystore|\.p12|\.pem)$' \
  | sort -u

Recent sensitive changes:

git log --since="12 months ago" --oneline -- \
  .github/workflows/ \
  infra/ \
  terraform/ \
  services/auth/ \
  services/authz/ \
  services/audit/ \
  '**/migrations/**'

Remember:

  • absence of obvious secret filenames does not prove no secret leak,
  • deleting a secret from current tree does not remove it from history,
  • signed commits/tags prove identity only within configured trust model,
  • branch protection/rulesets live on the hosting platform, not in plain Git history.

15. Ownership and Social Topology

Git can reveal historical authors, but not full responsibility.

# Repository-level contributors
git shortlog -sn --all | head -30

# Directory-level contributors
git shortlog -sn --since="12 months ago" -- services/auth/

# Recent owners by file
git log -1 --format='%ad %an <%ae> %h %s' --date=short -- services/auth/policy_engine.go

Combine with:

  • CODEOWNERS,
  • PR review history,
  • on-call ownership,
  • service catalog,
  • incident records,
  • architecture docs,
  • team boundaries.

Ownership questions:

  • Who can approve changes safely?
  • Who understands release process?
  • Who owns migrations?
  • Who owns deployment manifests?
  • Who owns security-sensitive paths?
  • Which areas have no active human owner?

16. Dependency and Build Boundary

Identify build system before changing Git workflow.

Language clues:

find . -maxdepth 3 -type f \( \
  -name package.json -o \
  -name pnpm-lock.yaml -o \
  -name yarn.lock -o \
  -name package-lock.json -o \
  -name pom.xml -o \
  -name build.gradle -o \
  -name go.mod -o \
  -name Cargo.toml -o \
  -name requirements.txt -o \
  -name pyproject.toml -o \
  -name Pipfile.lock \
\) -print

Release/build clues:

grep -R "git rev-parse\|GITHUB_SHA\|CI_COMMIT_SHA\|BUILD_VERSION\|VERSION" -n \
  .github .gitlab Jenkinsfile* Makefile build.gradle pom.xml package.json 2>/dev/null | head -100

Questions:

  • Is artifact version derived from tag or commit SHA?
  • Are builds reproducible from clean clone?
  • Does CI checkout shallow history?
  • Does release note generation require tags?
  • Are submodules or LFS fetched in CI?
  • Are generated files committed or generated in build?

17. Unknown Repository Risk Classification

After the first pass, classify the repository.

Green

  • clean working tree,
  • clear canonical remote,
  • clear default branch,
  • recent CI config,
  • consistent tags,
  • clear ownership,
  • no obvious storage/corruption issue,
  • documented build/release path.

Yellow

  • stale branches,
  • sparse/inconsistent tags,
  • unclear owner for some modules,
  • large blobs but manageable,
  • shallow clone limits analysis,
  • CI present but not obviously release-safe,
  • some untracked/generated noise.

Red

  • dirty working tree with unknown changes,
  • in-progress merge/rebase/cherry-pick,
  • missing/corrupt objects,
  • moved release tags,
  • secrets in history,
  • no clear canonical remote,
  • release branch diverged from main with no plan,
  • unverified artifacts,
  • large binary history causing severe clone/fetch failure,
  • unknown deploy scripts tied to branch names.

Red does not mean panic. It means preserve evidence, reduce blast radius, and avoid casual mutation.


18. The 30/90/240-Minute Playbook

First 30 minutes — safety and identity

Goal: do no harm and identify current state.

Run:

git status --porcelain=v2 -b
git remote -v
git branch -vv --all
git log --graph --decorate --oneline --all -50
git tag --sort=-creatordate | head -20
git config --list --show-origin --show-scope | sed -n '1,160p'

Deliverable:

Repository identity:
Current branch/HEAD:
Canonical remote guess:
Working tree state:
Default branch guess:
Latest tag:
Immediate dangers:

First 90 minutes — topology and release

Goal: understand branch/release model.

Run:

git remote show origin
git for-each-ref --sort=-committerdate --format='%(committerdate:short)%09%(refname:short)' refs/remotes | head -80
git log --first-parent --decorate --oneline origin/main -100 2>/dev/null || true
git log --first-parent --decorate --oneline origin/master -100 2>/dev/null || true
git describe --tags --always --dirty

Deliverable:

Integration line:
Release branches:
Tag policy guess:
Merge policy guess:
Branch drift risks:
CI/release entry points:

First 240 minutes — health, ownership, risk

Goal: produce actionable repository dossier.

Run:

git count-objects -vH
git fsck --full
git shortlog -sn --all | head -50
git log --since="12 months ago" --numstat --format='' -- . | head -100
find . -maxdepth 3 -type f \( -name CODEOWNERS -o -name .gitattributes -o -name .gitmodules \) -print

Deliverable:

Storage health:
Large objects:
Sensitive paths:
Ownership map:
Hotspots:
Release integrity risks:
Recommended next actions:

19. Forensic Dossier Template

Use this template when handing off findings:

# Repository Forensic Dossier

## Identity
- Repository path:
- Git version:
- HEAD:
- Current branch:
- Canonical remote:
- Default branch:
- Is bare/shallow/partial/sparse:

## Current State
- Working tree clean:
- Index clean:
- Untracked files:
- In-progress operation:
- Stashes:
- Worktrees:

## Topology
- Important remotes:
- Main integration branch:
- Release branches:
- Long-lived branches:
- Stale branches:
- Fork/mirror relationships:

## Release State
- Latest tag:
- Tag type/signature:
- Recent releases:
- Artifact commit source:
- RC/hotfix pattern:
- Tag immutability concerns:

## Workflow
- Merge policy inferred:
- PR/review indicators:
- CODEOWNERS:
- CI entry points:
- Deploy entry points:
- Hooks/config surprises:

## Health
- Object count:
- Packfiles:
- Large blobs:
- fsck result:
- LFS/submodules:
- Maintenance concerns:

## Security / Compliance
- Sensitive paths:
- Secret exposure indicators:
- Signed tags/commits:
- Auth/authz/audit changes:
- Branch protection unknowns:

## Ownership
- Top contributors:
- Active owners:
- Decayed areas:
- Review bottlenecks:

## Risks
- Red:
- Yellow:
- Green:

## Recommended Actions
1.
2.
3.

A dossier is useful because it turns scattered Git commands into shared operational knowledge.


20. Specific Incident Playbooks

20.1 Dirty inherited working tree

Symptoms:

git status --porcelain=v2 -b

shows modifications/untracked files.

Do:

git diff > ../repo-forensics/dirty-working-tree.diff
git diff --cached > ../repo-forensics/dirty-index.diff
git ls-files --others --exclude-standard > ../repo-forensics/untracked-files.txt

Then decide:

  • Are changes generated?
  • Are changes local emergency patch?
  • Are changes secrets/config that must not be committed?
  • Is this somebody else’s work?
  • Should it become a branch?

Only after that consider stash, commit, reset, or clean.

20.2 Unknown detached HEAD

Run:

git rev-parse HEAD
git branch --contains HEAD
git tag --contains HEAD
git describe --tags --always --dirty

Interpretation:

ResultMeaning
Tag contains HEADlikely release checkout
Remote branch contains HEADbranch checkout detached by CI/tool
No ref contains HEADorphaned/temporary commit or incomplete history
Dirty statebuild or local mutation after checkout

Do not create a branch unless needed. First identify why HEAD is detached.

20.3 Suspected corruption

Run:

git fsck --full
git count-objects -vH

If missing objects appear:

  • check partial clone config,
  • check alternates,
  • check submodules,
  • check shallow clone,
  • fetch from canonical remote if safe,
  • avoid gc until diagnosis is complete.

20.4 Suspected secret in history

Do not start with history rewrite.

First:

  1. identify exposed secret,
  2. revoke/rotate secret,
  3. determine exposure scope,
  4. preserve evidence,
  5. plan rewrite only if useful,
  6. coordinate all clones/downstream consumers,
  7. add prevention guardrails.

Useful Git queries:

git log --all --name-only --format='%H' | grep -Ei 'secret|token|credential|\.env|\.pem|\.p12'
git grep -n -I -E 'AKIA|BEGIN RSA PRIVATE KEY|BEGIN OPENSSH PRIVATE KEY|password\s*=' $(git rev-list --all) -- 2>/dev/null || true

The second command can be expensive and noisy on large repositories. Use dedicated secret scanning tools for serious work.

20.5 Unknown release artifact

Given an artifact with commit SHA:

SHA=<artifact-sha>
git cat-file -t "$SHA"
git branch --contains "$SHA"
git tag --contains "$SHA"
git describe --tags --contains "$SHA" 2>/dev/null || true
git log --oneline -1 "$SHA"

Questions:

  • Is SHA in this repository?
  • Is SHA reachable from release tag?
  • Is SHA reachable from protected branch?
  • Is SHA dirty-build or clean-build source?
  • Does artifact metadata match Git tag/version?

21. Platform Boundary: What Git Cannot Tell You Alone

A local clone cannot fully reveal:

  • branch protection rules,
  • required checks,
  • merge queue configuration,
  • CODEOWNER enforcement settings,
  • PR approvals,
  • review dismissal policy,
  • deployment environment approvals,
  • repository secrets,
  • audit log of force pushes/deleted branches,
  • who had permission at the time.

Git can show refs and objects. Hosting platforms hold governance state.

For serious forensics, combine:

Git clone data + hosting platform metadata + CI logs + artifact registry + incident records

22. Build a repo-forensics.sh Script

#!/usr/bin/env bash
set -euo pipefail

ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
NAME=$(basename "$ROOT")
OUT="${1:-../repo-forensics/${NAME}-$(date +%Y%m%d-%H%M%S)}"
mkdir -p "$OUT"

run() {
  local name="$1"
  shift
  echo "Running $name..." >&2
  {
    echo "# $*"
    "$@"
  } > "$OUT/$name.txt" 2>&1 || true
}

run identity git rev-parse --show-toplevel
run git-dir git rev-parse --git-dir
run head git rev-parse HEAD
run status git status --porcelain=v2 -b
run remotes git remote -v
run branches git branch -vv --all
run refs git show-ref
run reflog git reflog --date=iso
run config git config --list --show-origin --show-scope
run recent-log git log --graph --decorate --oneline --all -100
run tags bash -lc "git for-each-ref --sort=-creatordate --format='%(creatordate:iso8601)%09%(refname:short)%09%(objecttype)%09%(objectname:short)' refs/tags | head -100"
run recent-refs bash -lc "git for-each-ref --sort=-committerdate --format='%(committerdate:iso8601)%09%(refname:short)%09%(objectname:short)' refs/heads refs/remotes | head -100"
run count-objects git count-objects -vH
run fsck git fsck --full
run worktrees git worktree list
run submodules git submodule status --recursive
run lfs bash -lc "git lfs env && git lfs ls-files | head -100"
run sparse bash -lc "git sparse-checkout list && git config --get index.sparse"

find . -maxdepth 3 -type f \( \
  -name CODEOWNERS -o \
  -name .gitattributes -o \
  -name .gitmodules -o \
  -name .gitignore -o \
  -path './.github/workflows/*' \
\) -print > "$OUT/control-files.txt" 2>&1 || true

echo "Forensic snapshot written to $OUT"

Run it from the repository root:

chmod +x repo-forensics.sh
./repo-forensics.sh

This script intentionally avoids mutation.


23. Reading the Evidence Without Fooling Yourself

Common traps:

TrapCorrection
origin is assumed canonicalVerify remote topology
main is assumed productionCheck CI/deploy workflows and tags
clean working tree means safe repoNeed history/release/security scan
no current secret means no leaked secretSearch history and rotate if exposed
latest tag means latest deploymentCheck artifact/deployment metadata
branch name prod means production truthVerify with deployment system
signed tag means safe releaseSignature only covers identity/integrity, not correctness
shallow clone means old commits absentFetch complete history before conclusion
no CODEOWNERS means no ownerOwnership may live outside Git
fsck warning means corruptionCould be partial clone/promisor/alternates context

Forensics is controlled skepticism.


24. Unknown Repository Decision Tree


25. What “Good” Looks Like After Forensics

After a strong initial investigation, you should be able to say:

This repository's canonical remote appears to be X.
The integration branch appears to be Y.
The latest release tag is Z and points to commit C.
The working tree is clean/dirty for these reasons.
The history shape suggests merge/squash/rebase workflow.
The active release branches are A, B, C.
The risky areas are P, Q, R.
The current ownership map is incomplete/clear.
There are/no obvious large-object/storage risks.
There are/no obvious secret/tag/signature risks.
Before changing workflow, we need these platform facts.

That is actionable. “Looks okay” is not.


26. Exercises

Exercise 1 — Build a repository dossier

Take any unfamiliar repository and produce the dossier template from this part. Do not change the repository.

Exercise 2 — Identify release identity

Find latest release tag, determine whether it is annotated/lightweight/signed, and identify whether current HEAD is ahead/behind it.

Exercise 3 — Detect incomplete clone assumptions

Determine whether the repo is shallow, partial, sparse, LFS-enabled, or submodule-based. Explain what each means for analysis correctness.

Exercise 4 — Risk classify branches

List remote branches by last commit date and classify stale/diverged/release-critical branches.

Exercise 5 — Platform boundary

List at least five things you cannot know from Git alone and what system you would query for each.


27. Final Mental Model

An unknown repository is not just source code. It is a living operational artifact:

  • object database,
  • branch topology,
  • release record,
  • collaboration protocol,
  • ownership map,
  • security boundary,
  • CI/deployment source,
  • historical evidence store.

The first job is not to be clever. The first job is to be safe.

Professional repository forensics follows this invariant:

preserve state -> identify topology -> reconstruct release identity -> assess health -> assess risk -> recommend controlled action

Only after that should you refactor, clean, rewrite, or enforce new policy.


References

Lesson Recap

You just completed lesson 86 in deepen practice. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.