# Buggy code
def _process_changes(self, newRev, branch):
    """
    Read changes since last change.

    - Read list of commit hashes.
    - Extract details from each commit.
    - Add changes to database.
    """

    # initial run, don't parse all history
    if not self.lastRev:
        return

    # get the change list
    revListArgs = (
        ["--format=%H", "{}".format(newRev)]
        + ["^" + rev for rev in sorted(self.lastRev.values())]
        + ["--"]
    )
    self.changeCount = 0
    results = yield self._dovccmd("log", revListArgs, path=self.workdir)

    # process oldest change first
    revList = results.split()
    revList.reverse()

    if self.buildPushesWithNoCommits and not revList:
        existingRev = self.lastRev.get(branch)
        if existingRev != newRev:
            revList = [newRev]
            if existingRev is None:
                # This branch was completely unknown, rebuild
                log.msg(
                    'gitpoller: rebuilding {} for new branch "{}"'.format(
                        newRev, branch
                    )
                )
            else:
                # This branch is known, but it now points to a different
                # commit than last time we saw it, rebuild.
                log.msg(
                    'gitpoller: rebuilding {} for updated branch "{}"'.format(
                        newRev, branch
                    )
                )

    self.changeCount = len(revList)
    self.lastRev[branch] = newRev

    if self.changeCount:
        log.msg(
            'gitpoller: processing {} changes: {} from "{}" branch "{}"'.format(
                self.changeCount, revList, self.repourl, branch
            )
        )

    for rev in revList:
        dl = defer.DeferredList(
            [
                self._get_commit_timestamp(rev),
                self._get_commit_author(rev),
                self._get_commit_committer(rev),
                self._get_commit_files(rev),
                self._get_commit_comments(rev),
            ],
            consumeErrors=True,
        )

        results = yield dl

        # check for failures
        failures = [r[1] for r in results if not r[0]]
        if failures:
            for failure in failures:
                log.err(
                    failure, "while processing changes for {} {}".format(newRev, branch)
                )
            # just fail on the first error; they're probably all related!
            failures[0].raiseException()

        timestamp, author, committer, files, comments = [r[1] for r in results]

        yield self.master.data.updates.addChange(
            author=author,
            committer=committer,
            revision=bytes2unicode(rev, encoding=self.encoding),
            files=files,
            comments=comments,
            when_timestamp=timestamp,
            branch=bytes2unicode(self._removeHeads(branch)),
            project=self.project,
            repository=bytes2unicode(self.repourl, encoding=self.encoding),
            category=self.category,
            src="git",
        )


# Traceback (buildbot.changes.gitpoller.GitError)
buildbot_1               | 2019-12-16 14:43:59+0000 [-] trying to poll branch refs/heads/5.3 of https://github.com/aliceinwire/linux-patches
buildbot_1               |      Traceback (most recent call last):
buildbot_1               |        File "/usr/lib/python3.6/site-packages/twisted/internet/defer.py", line 654, in _runCallbacks
buildbot_1               |          current.result = callback(current.result, *args, **kw)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/twisted/internet/defer.py", line 1475, in gotResult
buildbot_1               |          _inlineCallbacks(r, g, status)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/twisted/internet/defer.py", line 1416, in _inlineCallbacks
buildbot_1               |          result = result.throwExceptionIntoGenerator(g)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
buildbot_1               |          return g.throw(self.type, self.value, self.tb)
buildbot_1               |      --- <exception caught here> ---
buildbot_1               |        File "/usr/lib/python3.6/site-packages/buildbot/changes/gitpoller.py", line 226, in poll
buildbot_1               |          yield self._process_changes(revs[branch], branch)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/twisted/internet/defer.py", line 1416, in _inlineCallbacks
buildbot_1               |          result = result.throwExceptionIntoGenerator(g)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
buildbot_1               |          return g.throw(self.type, self.value, self.tb)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/buildbot/changes/gitpoller.py", line 316, in _process_changes
buildbot_1               |          results = yield self._dovccmd('log', revListArgs, path=self.workdir)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/twisted/internet/defer.py", line 1416, in _inlineCallbacks
buildbot_1               |          result = result.throwExceptionIntoGenerator(g)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/twisted/python/failure.py", line 512, in throwExceptionIntoGenerator
buildbot_1               |          return g.throw(self.type, self.value, self.tb)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/buildbot/changes/gitpoller.py", line 410, in _dovccmd
buildbot_1               |          stdout = yield self._dovccmdImpl(command, args, path, None)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
buildbot_1               |          result = g.send(result)
buildbot_1               |        File "/usr/lib/python3.6/site-packages/buildbot/changes/gitpoller.py", line 441, in _dovccmdImpl
buildbot_1               |          full_args, path, self.repourl, code, stderr))
buildbot_1               |      buildbot.changes.gitpoller.GitError: command ['log', '--format=%H', '0ed25f649e3464d2d4a156d1ec101d471e87f711', '^0632b05dfe0edf20e50d473d3c174fda502d6808', '^077ba01d4280501028651068c5276ca67f0a827f', '^077ba01d4280501028651068c5276ca67f0a827f', '^0b3da0b3904e0dabb4d3ba04448ba3169b8599d8', '^0b3da0b3904e0dabb4d3ba04448ba3169b8599d8', '^0ed25f649e3464d2d4a156d1ec101d471e87f711', '^0ee489d1a3a6a217d26da42a6151dc67d33ca20c', '^0f69e0c144eb22f7b48b0c48d4bbdca32290481d', '^107277b141052bc8f7fe406453cdb51e4bb0fc1d', '^111b09445ca154f9feee0743aa1a84f9250a2dab', '^1ed332103c66657d4606ae29c42ba41adb713a3d', '^203f855f3df02c2e1878212e32716806671716cd', '^203f855f3df02c2e1878212e32716806671716cd', '^389573bf5cf2f40a9ec37dfc15e4f14ca9e0a74d', '^398f49b48283feeacc2e0ed33dc6951e0978ada1', '^3a9d9184e1f0d412574eabf24e5cd3586f69d3e9', '^47283ffe7b6fc31c1326713424e59ca4852ab7d4', '^4bcce038842874ce87861be9f9682af7c21c9d61', '^4f401f0d67bf9ea50c8d9ebc772844fd26b4e99d', '^5f1fcf42d2b9edd5baca2940182eb948753faf2a', '^63a8f3beb3c3ac5417e18aad9ed0b4001e5c92b3', '^64881833b8854f3c3a82270811c619b49e013da7', '^679479168a68ec71fc95e7a66dac25305220e45f', '^70fa93ee16ccde9d51810e352e2a25b7edb13e78', '^71ec30f97ea667e987e0de30f7592909cfa96685', '^7204d256da7c380bc6fcc48f4acebc4b1e6fed07', '^9182fc70611d1887e3090d9768655dacf0a7fb06', '^a1276f7f2c41720aeee601e59069f45f1fb5ebf2', '^aacb6d87890588e839500bcfeabb1fde7bf93e35', '^ae029c4cde3493b928e501e846e93cc067b4a845', '^af6dfb8341d6ec2f07e8be8c04cc67db993f7d5c', '^afdf80395cd18368043156124343e742f3cb572c', '^b40e4b7205dd73330cf29bf39590327f973a473b', '^b9fd7bdba6609d0fa42485ee3cdee8f607a321ec', '^b9fd7bdba6609d0fa42485ee3cdee8f607a321ec', '^c75c995c2729fd757a3c04492a7adac5e31b18c0', '^cec555b10aaa9021172ca97c9c4f3a605f82ffb8', '^d3b6891f47be9ecc46753b7da1ae9d4ab09e004a', '^d9a7b48394c11e665ecac4ddb28dfae1fb8a2a42', '^dadae5e6ec2d9d5e86edccb8cbeb728efc26033c', '^dadae5e6ec2d9d5e86edccb8cbeb728efc26033c', '^df00160fd19ac3ffbd1887ee9bdc64384f4f8421', '^e54c798c11904682e91e05d4114b6bf7181ed8b9', '^e70e295836f04951c3eeaf0bdba524da86691c26', '^f038ea3a40fec1a50410f3e39b1ca402f8d6543c', '^f038ea3a40fec1a50410f3e39b1ca402f8d6543c', '^f0c91086a01b8aebce1a268d2545b694d3e52c39', '^f209e98096e70700cfc4d98580b2f817781c15b6', '--'] in /var/lib/buildbot/gitpoller-work on repourl https://github.com/aliceinwire/linux-patches failed with exit code 128: fatal: bad object e70e295836f04951c3eeaf0bdba524da86691c26
buildbot_1               |

