Given the initial state:
A - origin/branch-1
|
X A - origin/branch-2
| /
M - master
where both A
commits make the same edit and where it has no overlap with the X
commit, what is the best way to get things to the following state?:
A - origin/branch-1 - origin/branch-2
|
X
|
M - master
Specifically, I want to NOT end up in the following state as (regardless of the physical actions taken) the logical actions are sequential and do not include a merge (i.e. the state where A
didn't follow X
was never valid in the first place and should be removed from the repository):
M - origin/branch-1 - origin/branch-2
| \
A |
| |
X A
| /
M - master
A remote-tracking name like
origin/branch-1
ororigin/branch-2
represents your Git's memory of some other Git's branch name. That is, your Git called up their Git; their Git said mybranch-2 holds hash ID _____
(fill in the blank with an actual hash ID) and your Git then grabbed that commit if necessary, so that you have it, and created or updated yourorigin/branch-2
to point to that commit.Assuming that
A
andA
are reallyA
andA'
—i.e., two different commits with different hash IDs but similar effects), your job is to convince the other Git repository—the one over onorigin
—to set its branch namebranch2
to point to whichever of these two is the desired hash. You have that hash ID in your Git under the nameorigin/branch-1
, so:will have your Git call up the Git at
origin
and tell it: I don't care which commit yourbranch2
identifies right now, make it point to hash ID_____
right now! (with the blank here filled in with the hash ID your Git has stored under the nameorigin/branch-1
).They may obey this command, or they may not. If they don't, you can't fix it from here like this: you will have to get someone who can issue such commands, to do that. That someone might be yourself but logged in to the server directly, or it might be someone with administrative permissions.1
Suppose they do obey. Their
branch-2
currently points to some commit—maybe the one you think, maybe some other commit that's been added since then. Either way, though, they obey your forceful command, and now theirbranch-2
points to the otherA
. Your Git sees that they did obey, and updates yourorigin/branch-2
, and you get what you wanted.Be careful with force-push operations. Note that you can use
--force-with-lease
but to do so you'll need to create a local branch name on your end. The--force-with-lease
operation needs to know what hash ID to hand to them, as it changes the command from I don't care, set to___
to I think your branch is currently___
; if so, set it to___
; either way, tell me if I was right and if you obeyed. To make all this work, your Git you to have your own local namebranch-2
that it can map back to your localorigin/branch-2
so that it can get the hash IDs for both blanks.1As a subterfuge, sometimes if you can't convince another Git to update a branch name, you can just tell that other Git to delete the branch name entirely. Having deleted it, you can then tell that other Git to create a whole new, totally different branch name that merely happens to have the exact same spelling. A lot of times, a Git that won't let you force-update a branch name, will let you delete and re-create it however you like.