lib/git/whence.rb in git-whence-0.2.1 vs lib/git/whence.rb in git-whence-0.3.0

- old
+ new

@@ -1,10 +1,12 @@ require "git/whence/version" require "optparse" module Git::Whence module CLI + SQUASH_REGEX = /\(#(\d+)\)$/ + class << self def run(argv) options = parse_options(argv) commit = argv[0] unless system("git rev-parse --git-dir 2>&1 >/dev/null") @@ -17,12 +19,11 @@ if is_merge?(commit) warn "Commit is a merge" show_commit(commit, options) 1 else - merge = find_merge(commit) - if merge + if merge = find_merge(commit) show_commit(merge, options) 0 else warn "Unable to find merge" show_commit(commit, options) if options[:open] @@ -42,11 +43,11 @@ end def show_commit(merge, options) info = sh("git show -s --oneline #{merge}").strip if options[:open] - if pr = info[/Merge pull request #(\d+) from /, 1] + if pr = info[/Merge pull request #(\d+) from /, 1] || info[SQUASH_REGEX, 1] exec "open", "https://github.com/#{origin}/pull/#{pr}" else warn "Unable to find PR number in #{info}" exec "open", "https://github.com/#{origin}/commit/#{merge}" end @@ -55,23 +56,27 @@ end end # https://github.com/foo/bar or git@github.com:foo/bar.git -> foo/bar def origin - repo = sh("git remote get-url origin").strip + repo = sh("git remote get-url origin").strip # TODO: read file instead repo.sub!(/\.git$/, "") repo.split(/[:\/]/).last(2).join("/") end def find_merge(commit) - commit, merge = ( + merge_commit, merge = ( find_merge_simple(commit, "HEAD") || find_merge_simple(commit, "master") || find_merge_fuzzy(commit, "master") ) - merge if merge && merge_include_commit?(merge, commit) + if merge && merge_include_commit?(merge, merge_commit) + merge + else + find_squash_merge(commit) # not very exact, so do this last ... ideally ask github api + end end def merge_include_commit?(merge, commit) commit = sh("git show HEAD -s --format=%H").strip if commit == "HEAD" sh("git log #{merge.strip}^..#{merge.strip} --pretty=%H").split("\n").include?(commit) @@ -81,21 +86,25 @@ if similar = find_similar(commit, branch) find_merge_simple(similar, branch) end end + def find_squash_merge(commit) + commit if sh("git show -s --format='%s' #{commit}") =~ SQUASH_REGEX + end + def find_similar(commit, branch) month = 30 * 24 * 60 * 60 time, search = sh("git show -s --format='%ct %an %s' #{commit}").strip.split(" ", 2) time = time.to_i same = sh("git log #{branch} --pretty=format:'%H %an %s' --before #{time + month} --after #{time - month}") found = same.split("\n").map { |x| x.split(" ", 2) }.detect { |_, message| message == search } found && found.first end def find_merge_simple(commit, branch) - result = sh "git log #{commit}..#{branch} --ancestry-path --merges --pretty='%H' 2>/dev/null | tail -n 1" - [commit, result.strip] unless result.strip.empty? + result = sh("git log #{commit}..#{branch} --ancestry-path --merges --pretty='%H' 2>/dev/null | tail -n 1").chomp + [commit, result] unless result.empty? end def sh(command) result = `#{command}` raise "Command failed\n#{command}\n#{result}" unless $?.success?