9

We are sick of linting. So we want to use black in our project. Unfortunately, it changes almost every other line in our project which would make us loose most of our authorship information. We use annotate in pycharm or git blame a lot to figure out who to talk to when looking at specific code pieces. How could this information be preserved when changing lots of files in one commit?

Edit: As this is a duplicate of this question, I'd like to focus rather on a "as good as possible" approach.

Let's assume the lint commit is created by an artificial (but known) author, hence serving as a flag. Is it then possible to create a git blame like output which shows all authors since this key lint commit as well as any previous author of lines that were changed in that commit?

I realize this wouldn't work well for lines that were split / merged but it at least gives a faster way to limit the scope of potential persons to talk to to 1,2,3 people.

pascalwhoop
  • 2,984
  • 3
  • 26
  • 40
  • It can't, there's nothing in git that will help you. The last person that runs a reformatter will take "ownership" of all the lines that were modified. However, does black change everything, **all the time**? – Lasse V. Karlsen Feb 11 '19 at 12:21
  • I think the answer is likely "it can't in all cases", consider when black collapses two lines by different authors. `git log -G ... ` is probably a good tool to start using – anthony sottile Feb 11 '19 at 12:22
  • No but of course a project with some 100k+ lines of code will now be dominated by one author even if that author is an artificial one like `lint bot` to signal that there is actually someone else "behind" that line. – pascalwhoop Feb 11 '19 at 12:23
  • 1
    Possible duplicate of [How do I run a code formatter over my source without modifying git history?](https://stackoverflow.com/questions/53502654/how-do-i-run-a-code-formatter-over-my-source-without-modifying-git-history) – phd Feb 11 '19 at 13:04

2 Answers2

3

From https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revltrevgt:

--ignore-rev

Ignore changes made by the revision when assigning blame, as if the change never happened. Lines that were changed or added by an ignored commit will be blamed on the previous commit that changed that line or nearby lines. This option may be specified multiple times to ignore more than one revision. If the blame.markIgnoredLines config option is set, then lines that were changed by an ignored commit and attributed to another commit will be marked with a ? in the blame output. If the blame.markUnblamableLines config option is set, then those lines touched by an ignored commit that we could not attribute to another revision are marked with a *.

If the code formatting is all done in a single commit, I think you could use that flag. There's also a --ignore-revs-file that looks useful if you want to ignore more than a single commit.

0

I've created a script which only changes lines of a given author. Every author could apply this to the code base and would keep the code authorship.


import git
import black
from blib2to3.pgen2.tokenize import TokenError

new_lines = list()
author_email = "example@example.org"
filename = "setup.py"
for commit, lines in repo.blame('HEAD', filename):
    if author_email == commit.author.email:
        try:
            new_lines.append(
                black.format_str(
                    "\n".join(lines), 
                    mode=black.Mode()
                )
            )
        except:
            new_lines.extend(lines)
    else:
        new_lines.extend(lines)
open(filename, "w").writelines(new_lines)

The script can only change code lines which together makes sense to black. If an author only changed one line in a multiline statement it does not change it. Therefore after every author applied the script, some lines still need to be changed by black. However, the amount of lines will be much smaller than before.

Updates can be found here: https://gist.github.com/JulianWgs/ba762ba729d8f17090cafd5230261ab2

JulianWgs
  • 961
  • 1
  • 14
  • 25