3

A classic case of "don't start from here"... as is the way of all things, disorganisation has descended on our Git, tree looks something like this:

A-B-C-D  master
       \
        E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T... exciting new stuff

Whereas the unfortunate truth that it would be better reflected something like this:

                            P-Q failed idea
                           /
A-B-C-D                K-L-M-N-O       U-V... master
       \              /         \     /
        \            /           R-S-T oh god fix it fix it arghh
         \          /
         E-F-G-H-I-J  exciting new stuff

For ease of annotation, let's use numbers:

                            P-Q Branch 2
                           /
A-B-C-D                K-L-M-N-O       U-V... master
       \              /         \     /
        \            /           R-S-T Branch 3
         \          /
         E-F-G-H-I-J  Branch 1

Closest thing I've found is this question:

How do I move recent (but not latest) commits to a new branch

But I'm not clear enough on what the top answer actually ends up doing to make me want to try it and see.

If it helps, the project is small and not being actively worked on by multiple people, so assume that we can get away with naughty behaviour like "changing history". It's all living on a github server if that makes a difference, so we want to end up with the changes reflected on that server not just locally.

EDIT:

OK I'll try and be a bit clearer on what I'd like to do.

I really should have said: PQ was a dead-end development that was effectively rolled-back by , so handle that as you feel is best! This project has suffered chaos panic and disorder worthy of an entire volume of Dilbert strips and consequently the Git tree and my own mental sanity have suffered significantly.

Starting point the current tree looks like this:

A-B-C-D  master
       \
        E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T... exciting new stuff

Step 1 I'd like to end up with this:

A-B-C-D             K-L-M-N-O-P-Q-R-S-T... master
       \           /
        E-F-G-H-I-J Branch 1

Step 2 I'd then like to do this:

                              P-Q  Branch 2
                             /
A-B-C-D             K-L-M-N-O-R-S-T... master
       \           /
        E-F-G-H-I-J Branch 1

I think if I can get those done without snapping the universe in half I'll be able to work the rest out from there.

John U
  • 2,886
  • 3
  • 27
  • 39
  • 1
    But what is it that you want to do? – Tim Mar 16 '16 at 12:19
  • The way your diagram shows it, the only commits that are *not* merged into the master branch are P and Q. And your first diagram shows those two as "failed idea." So yes, as @TimCastelijns said—what do you want to do? – Wildcard Mar 16 '16 at 12:23
  • I guess the two things I want to achieve (and understand) are: **merge** everything from onwards back into master and then/also **branch** a few selected commits such as

    and without simultaneously jamming my foot in my mouth and shooting my toes off.

    – John U Mar 16 '16 at 12:38
  • No, PQ was a dead-end change that was reverted in (sorry, chaos panic & disorder have ruined the project) - I've updated the question to (try to) reflect that. – John U Mar 16 '16 at 12:45

1 Answers1

2

For clarification, I named the branch exciting

Step 1

From

A-B-C-D  master
       \
        E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T... exciting

to

A-B-C-D             K-L-M-N-O-P-Q-R-S-T... master
       \           /
        E-F-G-H-I-J exciting

you could do

$ git checkout master
$ git cherry-pick K
$ git cherry-pick L
$ git cherry-pick M
$ git cherry-pick N
$ git cherry-pick O
$ git cherry-pick P
$ git cherry-pick Q
$ git cherry-pick R
$ git cherry-pick S
$ git cherry-pick T

This looks quite ugly all the separate cherry-picks, there is probably a cleaner way but I don't know it from the top of my head.

After cherry-picking everything you want to master do

$ git checkout exciting
$ git reset --hard HEAD^^^^^^^^^^  # Reset back 10 commits, HEAD~10 would also work

Step 2

From

A-B-C-D             K-L-M-N-O-P-Q-R-S-T... master
       \           /
        E-F-G-H-I-J exciting

to

                              P-Q  Branch 2
                             /
A-B-C-D             K-L-M-N-O-R-S-T... master
       \           /
        E-F-G-H-I-J exciting

you could do

$ git checkout -b branch2 Q  # make new branch2 at commit Q
$ git checkout master
$ git rebase HEAD~8 --interactive # 8 may not be the correct number. Pick big enough number so that P and Q are included

In the editor that pops up, remove both the lines that represent commit P and Q to remove them from the history of master. They still live in branch2

To push this to remote you will have to rewrite most of the history, requiring a git push --force for that to work. Make sure the repo state you have locally is what you need on the remote, and that the remote contains no commits that you don't have locally. Else they will be lost.

Tim
  • 41,901
  • 18
  • 127
  • 145
  • I may be missing something but we're not starting from diagram 2, we're starting from diagram 1 in my post and want to end up with the last 2... has one of us misinterpreted? – John U Mar 16 '16 at 13:58
  • @JohnU my bad I think.. so currently you have just the master branch and the other branch with the exciting stuff? – Tim Mar 16 '16 at 14:00
  • Yes, the current structure of the tree is as per my 1st diagram. Re-reading the post I realise it could be taken either way. – John U Mar 16 '16 at 14:29
  • @JohnU alright forget everything I wrote here earlier, Ill edit it – Tim Mar 16 '16 at 14:34
  • Excellent, that looks like it makes sense - I'm off to make extra double backups of everything and give it a try! – John U Mar 16 '16 at 15:13
  • I'm currently hitting issues as our git repo includes binaries (again, _don't start from here_) which is a separate headache altogether. – John U Mar 17 '16 at 13:59
  • @JohnU alright. Good luck trying to clean it up. I'll hear from you when I do – Tim Mar 17 '16 at 14:02