In order to support lazily loading the values stored in a user's `.gitconfig`,
we must wait until calling `*config.Configuration.loadGitConfig()` until it is
_absolutely necessary_.
To accomplish this, it was proposed that we introduce a wrapped variant of the
`*Environment` type, only for interacting with the `GitFetcher` that was
capable of supporting such beahvior.
As such, a new implementation of the `Environment` type must be defined. Since
previously there only existed the concrete type `*Environment`, this commit
demotes that down to `*enviornment`, and introduces the interface
`Environment`, which it implements.
Previously, to fetch data out of the `*config.Configuration` type, a reference
to a `Fetcher` was used, a-la:
```
cfg.Env.Get(...)
```
This is quite convenient, however, it forces the LFS client to implement
several methods more than once. Consider the interface:
```
type Fetcher interface {
Get(key string) (val string)
Bool(key string, def bool) (val bool)
// et. al.
}
```
In order to return typed information from a configuration instance, _each_
`Fetcher` must implement its own `N` methods for `Int`, `Bool`, etc.
To remedy this, the `Environment` type was introduced. It instead _has_ a
`Fetcher`, and defines its own type conversions, like so:
```
type Environment struct {
f Fetcher
}
func (e *Environment) Bool(key string, def bool) (val bool) { }
func (e *Environment) Int(key string, def int) (val int) { }
// et. al.
```
Now, the `config.Configuration` type holds a reference to an `Environment`, and
all type conversion methods are defined only once, saving time, and enforcing
consistency across multiple sources.