Jump to content

Merging sub-sub branches


Soho

Recommended Posts

My team and I have run in to some merge problems quite a few times that doesn't fit our mental model of how branches work in Plastic. It would be great with some insight to correct our model and understand the following behavior:

Assume I have a branch A.

In branch A I create and check in a file foo.txt

Next I branch latest change set of A to a child branch "B".

I switch workspace to B and checkout foo.txt and make some changes, which I check in.

I then branch the last change set of B to "C".

I switch back to A and merge from C

In short: A branch to B - change foo.txt in B - branch to C - merge C to A.

Here comes the surprise for us. The merge operation from C to A finds no changes even though foo.txt changed in B before branching to C.

It is true that foo.txt hasn't changed in C since branching from B, but it certainly has changed since branching from A.

This has caused several cases of missing changes after merges for us, so if someone could enlighten us with a better understanding of the branch / merge model it would be greatly appreciated.

If merges only consider changes made directly in the source and destination branches and not in intermediate branches, what is the correct procedure to work with several layers of branching?

Link to comment
Share on other sites

Hi Soho,

You're right. That's how branches work up to 3.0.

A branch JUST contains what you changed on it.

So, if you:

- branch A from /main

- create /main/A/B

- create /main/A/B/C

and then merge from /main/A/B/C to /main, only the changes on C will be merged, not the ones in B or C

This is how "branch inheritance" works...

I used to love it but I can tell you that in 4.0 (you know the beta is available) it works as you expect... if you merge /main/A/B/C you merge the "C status", which means, the "tree" you load in "C", including all changes "inherited" from A and B even if they weren't modified on C... As you expect...

That's why 4.0 will rule the world... ;)

Link to comment
Share on other sites

Here is a scenario from today:

A developer made some changes in branch B, child of A.

He wanted to merge B with our main branch, but since B contained a lot of changes he wanted to merge from main to B first to solve any problems expecting the problem solving to cause a few change set commits before B was stable enough to be merged into main.

However the merge went bad and after a few change set commits he gave up.

We could have cherry picked the last good change set in a B to main cherry pick merge, but we still wanted a few change set iterations to stabilize the branch.

To retry the merging we "rolled back" the bad merge by sub-branching B from the last change set before the merge.

We then merged main to the new branch C and this merge went well.

We then merged C to the main branch, but this obviously created problems since we didn't expect the changes in B to be left out. Only changes that happened to have been introduced in C because of the merge from main would be merge back, which left us with a "half" merge not knowing in details what had been merged and what had been not.

We solved some missing stuff by cherry picking from the last "good" change set in B, but it ended up being a quite complicate merge operation.

I suppose that the above problem would not have existed had we instead branched main to this "repair" branch and made a cherry pick merge from the last good change set in B. Made the "repair" branch work and merged that back to main.

It was intuitive to us, that sub-branching the change, merging from main and back would logically be the same as the above, but obviously this was not the case.

Link to comment
Share on other sites

> Here is a scenario from today:

> A developer made some changes in branch B, child of A.

> He wanted to merge B with our main branch, but since B

> contained a lot of changes he wanted to merge from main

> to B first to solve any problems expecting the problem

> solving to cause a few change set commits before B was

> stable enough to be merged into main.

Ok, wait, but this is a perfectly supported scenario. It is normally called a

"rebase" in Plastic jargon.

Question: from which release is "B" starting from? (Are you labelling releases

on /main regularly?)

> However the merge went bad and after a few change set commits he gave up.

Uhm... but it means he screwed up branch "B", doesn't it?

> We could have cherry picked the last good change set in a B

> to main cherry pick merge, but we still wanted a few change

> set iterations to stabilize the branch.

This (in 3.0, 4.0, git and in everything) won't work as you expect... cherry

picking the "last changeset" will only get "the changes done in the last changeset",

not all the changes on the branch... so you'd be loosing changes, wouldn't you?

> To retry the merging we "rolled back" the bad merge by sub-branching

> B from the last change set before the merge.

Ok

> We then merged main to the new branch C and this merge went well.

Uhm... isn't this exactly the same thing he tried first??

> We then merged C to the main branch, but this obviously

> created problems since we didn't expect the changes in

> B to be left out. Only changes that happened to have been

> introduced in C because of the merge from main would be

> merge back, which left us with a "half" merge not knowing

> in details what had been merged and what had been not.

Yes, that's how branching works in 3.0. It is very strong but you've to know

how it works... that's why maybe a little bit of online training is worth the prize... ;)

> We solved some missing stuff by cherry picking from the last

> "good" change set in B, but it ended up being a quite complicate merge operation.

> I suppose that the above problem would not have existed had we

> instead branched main to this "repair" branch and made a cherry

> pick merge from the last good change set in B. Made the "repair"

> branch work and merged that back to main.

> It was intuitive to us, that sub-branching the change, merging

> from main and back would logically be the same as the above,

> but obviously this was not the case.

We're changing this behavior in 4.0, but yes, as you point the "issue" is that

right now the changes in the intermediate branch are left out. So, it would be

"better" to merge B first and then C.

IT all depends on the way you're using branches, of course. If C is just a "bug fix" then

it can probably be applied to A, but it all depends on whether it starts from a point or

a different one already having changes C will depend on.

pablo

Link to comment
Share on other sites

>

> However the merge went bad and after a few change set commits he gave up.

Uhm... but it means he screwed up branch "B"' date=' doesn't it?

[/quote']

Yes, this was a repair mission. What we wanted to do was to roll back the bad check-ins he had done. Instead of doing a subtractive merge (would that be the correct procedure anyway?) we branched the change set we wanted to roll back to. This made sense because we thought the "B" branch changes would be conserved when we later merged the repair branch "C" to "A" (ancestor of "B").

When you have not adopted the task-per-branch workflow completely, then Plastic 3 can surprise you now and then.

Link to comment
Share on other sites

Hi,

Yes, the best tool to undo the entire situation would have been "cset deletion" but you'll have to wait for 4.0 :P

What you did (subbranching) looks correct to me to "undo the mess" but then you've to be aware of how merging works.

As I pointed on a comment here (http://stackoverflow.com/questions/7097642/merging-changes-in-intermediate-branches-with-dvcs) as shocking as it might sound, we only have a few issues with this approach in 5 years and with really huge customers. I admit I'm more comfortable with the "merge status" (use what you're loading (like browse repository on this branch) as source instead of the "branch content") now, but we've been using "merge branch content" for years seamlessly.

pablo

Link to comment
Share on other sites

Could you clarify the best way to perform this kind of merge?

Given the scenario:

Branch B branched from A change set A1

B contains change sets B1 B2 B3 B4 B5

B4 and B5 are bad change sets.

After B branched from A1 A has the change set A2 A3 added.

What would be the correct procedure to create a new change set: A4 on A containing a merge between B1 - B3 and A?

In a similar scenario, lets say we branch of C at B3 and add change set C2 C3.

What would be the correct procedure to get B1 - B3 plus all of C merged with A?

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...