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-1ororigin/branch-2represents 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-2to point to that commit.Assuming that
AandAare reallyAandA'—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 namebranch2to 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
originand tell it: I don't care which commit yourbranch2identifies 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-2currently 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-2points 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-leasebut to do so you'll need to create a local branch name on your end. The--force-with-leaseoperation 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-2that it can map back to your localorigin/branch-2so 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.