These now exist in prepare_upload.py, so we can call that function
instead. That API isn't stable, but Steve prefers that to this code
duplication in his review in the MP, and I don't have a strong opinion.
prepare_upload: rename printargs to establish_args
Now that the Python printargs method doesn't actually print the
arguments, it's a misnomer and establish_args is better. "Establish"
because it has side-effects (possible fetch, push, force-push) before
the args are known to be correct.
Add a --force-push command to pass on as --force to "git push", so that
if an uploader has amended their branch locally, they can push that rich
history directly with prepare-upload.
Since we now fetch first, we can detect when a force push would be
required, and fail with a friendly error message if this is the case and
--force-push was not specified.
This is a major refactoring/rewrite of the prepare-upload code. So much
changed that it didn't seem worth breaking it down. It's probably easier
to review afresh.
Functionally, what has changed is that we now fetch from the remote
using its default configured refspecs first, assuming that this will
update the remote tracking branch following normal conventions. Then we
can determine if the remote branch already contains our rich history or
not. We then only push if it does not.
In the code, this involved considerable refactoring. There is now a
Parameters namedtuple that carries the various facts around, and the
determination of these facts are moved into a classmethod constructor.
Various common steps between the "args" and "mangle" operations are
broken out.
Rich history may be supplied in such a way that fetching it requires
authentication. For example, Launchpad does this when referring to a
repository that does not exist, since a private repository may become
visible following authentication.
For rich history purposes, we should ignore this case and ensure that
git does not prompt the user for authentication but instead treat the
case as "rich history not provided".
It does not seem worth arranging a test for this, since we would need to
fake a remote repository that requires authentication and we don't
currently have (and until now have not needed) a test fixture for that.
I have tested this implementation manually. It is unlikely to regress in
our code base. If it were to regress because a future version of git
changes behaviour, then behaviour would revert back to a soft failure,
and we would be able to detect and debug the problem from there.