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.