this change improves drastically pre-push behaviour, by not sending
lfs objects which are already on a remote. Works perfectly with
pushing new branches and tags.
currently pre-push command analyse "local sha1" vs "remote sha1" of the
ref being pushed and if "remote sha1" is available locally tries to send
only lfs objects introduced with new commits.
why this is broken:
- remote branch might have moved forward (local repo is not up to date).
In this case you have no chance to isolate new lfs objects ("remote sha1"
does not exist locally) and git-lfs sends everything from the local
branch history.
- remote branch does not exist (or new tag is pushed). Same consequences.
But what is important - local repository always have remote references,
from which user created his local branch and started making some local
changes. So, all we have to do is to identify new lfs objects which do
not exist on remote references. And all this can be easily achieved with
the same all mighty git rev-list command.
This change makes git-lfs usable with gerrit, where changes are uploaded
by using magic gerrit branches which does not really exist. i.e.
git push origin master:refs/for/master
in this case "refs/for/master" does not exist and git feeds all 0-s as
"remote sha1".
Reorganize the transfer queue to provide a channel to watch for object
OIDs as they finish. This can be used in the `get` command to feed a
goroutine that will copy the file to the working directory and inform
the update-index process about it as the transfers finish. This leads to
a greatly reduced amount of time spent updating the index after a get.
This refactoring will make a number of things easier. These didn't
really need to be in their own packages. Having them separate packages,
there are a few refactorings I've tried to do that end up with circular
dependencies due to things outside of `lfs` depending on `lfs`. Pushing
these into `lfs` makes refactoring simpler.