The only reasonable way to explain what happened is with diagrams (commits are alphabeti-chronological)
Starting state:
C (master, HEAD, origin/master, origin/HEAD, ec2/master, devserver/master, devserver/HEAD)
|
B
|
A
Then I went back to A because I went in the wrong direction with B and C: git checkout A
C (master, origin/master, origin/HEAD, ec2/master, devserver/master, devserver/HEAD)
|
B
|
A (HEAD)
Now I make a string of new good changes:
E (HEAD)
|
D
|
| C (master, origin/master, origin/HEAD, ec2/master, devserver/master, devserver/HEAD)
| |
| B
| |
|/
A
Crap. Forgot I left my HEAD detached. Okay. Let's try this!
git branch -f master E
E (master, HEAD)
|
D
|
| C (origin/master, origin/HEAD, ec2/master, devserver/master, devserver/HEAD)
| |
| B
| |
|/
A
Here is where I am now. I recognize that if I run git pull
, I'm gonna pull in crappy changes from B and C. I am unsure what will happen if I try to git push
.
Do I have to go to all remotes and do git revert
and then get those new "revert" commits to be merged back in on here? Is that the way to go about it? Having extra merge-related commit clutter is okay, but I am hoping that there is a way to get out of this situation without leaving a mess.
I'd ideally like to keep the history of B and C in case I do want them back. I guess I need to make a branch to do that properly, but for now these changes are not important enough even to warrant the effort required to configure (and think of a name for) a branch for them.
I did some searching and find that git revert -m
-something is likely appropriate, but I'm unsure how to apply it (i.e., I'm not sure how i can be sure that B and C are thrown out when merging). As you can see I have many remotes and would prefer a command I can safely and easily apply to all the remotes (or even more awesome maybe theres something I can list all the remotes to run it for).
Update:
I have now dug a slightly deeper hole:
I ran git push -f
on all my remotes.
So, a fresh user would pull in this:
E (master, HEAD, origin/master, origin/HEAD, ec2/master, devserver/master, devserver/HEAD)
|
D
|
A
However I forgot about how I have stuff set up on ec2, where that server's bare repo has a post-receive hook which cd's to a local regular repo, and runs git pull
from there. So I do have a virtual user who is pulling all the branches all the damn time.
For this repo it now looks like this, because this user has only one remote, origin
, which is the same remote as ec2
from my macbook (all other diagrams):
E (origin/master, origin/HEAD)
|
D
|
| C (HEAD, master)
| |
| B
| |
|/
A
At this point I figured, okay I will just go and save B and C after all (and push them in later as a branch to remote and it should be safely propagatable):
E (origin/master, origin/HEAD)
|
D
|
| C (HEAD, saving-B-C, master)
| |
| B
| |
|/
A
But here's where I get stuck:
$ git branch -f master E
fatal: Cannot force update the current branch.
Help!