ensure_binary_mode: python3 and python2/win32 compatibility

Python-3 needs binary mode so that it doesn't try to read into unicode
strings. Python-2 just uses bytes on Linux, but needs the mode set to binary
on Windows.

The smudge filter must also read binary because we can have files with a
"managed" extension that is not actually managed by git-fat. In that
case, we get raw binary data on stdin. It will not match our cookie, but
we must not corrupt its contents in the working tree, thus we have to
treat it as binary.
Abstract the backend and add S3 implementation
encoding: use uninterpreted bytes whenever possible

Git is encoding-agnostic in the sense that it interprets file contents,
commit messages and paths as binary. In the case of paths, this means
that the non-NUL bytes returned from readdir(2) are stored and later
passed to lstat(2) and creat(2). See git-commit(1) for details.

To be compatible with Git's mode of operation, we also use raw bytes
whenever possible. hashlib's hexdigest returns Python 'str', which we
immediately encode as ASCII so that it can be used with path component
and cleaned bytes to be committed.

Renamed variable 'bytes' to 'bytecount' due to conflict with type

Includes contributions from: Stephen Miller <stephen.l.miller1@navy.mil>