Skip to content

Instantly share code, notes, and snippets.

@WilliamBZA
Last active January 14, 2026 17:23
Show Gist options
  • Select an option

  • Save WilliamBZA/453f4077a056fcc140e5854fa6c64a66 to your computer and use it in GitHub Desktop.

Select an option

Save WilliamBZA/453f4077a056fcc140e5854fa6c64a66 to your computer and use it in GitHub Desktop.

Most freqently changed file

git log --since="1 year ago" --no-merges --name-only --pretty=format: \
  | sort | uniq -c | sort -rn | head -30

Files most touched by “fix/bug/hotfix” commits

git log --since="1 year ago" --no-merges --name-only --pretty=format: \
  --grep='fix\|bug\|hotfix\|patch\|regression' -i \
  | sort | uniq -c | sort -rn | head -30

Largest single change commit per file

git log --no-merges --numstat --pretty=format: \
  | awk 'NF==3 && $0 ~ /\.cs$/ && $1 ~ /^[0-9]+$/ && $2 ~ /^[0-9]+$/ {s=$1+$2; if(s>max[$3]) max[$3]=s}
         END{for(f in max) printf "%d\t%s\n", max[f], f}' \
  | sort -rn | head -30

Find high-churn files

git log --since="1 year ago" --no-merges --numstat --pretty=format: \
  | awk 'NF==3 && $1 ~ /^[0-9]+$/ && $2 ~ /^[0-9]+$/ {a[$3]+=$1; d[$3]+=$2}
         END{for(f in a) printf "%d\t%d\t%d\t%s\n", a[f]+d[f], a[f], d[f], f}' \
  | sort -rn | head -30

Find the strongest co-pair files

git log --no-merges --name-only --pretty=format:%H \
| awk '
  /^[0-9a-f]{40}$/ { commit=$0; next }
  NF && $0 ~ /\.cs$/ { files[commit]=files[commit] "\n" $0 }
  END {
    for (c in files) {
      n=split(files[c], a, "\n")
      # de-dupe per commit
      for (i=1;i<=n;i++) if (a[i]!="") seen[a[i]]=1
      # list of unique files
      m=0
      for (f in seen) u[++m]=f
      # all unordered pairs
      for (i=1;i<=m;i++)
        for (j=i+1;j<=m;j++) {
          p=u[i] "  <->  " u[j]
          pair[p]++
        }
      # reset seen/u for next commit
      for (f in seen) delete seen[f]
      for (i=1;i<=m;i++) delete u[i]
    }
    for (p in pair) printf "%8d  %s\n", pair[p], p
  }
' \
| sort -rn \
| head -150

Which files also change when file X changes

TARGET="Path/to/file.cs"

git log --no-merges --pretty=format:%H --name-only \
| awk -v target="$TARGET" '
  /^[0-9a-f]{40}$/ { commit=$0; next }
  NF {
    f=$0
    touched[commit,f]=1
    commit_touched[commit]=1
    file_total[f]++
    if (f==target) target_commits[commit]=1
  }
  END {
    # count cochanges with target
    for (k in touched) {
      split(k, parts, SUBSEP)
      c=parts[1]; f=parts[2]
      if (!target_commits[c] || f==target) continue
      co[f]++
    }
    # total number of commits where target changed
    t=0
    for (c in target_commits) t++
    for (f in co) {
      printf "%6.2f%%  (%5d/%d)  %s\n", (100.0*co[f]/t), co[f], t, f
    }
  }
' \
| sort -rn \
| head -30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment