From 725e0fdd84339713fa739147ba75898d7bf15aff Mon Sep 17 00:00:00 2001 From: Vikas Panwar Date: Thu, 19 May 2016 15:26:28 -0700 Subject: [PATCH 1/8] deleted files not getting picked up --- lib/git_diff_parser/patches.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/git_diff_parser/patches.rb b/lib/git_diff_parser/patches.rb index 342de7e..277b677 100644 --- a/lib/git_diff_parser/patches.rb +++ b/lib/git_diff_parser/patches.rb @@ -26,7 +26,9 @@ def self.parse(contents) file_name = '' end body = false - when /^\-\-\-/ + when %r{^\-\-\- a/(?.*)} + file_name = Regexp.last_match[:file_name] + body = true when %r{^\+\+\+ b/(?.*)} file_name = Regexp.last_match[:file_name] body = true From e088ba5cfa9932ed58ecd1a52f725e53bf76414d Mon Sep 17 00:00:00 2001 From: Vikas Panwar Date: Tue, 24 May 2016 12:50:39 -0700 Subject: [PATCH 2/8] added support for parsing commits and correlating them with changes --- lib/git_diff_parser.rb | 6 ++ lib/git_diff_parser/commit.rb | 26 ++++++++ lib/git_diff_parser/commits.rb | 92 ++++++++++++++++++++++++++ lib/git_diff_parser/commits_by_file.rb | 20 ++++++ lib/git_diff_parser/diff_parser.rb | 3 + 5 files changed, 147 insertions(+) create mode 100644 lib/git_diff_parser/commit.rb create mode 100644 lib/git_diff_parser/commits.rb create mode 100644 lib/git_diff_parser/commits_by_file.rb diff --git a/lib/git_diff_parser.rb b/lib/git_diff_parser.rb index d6254d0..61abcfd 100644 --- a/lib/git_diff_parser.rb +++ b/lib/git_diff_parser.rb @@ -2,6 +2,8 @@ require 'git_diff_parser/line' require 'git_diff_parser/patch' require 'git_diff_parser/patches' +require 'git_diff_parser/commit' +require 'git_diff_parser/commits' require 'git_diff_parser/diff_parser' # Parse `git diff` into patches and lines @@ -12,4 +14,8 @@ module GitDiffParser def self.parse(contents) Patches.parse(contents) end + + def self.parselog(contents) + Commits.parse(contents) + end end diff --git a/lib/git_diff_parser/commit.rb b/lib/git_diff_parser/commit.rb new file mode 100644 index 0000000..8f64ea2 --- /dev/null +++ b/lib/git_diff_parser/commit.rb @@ -0,0 +1,26 @@ +module GitDiffParser + # Parsed commit + class Commit + attr_accessor :hash, :author, :date, :comment, :files + + def debug_output + puts '-----new Commit----' + puts @hash + puts @author + puts @date + puts @comment + puts @files + puts '-----end----' + end + + def initialize( options = {}) + @hash = options[:hash].dup if options[:hash] + @author = options[:author].dup if options[:author] + @date = options[:date].dup if options[:date] + @comment = options[:comment].dup if options[:comment] + @files = options[:files].dup if options[:files] + +# debug_output + end + end +end diff --git a/lib/git_diff_parser/commits.rb b/lib/git_diff_parser/commits.rb new file mode 100644 index 0000000..2ed8d5c --- /dev/null +++ b/lib/git_diff_parser/commits.rb @@ -0,0 +1,92 @@ +require 'delegate' +module GitDiffParser + # The array of commit + class Commits < DelegateClass(Array) + # @return [Commits] + def self.[](*ary) + new(ary) + end + + # @param contents [String] `git diff` result + # + # @return [Commits] parsed object + def self.parse(contents) + body = false + consume = false + author = '' + date = '' + chash = '' + file = '' + files = [] + comments = [] + commit = [] + lines = contents.lines + line_count = lines.count + parsed = new + lines.each_with_index do |line, count| + case line.chomp + when %r{^commit (?.*)} + if body == true + parsed << Commit.new(hash: chash, author: author, date: date, comment: comments, files: files) + comments.clear + files.clear + body = false + end + chash = Regexp.last_match[:hash] + consume = true + when %r{^Author:\s+(?.*)} + if consume + author = Regexp.last_match[:author] + body = true + end + when %r{^Date: (?.*)} + if consume == true + date = Regexp.last_match[:date] + body = true + end + when /^Merge: / + consume = false + when %r{^[ACDMRTUXB]\s(?.*)} + if consume == true + file = Regexp.last_match[:file] + files << file + body = true + if line_count == count + 1 + parsed << Commit.new(hash: chash, author: author, date: date, comment: comments, files: files) + end + end + else + if consume == true + comments << line + body = true + end + end + end + parsed + end + + # @return [Commits] + def initialize(*args) + super Array.new(*args) + end + + # @return [Array] file path + def hashes + map(&:chash) + end + + # @param file [String] file path + # + # @return [Commit, nil] + def find_commit_by_file(file) + find { |commit| commit.file == file } + end + + # @param secure_hash [String] target sha1 hash + # + # @return [Commit, nil] + def find_commit_by_secure_hash(secure_hash) + find { |commit| commit.secure_hash == secure_hash } + end + end +end diff --git a/lib/git_diff_parser/commits_by_file.rb b/lib/git_diff_parser/commits_by_file.rb new file mode 100644 index 0000000..b4c7633 --- /dev/null +++ b/lib/git_diff_parser/commits_by_file.rb @@ -0,0 +1,20 @@ +require 'git_diff_parser.rb' +module GitDiffParser + class CommitsByFile + def initialize(commit_log) + commits = GitDiffParser.parselog(commit_log) + + @commits_by_file = Hash.new {|h,k| h[k]=[]} + commits.each { |commit| + commit.files.each { |file| + @commits_by_file[file] << commit + } + } + end + + def get_commits(file_name) + return @commits_by_file[file_name] + end + end +end + diff --git a/lib/git_diff_parser/diff_parser.rb b/lib/git_diff_parser/diff_parser.rb index 2d7835a..9d5c328 100644 --- a/lib/git_diff_parser/diff_parser.rb +++ b/lib/git_diff_parser/diff_parser.rb @@ -14,5 +14,8 @@ def self.parse(contents) warn '[DEPRECATION] `DiffParser.parse` is deprecated. Please use `Patches.parse` instead.' Patches.parse(contents) end + def self.parselog(contents) + Commits.parse(contents) + end end end From ae4e7f4a05d885741bc6f00dfeac648855262c22 Mon Sep 17 00:00:00 2001 From: Vikas Panwar Date: Fri, 2 Dec 2016 14:39:38 -0800 Subject: [PATCH 3/8] extract pull requests --- lib/git_diff_parser/commit.rb | 4 +++- lib/git_diff_parser/commits.rb | 12 ++++++++---- lib/git_diff_parser/commits_by_file.rb | 13 +++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/git_diff_parser/commit.rb b/lib/git_diff_parser/commit.rb index 8f64ea2..b9228e8 100644 --- a/lib/git_diff_parser/commit.rb +++ b/lib/git_diff_parser/commit.rb @@ -1,11 +1,12 @@ module GitDiffParser # Parsed commit class Commit - attr_accessor :hash, :author, :date, :comment, :files + attr_accessor :hash, :mhash, :author, :date, :comment, :files def debug_output puts '-----new Commit----' puts @hash + puts @mhash puts @author puts @date puts @comment @@ -15,6 +16,7 @@ def debug_output def initialize( options = {}) @hash = options[:hash].dup if options[:hash] + @mhash = options[:mhash].dup if options[:mhash] @author = options[:author].dup if options[:author] @date = options[:date].dup if options[:date] @comment = options[:comment].dup if options[:comment] diff --git a/lib/git_diff_parser/commits.rb b/lib/git_diff_parser/commits.rb index 2ed8d5c..51f9d72 100644 --- a/lib/git_diff_parser/commits.rb +++ b/lib/git_diff_parser/commits.rb @@ -16,6 +16,7 @@ def self.parse(contents) author = '' date = '' chash = '' + mhash = '' file = '' files = [] comments = [] @@ -27,7 +28,7 @@ def self.parse(contents) case line.chomp when %r{^commit (?.*)} if body == true - parsed << Commit.new(hash: chash, author: author, date: date, comment: comments, files: files) + parsed << Commit.new(hash: chash, mhash: mhash, author: author, date: date, comment: comments, files: files) comments.clear files.clear body = false @@ -44,15 +45,18 @@ def self.parse(contents) date = Regexp.last_match[:date] body = true end - when /^Merge: / - consume = false + when %r{^Merge: (?.*)} + if consume == true + mhash = Regexp.last_match[:mhash] + body = true + end when %r{^[ACDMRTUXB]\s(?.*)} if consume == true file = Regexp.last_match[:file] files << file body = true if line_count == count + 1 - parsed << Commit.new(hash: chash, author: author, date: date, comment: comments, files: files) + parsed << Commit.new(hash: chash, mergeh: mhash, author: author, date: date, comment: comments, files: files) end end else diff --git a/lib/git_diff_parser/commits_by_file.rb b/lib/git_diff_parser/commits_by_file.rb index b4c7633..ef931d6 100644 --- a/lib/git_diff_parser/commits_by_file.rb +++ b/lib/git_diff_parser/commits_by_file.rb @@ -5,16 +5,29 @@ def initialize(commit_log) commits = GitDiffParser.parselog(commit_log) @commits_by_file = Hash.new {|h,k| h[k]=[]} + @prs = [] commits.each { |commit| commit.files.each { |file| @commits_by_file[file] << commit } + + if !(commit.mhash.nil? || commit.mhash.empty?) + commit.comment.each { |comment| + if comment =~ /Merge pull request/ + @prs << comment[/\d+/].to_i + end + } + end } end def get_commits(file_name) return @commits_by_file[file_name] end + + def get_prs() + return @prs + end end end From 4c5916c730c0f5290292149c280171461bb975f5 Mon Sep 17 00:00:00 2001 From: Vikas Panwar Date: Thu, 8 Dec 2016 21:08:53 -0800 Subject: [PATCH 4/8] extract more info about the PR --- lib/git_diff_parser/commits_by_file.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/git_diff_parser/commits_by_file.rb b/lib/git_diff_parser/commits_by_file.rb index ef931d6..6ef24fc 100644 --- a/lib/git_diff_parser/commits_by_file.rb +++ b/lib/git_diff_parser/commits_by_file.rb @@ -14,7 +14,9 @@ def initialize(commit_log) if !(commit.mhash.nil? || commit.mhash.empty?) commit.comment.each { |comment| if comment =~ /Merge pull request/ - @prs << comment[/\d+/].to_i + id = comment[/\d+/].to_i + text = comment.split(" from ").last + @prs << {:id => id, :text => text} end } end From 225a192337e20c5a82bc8bdd96f78c3219258601 Mon Sep 17 00:00:00 2001 From: Vikas Panwar Date: Fri, 9 Dec 2016 22:58:20 -0800 Subject: [PATCH 5/8] correlate merged commits --- lib/git_diff_parser/commits_by_file.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/git_diff_parser/commits_by_file.rb b/lib/git_diff_parser/commits_by_file.rb index 6ef24fc..9c93c92 100644 --- a/lib/git_diff_parser/commits_by_file.rb +++ b/lib/git_diff_parser/commits_by_file.rb @@ -3,12 +3,26 @@ module GitDiffParser class CommitsByFile def initialize(commit_log) commits = GitDiffParser.parselog(commit_log) + @merge_commits = {} + commits.each { |commit| + if !commit.mhash.nil? + orig_hash = commit.mhash.split(" ").last + @merge_commits[orig_hash] = commit + end + } @commits_by_file = Hash.new {|h,k| h[k]=[]} @prs = [] commits.each { |commit| commit.files.each { |file| - @commits_by_file[file] << commit + short_chash = commit.hash[0...7] + if !@merge_commits[short_chash].nil? + c = @merge_commits[short_chash] + #c.comment << commit.comment + @commits_by_file[file] << c + else + @commits_by_file[file] << commit + end } if !(commit.mhash.nil? || commit.mhash.empty?) From 6d0966aba17ee947a391cb1557681a5e5580e956 Mon Sep 17 00:00:00 2001 From: Vikas Panwar Date: Mon, 12 Dec 2016 17:49:51 -0800 Subject: [PATCH 6/8] make lines public --- lib/git_diff_parser/patch.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/git_diff_parser/patch.rb b/lib/git_diff_parser/patch.rb index 26011b6..5f9ecdb 100644 --- a/lib/git_diff_parser/patch.rb +++ b/lib/git_diff_parser/patch.rb @@ -90,8 +90,6 @@ def find_patch_position_by_line_number(line_number) target.patch_position end - private - def lines @body.lines end From a090da7f8a302a5bb6e8035cf25f690a9406f665 Mon Sep 17 00:00:00 2001 From: Vikas Panwar Date: Fri, 22 Sep 2017 13:57:41 -0700 Subject: [PATCH 7/8] return author with the PR list --- lib/git_diff_parser/commits_by_file.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/git_diff_parser/commits_by_file.rb b/lib/git_diff_parser/commits_by_file.rb index 9c93c92..a2e0ba8 100644 --- a/lib/git_diff_parser/commits_by_file.rb +++ b/lib/git_diff_parser/commits_by_file.rb @@ -30,7 +30,7 @@ def initialize(commit_log) if comment =~ /Merge pull request/ id = comment[/\d+/].to_i text = comment.split(" from ").last - @prs << {:id => id, :text => text} + @prs << {:id => id, :text => text, :author => commit.author} end } end From 3b5641ca0f2be3160114d556885f38efd1e04fb3 Mon Sep 17 00:00:00 2001 From: Vikas Panwar Date: Tue, 10 Oct 2017 08:10:24 -0700 Subject: [PATCH 8/8] clean merge hash when processing commits --- lib/git_diff_parser/commits.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/git_diff_parser/commits.rb b/lib/git_diff_parser/commits.rb index 51f9d72..0f734b2 100644 --- a/lib/git_diff_parser/commits.rb +++ b/lib/git_diff_parser/commits.rb @@ -31,6 +31,7 @@ def self.parse(contents) parsed << Commit.new(hash: chash, mhash: mhash, author: author, date: date, comment: comments, files: files) comments.clear files.clear + mhash.clear body = false end chash = Regexp.last_match[:hash]