## Working internally with push/pull (remotes, caching, and you)
Pijul recognizes two "views" of a (remote, channel) pair. The first is just the actual state of the (remote, channel). The second is a locally stored version of the remote, which is the last version of the actual remote that we've signed off on (we'll continue to call this the "local remote cache"). During a push or pull, the local remote cache almost always just downloads and caches whatever new patches are present in the (remote, channel) before you select what you actually want to push or pull via hunk selection. (NOTE: For `LocalChannel` remotes, there's no local cache; `LocalChannel` means it's just another channel in the same repository you're already working in).
API notes:
+ As usual, we need some kind of Transaction for most of the interactions with either view of a remote.
+ `pijul::remote::RemoteRepo` represents the _actual_ remote.
+ `libpijul::pristine::RemoteRef` represents the local cache of the last remote we've signed off on.
Example of the base case:
+ local/master is comprised of the patches `[(0, A), (1, B)]`
+ remote/bugfix is comprised of the patches `[(0, A), (1, B), (2, C), (3, D), (4, E)]`
If we invoke `pijul pull remote/bufgix`, pijul will put the new patches `[(2, C), (3, D), (4, E)]` in the local remote cache for `remote/bugfix`, and ask which of the new changes you actually want to pull into `local/master`. Now, even if only `(2, C)` is pulled via hunk selection, subsequent pull operations generally won't have to re-download `(3, D)` and `(4, E)`.
At time of writing, the only notable exception to this straight-forward caching strategy is if the actual remote has unrecorded a patch that ALSO exists in the channel we're pulling to or pushing from.
Example of the exceptional case:
we're pulling from remote/bugfix into local/master.
+ local/master is comprised of the patches `[(0, A), (1, B), (2, C), (3, D)]`,
+ the last version of `remote/bugfix` we saw was `[(0, A), (1, B), (2, C)]`
If, when we invoke `pijul pull remote/bugfix`, we discover that the new set of changes comprising that (remote, channel) is `[(0, A), (_, _), (_, _), (3, X), (4, Y)]`, meaning that the actual remote has unrecorded `(1, B)` and `(2, C)` since the last time we interacted with it, then the patches after the dichotomy (the last point at which the local remote cache and the actual remote were the same; here `(0, A)`) will not be cached.
We want to notify user that `(1, B)` and `(2, C)` have been unrecorded in the remote they're pulling from (or pushing to) before they're presented with hunk selection, and preserving the divergence between the local remote cache and the actual remote allows us to do this. Furthermore, we don't want to overwrite the local remote cache, because we want to continue to remind the user of this unrecord until either a) the user forces the cache to update (with the `--force-cache` flag), or b) the user fixes the discrepancy by unrecording `(1, B)` and `(2, C)` in local/master.
For the sake of completeness, if the actual remote has unrecorded one or more patches, but they do NOT exist in the channel we're trying to pull/push to, the cache will be updated and the user will not be notified. It is assumed that the user isn't concerned with those patches since they were either actively ignored during a previous hunk selection, or we never knew about them in the first place.