简体   繁体   中英

How can I update remote branches, after I make a series of commits from a Detached HEAD locally?

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 (ie, 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!

This will solve the case when git push -f and git reset --hard origin/master are not an option (ie the problem before the update in the question).

Create a branch pointing at commit C :

git checkout -b temp origin/master

Then follow the instructions here to revert B and C.

So now your history looks like this:

E (master)
|
D (BC)' (temp, HEAD)
| |
| C (origin/master, origin/HEAD, ec2/master, devserver/master, devserver/HEAD)
| |
| B
| |
|/
A

Now you want to move commits D and E so they are after the revert. There are several ways to do this, one could be:

git checkout master
git rebase temp
git branch -d temp

Now your history looks like this:

E (master, HEAD)
|
D
|
(BC)'
|
C (origin/master, origin/HEAD, ec2/master, devserver/master, devserver/HEAD)
|
B
|
A

Which is safe to push to all of your remotes.

Aha! I looked at the error message a second time, and interpreted it more literally. It then occurred to me that I just gotta hop off the rock I was standing on to move it.

git checkout saving-B-C
git branch -f master E

Success!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM