Git will start to support SHA-256 as a hash for repositories in the near
future. Let's update gitobj to version 2 to support SHA-256
repositories properly. We initialize the repository based on the
extensions.objectFormat value, if one is provided, since this is the
configuration key that represents the hash algorithm.
Vendor the proper dependencies in place.
We have two places in our code where we use gitobj to open an object
database. Our calls will soon be more complex since we must account for
hash algorithm options, so move this code into a function that we can
reuse.
Currently, we only need the operating system environment to pass to the
object scanner, but when we start processing SHA-256 repositories, we'll
also need to know about the Git configuration as well to determine the
extensions.objectFormat value (which specifies the hash algorithm).
Let's pass the Git environment, as well as the OS environment, down to
our object scanner.
There are two ways to specify an alternate in Git: via the repository
file or via the environment. gitobj recently learned how to accept the
contents of an environment variable and use it, so pass the environment
variable when creating a new object database.
When performing a fetch, we don't use the object scanner, but we do when
performing a push. To make sure that we're exercising the object scanner
and gitobj adequately, simulate a push using alternates as well.
We're going to need the environment variables in the object scanner, so
pass the appropriate Environment instance down into the object scanner.
Use an interface to avoid an import loop between the git and config
packages.
Note that the environment is not yet used, but will be in a future
commit.
When we read a tree, commit, or tag from gitobj, the object is
automatically closed for us, since these objects are relatively small
and can be read and parsed all in memory. However, blob objects may be
large, so we return a reader which can be used to read the data from the
object.
In order to properly clean up after ourselves, including closing any
object files which may open, we need to call Close on the blob after
reading it. Otherwise, we'll eventually run out of file descriptors,
causing us to silently hang. Restore the reset function that was
removed in e3fcde74 ("git: replace object scanner with one based on
gitobj", 2018-09-05) and ensure we close objects and reset the object
scanner between every call to Scan.
Currently, our object scanner is based on calling git cat-file --batch.
This is less efficient than reading the objects ourselves in process, so
update the object scanner to use our gitobj package instead.
Remove the reset function from the object scanner, since it is no longer
used. Also, since we no longer need to worry about reading too much
data from git cat-file --batch, switch the io.LimitedReader to a plain
io.Reader to simplify the code.
Note that in the tests we now specify the object ID of the pointer item
to scan since we no longer can implicitly read from a fake buffer.
Consequently, we no longer look for a trailing entry, since that won't
succeed anymore.