0

I have a history that looks like this:

A-B-C-----------M-I-J-K-L
     \         /
      D-E-F-G-H

master is currently pointing at L. This has already been pushed to origin.

I want to create a new branch which contains D to L and have master (on origin) pointing at C or a checkin that matches C. I need to make sure that anything other clones have done isn't broken. Then at some later point I want to merge D to L back into master and push to origin.

I looked at using revert, but it would appear that will affect what gets merged later. Is there a way to do this, I'm well confused.

Martin Brown
  • 24,692
  • 14
  • 77
  • 122
  • Why do you care what `origin/master` points at - what are you trying to achieve? Non-fast-forward changes to remote branches are generally a bad idea. – Useless Jun 29 '18 at 14:19
  • I care about origin/master as I don't want to screw up anyone else that has cloned. – Martin Brown Jun 29 '18 at 14:50
  • But rewinding origin/master is precisely the thing that will cause them pain. So, _why_ are you trying to rewrite history? Why can't you just use a different branch name for your different branch? – Useless Jun 29 '18 at 16:16
  • I'm not trying to rewrite the history, I'm trying to leave the history as is and create a new commit that does the opposite of what the history did. If that makes sense? – Martin Brown Jul 02 '18 at 16:01
  • Warping origin/master back in time to C _is_ changing history, in that you're pretending whatever sequence of events led to master being on L, never happened. This time-travel is the exact thing that causes problems, which is why I asked what you needed it for. – Useless Jul 02 '18 at 16:23

2 Answers2

1

Start by creating a new branch from L so you've got a reference

git checkout master
git checkout -b thisIsL

Now change master to point to a specific commit deadbeef for want of a better hex value

git branch -f master deadbeef
git push --force origin master

(See this answer.)

BUT this is likely to break any other clones from your remote (any time rebase or the -force flag is used with pushed commits this is likely to be the case). So start by making everyone else has committed everything and is ready to start with a fresh clone (if they end up needing that).

Richard
  • 106,783
  • 21
  • 203
  • 265
  • This is the right answer (but missing the `git push --force origin master` step) with the right caveat: when attempting to remove commits / rewrite history, make sure *all other users* of any clone of the rewritten repository understand that you are doing this and are good with it (in both senses: OK with it happening, and know how to recover on their side). But other users don't always have to start with a fresh clone: they can reset their own `master`, if they know how. – torek Jun 29 '18 at 14:37
  • @torek Of course the push is needed! And your right about the other user's impact (trying to keep things simple...) – Richard Jun 29 '18 at 14:49
  • That BUT is the whole reason why I'm asking this. – Martin Brown Jun 29 '18 at 14:51
  • @MartinBrown Please refine the question to make that clear: you want to know both what you need to do (which is the `branch --force` and `push --force`) and what your co-workers need to do before and after you `--force`? – Richard Jun 29 '18 at 14:57
  • Note for the recovery part lots of interesting pages from a search for `git recover from push force`, but what is right for you will depend on details of your circumstances – Richard Jun 29 '18 at 15:02
0

So here is what I've done, I don't know if this the best solution:

  1. On master I made sure there were no outstanding changes in my working tree.
  2. I used xcopy to take a copy of the entire working tree.
  3. I used git revert to create check-ins that reverse all the changes I don't want in master.
  4. I pushed the revert commits
  5. I created and checked out branch off the latest commit.
  6. I xcopied all the files back from my backup.

This leaves me with one check in on my branch that does all the changes. It perhaps looses a bit of the history, but I think it will merge correctly later down the line.

Martin Brown
  • 24,692
  • 14
  • 77
  • 122