Implement discovering branch targets from the archive
With the proper implementation of packfile negotiation, remotes can
return packfiles that do not contain all of our wanted objects. Consider
the following two histories:
- c1 * c1 ← [refs/tags/original]
↑ ↑ ↖
- c2 ← [refs/heads/main] | * c3 ← [refs/heads/main]
- c2 ← [refs/heads/broken]
The first visit of the origin would load commits c1 and c2, and write a
snapshot referencing c2.
During the second visit, the loader would tell the origin that c2 is
known, and that c1 and c3 are wanted (as new heads). The origin, knowing
that c1 is a parent of c2, would be allowed by the git protocol to send
a packfile containing only c3. Under these circumstances, the loader
cannot tell what object type the snapshot branch
[refs/tags/original] should point to.
The repository in tests has a similar structure ([refs/heads/master] is
in the history of [refs/tags/branch2-before-delete]), so refactor the
incremental load test to exercise this specific behavior. This test can
be moved to the common tests as well.