# Fixed code
def _process_changes(self, newRev, branch):
    """
    Read changes since last change.

    - Read list of commit hashes.
    - Extract details from each commit.
    - Add changes to database.
    """

    # initial run, don't parse all history
    if not self.lastRev:
        return

    # get the change list
    revListArgs = (
        ["--ignore-missing"]
        + ["--format=%H", "{}".format(newRev)]
        + ["^" + rev for rev in sorted(self.lastRev.values())]
        + ["--"]
    )
    self.changeCount = 0
    results = yield self._dovccmd("log", revListArgs, path=self.workdir)

    # process oldest change first
    revList = results.split()
    revList.reverse()

    if self.buildPushesWithNoCommits and not revList:
        existingRev = self.lastRev.get(branch)
        if existingRev != newRev:
            revList = [newRev]
            if existingRev is None:
                # This branch was completely unknown, rebuild
                log.msg(
                    'gitpoller: rebuilding {} for new branch "{}"'.format(
                        newRev, branch
                    )
                )
            else:
                # This branch is known, but it now points to a different
                # commit than last time we saw it, rebuild.
                log.msg(
                    'gitpoller: rebuilding {} for updated branch "{}"'.format(
                        newRev, branch
                    )
                )

    self.changeCount = len(revList)
    self.lastRev[branch] = newRev

    if self.changeCount:
        log.msg(
            'gitpoller: processing {} changes: {} from "{}" branch "{}"'.format(
                self.changeCount, revList, self.repourl, branch
            )
        )

    for rev in revList:
        dl = defer.DeferredList(
            [
                self._get_commit_timestamp(rev),
                self._get_commit_author(rev),
                self._get_commit_committer(rev),
                self._get_commit_files(rev),
                self._get_commit_comments(rev),
            ],
            consumeErrors=True,
        )

        results = yield dl

        # check for failures
        failures = [r[1] for r in results if not r[0]]
        if failures:
            for failure in failures:
                log.err(
                    failure, "while processing changes for {} {}".format(newRev, branch)
                )
            # just fail on the first error; they're probably all related!
            failures[0].raiseException()

        timestamp, author, committer, files, comments = [r[1] for r in results]

        yield self.master.data.updates.addChange(
            author=author,
            committer=committer,
            revision=bytes2unicode(rev, encoding=self.encoding),
            files=files,
            comments=comments,
            when_timestamp=timestamp,
            branch=bytes2unicode(self._removeHeads(branch)),
            project=self.project,
            repository=bytes2unicode(self.repourl, encoding=self.encoding),
            category=self.category,
            src="git",
        )