new_contents: #!/usr/bin/env python
  
  """
  """
  
  from subprocess import check_output
  import json
  from copy import deepcopy
  
  # The JSON object to
  JSON_LINE = {
      "repo_name": None,
      "commit_id": None,
      "author": None,
      "author_mail": None,
      "author_time": None,
      "author_timezone": None,
      "committer": None,
      "committer_mail": None,
      "committer_time": None,
      "committer_timezone": None,
      "comment": None,
      "filename": None,
      "line_num": None,
      "line": None,
  }
  
  
  def block_generator(filename):
      """Generates a set of "data blocks" using `git blame` from a file.
  
      Each block corresponds to the information about a single line of code as
      reported by `git blame --line-porcelain -- $FILE`.
  
      The porcelain output from `git` guarantees that the content line for a
      block of data starts with a '\\t' character. Lines are buffered by the
      generator until one starting with a '\\t' is found, at which point the
      buffer is yielded and cleared.
  
      Args:
          filename (str): The name of the file to run `git blame` on.
  
      Yields:
          list: A list of the lines in the porcelain output corresponding to a
              single line in the source file.
      """
      # Get the text from blame
      command = [
          'git',
          'blame',
          '--line-porcelain',
          '--',
          filename,
      ]
  
      blame = check_output(command)
  
      # Buffer the lines from the output until we find one that starts with \t,
      # indicating
      buffer = []
      for line in blame.splitlines():
          buffer.append(line)
          if line.startswith('\t'):
              yield buffer
              buffer = []
  
  
  def block_to_JSON(block, repo_name=None):
      """Take a data block and generate a JSON objects containing the
      same information.
  
      Args:
          block (list): A data block as generated by block_generator()
          repo_name (str, optional): The name of the repository.
              Defaults to None.
  
      Returns:
          str: A JSON object as a string (encoded using json.dumps()).
      """
      current_json = deepcopy(JSON_LINE)
  
      # Function to strip < and > from around email addresses
      def clean_email(email): return email.strip("<>")
  
      # Function to convert timezone to hour office integer
      def tz_int(tz): return int(tz, 10) / 100
  
      # Translation from the porcelain key to the key in our JSON object, as well
      # as an option transformation to apply first
      porcelain_to_json = {
          "author": ("author", None),
          "author-mail": ("author_mail", clean_email),
          "author-time": ("author_time", int),
          "author-tz": ("author_timezone", tz_int),
          "committer": ("committer", None),
          "committer-mail": ("committer_mail", clean_email),
          "committer-time": ("committer_time", int),
          "committer-tz": ("committer_timezone", tz_int),
          "summary": ("comment", None),
          "filename": ("filename", None),
      }
  
      # Set the name of the repo
      current_json["repo_name"] = repo_name
  
      # The header is of the form:
      #
      # hash original_line_number final_line_number group_end_line_number
      #
      # where group_end_line_number is optional and unused by us (it is redundant
      # when using `--line-porcelain`)
      header = block[0].split()
      current_json["commit_id"] = header[0]
      current_json["line_num"] = int(header[2])
  
      # The remaining body, except the final line, are not guaranteed to exist,
      # but are identified by the first word on the line
      for line in block[1:-1]:
          sline = line.split()
          key = sline[0]
          content = sline[1]
  
          try:
              (json_key, transform) = porcelain_to_json[key]
          except KeyError:
              # The spec allows additional lines to be added to the body of the
              # porcelain block, in which case the key may not exist in our
              # mapping. In this case, the best option is to skip the line and
              # continue.
              continue
          if transform is not None:
              content = transform(content)
          current_json[json_key] = content
  
      # The final line is the raw text of line's content, with an extra '\\t'
      # prepended
      current_json["line"] = block[-1][1:]  # Remove the leading tab
  
      return json.dumps(current_json)
  
  
  def file_to_json(filename, repo_name=None):
      """Returns a list of JSON objects containing the blame information
      associated with each line of the input file.
  
  
      Args:
          filename (str): The name of the file to run `git blame` on.
          repo_name (str, optional): The name of the repository.
              Defaults to None.
  
      Returns:
          list: A list containing strings of the JSON objects.
  
      """
      lines = []
      for block in block_generator(filename):
          lines.append(block_to_JSON(block))
  
      return lines
  
subject: Add code to convert `git blame` to JSON