Skip to content

Instantly share code, notes, and snippets.

@jhawthorn
Last active June 30, 2020 06:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhawthorn/3a950320d018b8d8592bed0dd7db4baf to your computer and use it in GitHub Desktop.
Save jhawthorn/3a950320d018b8d8592bed0dd7db4baf to your computer and use it in GitHub Desktop.
For each changed file, generate a separate "fixup" commit targetting the last time that file was changed.
#!/usr/bin/env ruby
# git-flatfix
# For each changed file, generate a separate "fixup" commit targetting the last
# time that file was changed.
def usage
STDERR.puts <<~USAGE
Usage: git-flatfix [basebranch]
USAGE
exit 1
end
def all_branches
@all_branches ||= `git branch --list --remotes --format='%(refname:lstrip=-2)'`.chomp.split("\n")
end
def detect_main_branch
(%w[origin/main origin/trunk origin/master] & all_branches).first
end
base = ARGV[0] || detect_main_branch
usage unless base || base == "--help" || ARGV.size > 1
changes = `git status --porcelain`.lines.grep(/\A M/)
if changes.empty?
STDERR.puts "No changes"
exit 0
end
changed_files = changes.map { |line| line[/\A M (.*)\n\z/m, 1] }
changed_files.map do |f|
last_change = `git log -n 1 --pretty=format:%H #{base}...HEAD -- #{f}`.chomp
if last_change.empty?
warn "Could not find last change for #{f}"
else
cmd = "git commit --quiet --fixup=#{last_change} -- #{f}"
puts cmd
system(cmd)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment