Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an inverse to Git's octopus merge?

Tags:

git

branch

Git has a much-touted(?) octopus-merge capability that can merge many heads into one.

But is there something that would do just the opposite, make several simultaneous branches out of one node?

Let's assume that I have a bunch of code for a project, and I just started using Git. Some of the features are complete in that project, others are still work-in-progress. What I'd want is to get those unfinished features moved into their own respective and separate branch, and have the master as 'complete' as possible, with no unfinished code.

Now, I could of course do all of this in single steps: Create a "unfinished feature #1" branch, and delete the files from the master that are specific to that feature. Then I'd re-branch the master into "unfinished feature #2" and again remove feature #2 specific files from the master, but also from the first branch. And thus the workload increases for each split I do.

Is there something that would help me in such a scenario?

like image 964
Henrik Paul Avatar asked Dec 17 '22 09:12

Henrik Paul


2 Answers

Side note: the octopus merge and the octopus branchpoint scenarios are very different. Please remember that pointers in DAG (directed acyclic graph) of commits point from child (newer commit) to parent or parents. So in the case of octopus merge you have commit (commit object) which has more than two parents; in the case of "octopus branchpoint" you simply have a few commits pointing to the same commit as its parent.

octopus merge:

1 <---- M
2 <----/ |
3 <------|

octopus branchpoint:

P <----- 1
^-------- 2
^-------- 3

So I think naming of this question is simply wrong


The answer

Now, if what you want to do is to split modifications in your working area between different branches, to put each feature in separate topic branch, you can make use of explicit staging area (aka index) in Git.

Let's assume that you modified two files, 'a' and 'b', and you want modification to file 'a' to go to branch 'A', and modification in file 'b' to go to branch 'B'. Let's assume that the branch you are currently on, the branching point you want to be base of many branches you want to create, is named 'master'.

First, lets create branch 'A'

$ git checkout -b A master

Git replies with:

M       a
M       b
Switched to a new branch "A"

The "M" means that the files 'a' and 'b' are modified with respect to the point you based branch 'A' on (the 'master' branch). (Below, I will simply put git response below commandline invocation, instead of separately noting what's a reply.)

Let us add contents of file 'a' to the staging area (index).

$ git add a

Note that if you want to add only some subset of changes in file 'a' to branch 'A', you could use "git add --interactive" (abbreviated as "-i") or "git gui" to do per-hunk addition of changes to the staging area and other such manipulations.

Now we commit changes to branch 'A'

$ git commit
Created commit 35d0061: Commit description...
 1 files changed, 1 insertions(+), 0 deletions(-)

Note that we didn't use the '-a' option to git-commit!

By the way, if you want to test changes before comitting from staging area, you can use "git stash save --keep-index" to get working area to the state you are to commit using "git commit", test changes, then go back to previous state using "git stash pop --index" (or "git stash pop"; I don't remember which one do you need here).

Now we create the other branch, branch 'B', based on branch 'master'

$ git checkout -b B master
M       b
Switched to a new branch "B"

You can easily see that the changes you have left for branch 'B' (the changes you didn't commit to branch 'A') goes to newly created branch 'B'. No need to delete files, or remove changes. No need to know what is in other branches. Everything is automatic.
Once again, add contents of file 'b' to staging area (index), and commit on branch 'B':

$ git add B
$ git commit

You can repeat this as often as necessary, and it doesn't get harder with the new branch.

HTH

like image 98
4 revs, 2 users 83% Avatar answered Dec 29 '22 05:12

4 revs, 2 users 83%


Since you just started using Git, it would be easier to start again and only commit your 'complete' code to the Master branch. Then checkout a new branch from the master for a feature and commit that 'unfinished' feature code on its own branch. Repeat for each feature branch.

You have to partition the code into features and 'complete' anyway, so use that to set up your repository.

like image 37
Paul Avatar answered Dec 29 '22 05:12

Paul