AFAIK the only git command to manipulate upstream tracking branches is git fetch (and other commands that trigger a fetch), but they only really allow a "fast forward" operation against the remote branch.
I would like to have more control and be able to "reset" it like any other local branch, without affecting remote. I think one way is to modify the file at .git/refs/remotes/origin/<branchname> to point to a different SHA, but is that correct/safe?
Why: to decouple multiple ongoing branches/workstreams
Let's say I've got:
* (HEAD -> kache/foo, origin/kache/foo) done, ready to push
| * (kache/bar) almost done, commits are atomic
|/
| * (kache/baz) still wip, commits are a mess
|/
* (main, origin/main)
I discover that foo needs a fresh main (for w/e reason), so I fetch origin/main, rebase foo on top, and then get it merged.
But now, main is far behind origin/main. Before I context switch, getting back a "clean slate" means forwarding main to origin/main and rebasing all branches on top. Should rebase conflicts arise, bar will be easy to fix, but baz won't.
I generally have many local dev branches and working on a single one (foo) has caused a workflow interruption on every other branch. In addition, the more "wip" like baz there are, the worse the mass-rebase overhead will be.
I've already tried/got various "rebasing a tree" solutions. I'll keep trying, but solving the general-case means being resilient against (multiple) rebase conflicts, being abort-able (atomic), retryable (recorded resolutions), etc, and AFAIK a general-case turnkey solution doesn't exist.
In this situation, I'd like to just reset origin/main back to main. Once foo is merged, I can delete my local foo, reset my origin/main, and immediately context-switch to bar or baz. Unlike a mass-rebase, it would be fast and would always work. I'd be able to fetch main and mass-rebase later when it's convenient, decoupling my foo workstream from every other.