def _hunks(self, commit, changed_files): git = self.git hunks = dict() if not changed_files: return hunks for changed_file in changed_files: try: blame = git.blame(commit + '^!', '--', changed_file, incremental=True) except GitCommandError: continue blame = blame.split('\n') hh = [ tuple([int(x) for x in blame[0].split()[2:4]]), ] blame = blame[1:] next_is_hunk = False for line in blame: if line.startswith('filename '): next_is_hunk = True continue if next_is_hunk: next_is_hunk = False line_split = line.split() if line_split[0] != commit: continue hh.append(tuple([int(x) for x in line_split[2:4]])) hunks[changed_file] = (tuple(hh)) return hunks
def _hunks(self, commit, changed_files): git = self.git hunks = dict() if not changed_files: return hunks for changed_file in changed_files: try: blame = git.blame(commit + '^!', '--', changed_file, incremental=True) except GitCommandError: continue blame = blame.split('\n') hh = [tuple([int(x) for x in blame[0].split()[2:4]]),] blame = blame[1:] next_is_hunk = False for line in blame: if line.startswith('filename '): next_is_hunk = True continue if next_is_hunk: next_is_hunk = False line_split = line.split() if line_split[0] != commit: continue hh.append(tuple([int(x) for x in line_split[2:4]])) hunks[changed_file] = (tuple(hh)) return hunks
def _was_fixed(self, hunks, followup): git = self.git followup_changed = git.diff(followup + '^!', diff_filter='M', name_only=True) followup_changed = followup_changed.split('\n') fixed_files = [] for changed in followup_changed: if changed in hunks: added_lines = set() for hh in hunks[changed]: added_lines.update(range(hh[0], hh[0] + hh[1])) try: blame = git.blame(followup + '^!', '--', changed, incremental=True, reverse=True) except GitCommandError: continue blame = blame.split('\n') first = blame[0].split() boundary = first[0] followup_deleted = set() followup_deleted.update( range(int(first[1]), int(first[1]) + int(first[3]))) blame = blame[1:] next_is_hunk = False for line in blame: if line.startswith('filename '): next_is_hunk = True continue if next_is_hunk: next_is_hunk = False line_split = line.split() if line_split[0] != boundary: continue followup_deleted.update( range(int(line_split[1]), int(line_split[1]) + int(line_split[3]))) if not followup_deleted.isdisjoint(added_lines): fixed_files.append(changed) if len(fixed_files) > 0: return tuple(fixed_files) return None
def _was_fixed(self, hunks, followup): git = self.git followup_changed = git.diff(followup + '^!', diff_filter='M', name_only=True) followup_changed = followup_changed.split('\n') fixed_files = [] for changed in followup_changed: if changed in hunks: added_lines = set() for hh in hunks[changed]: added_lines.update(range(hh[0], hh[0] + hh[1])) try: blame = git.blame(followup + '^!', '--', changed, incremental=True, reverse=True) except GitCommandError: continue blame = blame.split('\n') first = blame[0].split() boundary = first[0] followup_deleted = set() followup_deleted.update(range(int(first[1]), int(first[1]) + int(first[3]))) blame = blame[1:] next_is_hunk = False for line in blame: if line.startswith('filename '): next_is_hunk = True continue if next_is_hunk: next_is_hunk = False line_split = line.split() if line_split[0] != boundary: continue followup_deleted.update(range(int(line_split[1]), int(line_split[1]) + int(line_split[3]))) if not followup_deleted.isdisjoint(added_lines): fixed_files.append(changed) if len(fixed_files) > 0: return tuple(fixed_files) return None