I originally wanted this script to be more generic and look for *any* modified binary files that are over a certain threshold, but it took ~88 minutes to run over the entire library, and almost all that time was spent in `git` itself generating commit diffs (since they're not stored on-disk in such a way that those commit diffs are inexpensive to calculate).
I also did a rough prototype in Go using https://github.com/src-d/go-git but it had essentially the same speed (as expected, since it's the underlying data that makes it expensive to calculate, not the language being used to request the data).
So, instead this looks for modified files which match `**.tar**`, which should match the ones we typically worry about anyhow (there are some other problematic cases, but they aren't going to be rebased anytime soon because they've been problematic for so long so aren't worth bending over backwards to detect).
In particular, our namespace changes made `bashbrew list --build-order wordpress php` work properly but `bashbrew --namespace amd64 list --build-order wordpress php` does not -- these changes adjust our sorting to take into account both the namespaced and the non-namespaced version of each tag in our library when checking the `FROM` values for sorting purposes.
This allows bashbrew to properly handle cross-repository and cross-tag dependencies even in the face of multiple `FROM` instructions or `COPY --from=`.
This also provides the scaffolding necessary to implement this in scripts using `bashbrew cat`.
As fallback behavior, the `*DockerFrom` functions should return the `FROM` of the last stage in the `Dockerfile` (which is essentially the `FROM` of the final image).
Also, the output of `bashbrew from` is now a space-separated list.
This is a replacement for `bashbrew put-shared` (without `--single-arch`) that takes some shortcuts to get a pretty decent speed gain which should allow us to go back to the naïve solution of "push everything from each arch `:xyz-tag` to the multiarch repo's `:xyz-tag` and still have reasonable performance.
This was tested by pushing all ~3700 tags we currently have to https://hub.docker.com/u/trollin and for a full no-op we were around 8.5 minutes, and for a full forced push of every tag manifest (with no necessary blob mounts) we were around 45 minutes.