What is the best way to merge specific changes in several branches and trunk? - eclipse

I used SVN/CVS for a long time just as a place where my code stored is. But now I came to a point where I need a "best way to do".
We have several branches.
For Example:
Release1 (shipped),
Release2 (not finished, contains new features),
Fix1 (contains bug fixes for Release1 and will be shipped after customer tests),
Fix2/trunk (The trunk is our current development state with Fix2).
And now we come to my problem.
I cannot say if Release 2 is shipped before Fix1 or Fix2 and I have now a Hotfix for Release1. Just a few files, but it was urgent.
What is now the best way to get the changes in all branches?
Auto merge will also merge differences that are branch specific. Is the best way to merge it by hand?
There has to be a way like: I mark my change with ID "abc" and say merge only changes of abc in all branches.
Btw. I am using Eclipse with Subversive. Maybe a tool outside eclipse will be better!?

I use Subclipse plugin for Eclipse. You can probably do this with svn command line also. If your fix is isolated to a single revision number then you can merge just that revision to the trunk(or any other branch).
branch1 (revision 103) -hotfix
trunk (revision 100)
Using Subclipse, you can right click the file then choose "Team"->"Merge." Select either "Merge a range of revision" or "Merge two different trees" option then provide the source url and revision to merge to the target tree.
From command line... given that your current working directory is the trunk:
svn merge -r 103:103 http://svn/branches/branch1
You probably can't merge to multiple branches and that's probably better because you want to be careful with the merge process.

Related

Timestamp-based automatic merge in Mercurial

I want to use Mercurial for a email-based sync system (see this question).
I have played around with sending bundles back and forth ad applying them to the repositories to be synced. But I often get merge conflicts which I have to resolve manually.
But they could be resolved easily automatically: I just want the newer file to replace the older one.
Is it possible to set up a merge-tool in Mercurial that does exactly that: When I hg pull a bundle it updates to the file with the newer time stamp?
When you pull or unbundle new changesets in repository must not intersect with done in parallel (you'll get new head only) - I can't see why you can have merge on pull (uncommited local changes? Commit before pull!)
If your merge-conflicts appear on merge heads (when you merge local head into tip after pull) and you prefer to have tip version of conflicted files and abandon local changes you can use merge with --tool=internal:local option
If you prefer dummy-merge, i.e abandon all local changes from all files, you can use this trick from Mercurial wiki

How to minimize conflicts in merging with the CVS Eclipse plugin

I am trying to execute the above merge scenario using Eclipse and the CVS plugin. It works a lot like this Eclipse branching article.
The problem I am encountering is what I consider "incorrect conflicts".
Shouldn't M2 be free of conflicts?
At the point after the commit tagged PM1, the two branches are the same. Some work is done on HEAD (as WD2) and committed to HEAD. A tag W2 is created. Now I want those changes in p1test.
The branch in the Eclipse project is set to p1test and a merge is done by selecting HEAD as the "Branch or version to be merged (end tag)", and W1 as "Common base version (start tag)". Since there have been no changes in p1test, I would have expected no conflicts in M2. But that's not what I see. The WD2 work shows as conflicts. That doesn't seem right since those files haven't been touched in the p1test branch.
Am I doing this right?
I guess you did it right as your diagram comes from the original documentation.
Do you use CVS keywords ($Revision$, $Author$, $Date$, ...) in your text files ? Do conflicts concern lines with such keywords ?
I suggest you to test the merge operation with CVS command line itself:
Do a fresh checkout of p1test branch
Invoke cvs update -kk -j W1 -j W2
You should have no conflict and be able to commit the resulting merge on p1test branch
The -kk option is required to avoid conflicts on keywords.

How can I do a partial update (i.e., get isolated changesets) from subversion with subclipse?

If a file is committed several times with various changes, how can I fetch one change at a time, i.e., one changeset at a time?
I use eclipse, subversion, and subclipse, and I can't change the former two for the time being (or the MS platform..).
In my Team/Synchronization view in eclipse (using subclipse), choosing the changeset model, a file seems to be listed only in the latest relevant changeset even if all changesets are listed. So an earlier changeset doesn't necessarily show the full set of files in the original commit, nor the original diff for a file in a commit.
Update: I'm thinking about using changesets for simplified code review, so I'd like the partial update represented for all the files commited in one changeset. It's easy to get diffs and specific revisions for specific files in eclipse, but I'd like to step through all the changes in one specific commit/ changeset in a practical manner.
As I'm sure you know, svn up will by default grab the latest revision of the file.
However, you can use the -r parameter to svn up to grab a particular revision of a file. So if you know a file was committed in revisions 5, 7, and 9, you could do this:
svn up -r5 myfile
svn up -r7 myfile
svn up -r9 myfile
I believe (but I don't have an installation of it in front of me) that Subclipse has a similar option, labeled something like "Update to Revision..."
Subversion does not support atomic changesets.
(Note: If anyone can prove me wrong, I'll happily switch accepted answer.)
I've compared Git and Subversion using TortoiseGit and TortoiseSVN (and looked at what is possible on the command line).
With both Svn and Git I can update to a certain revision, or see and update to different versions of only one file at a time.
With both Tortoise clients can I see individual commits (revisions) from the repository and look at changes between a revision and the previous revision. (Note that I can't seem to do this in Eclipse, ref the question.)
Only with Git, however, can I update to or cherry-pick an isolated commit. The closest I've seen to this functionality in Subversion is to update to head and then revert a certain revision with a "subtractive merge"...
Test setup: make a project, check out or clone the project, make 2 separate commits to repository from elsewhere, including at least one file that is modified in both commits.
Then, with Git: fetch remote changes.
Then, with both Git and Subversion: look at the log.

Eclipse Merge Branch into Trunk

I am trying to merge my development branch back into the trunk of my repo. Steps I took:
Switch to trunk
check that it is up to date, resolve any conflicts
Go to Team->Merge
Select URL : development branch
Start Revision: Revision when branch was created
End Revision: HEAD
OK
This should do the magic - it opens up the syncronize view which is fine, shows me all the conflicts, but there the problem happens:
In the compare editor I see two files:
Local File | Remote File (306)
This is really strange, the revision number of the remote file is actually the one of the file in the working copy (trunk) and so is the content. The local file has the content of the file in the branch.
Now the arrow shows correctly that I am merging from left to right (branch to trunk). This also happens when I click ok.
BUT I can only move changes from right to left!!! That's not what I want - I do not want to overwrite the changes in the branches with the old content of the trunk. I want to move the content from left (branch) to right (trunk). But I can't even write in the right file.
I do not know why it writes remote file there?? It's clearly showing the working copy file in the remote file window, and the file from the branch (for merging) is shown in local file.
Some bug in Subversive?
Thx,
Martin
Merges are never been easy with subversive (as mentioned in this old SO question), so may be doing the merge externally (or with subclipse) would be easier here.
If your client and repository are both at least in SVN1.5, Subversive new merge capabilities are better, but still dangerous as illustrated by this thread.
Since Subversive has been modified for SVN 1.5 the whole merge behavior has changed. One thing I really liked is the ability to choose what changes I wanted, apply that to my working copy and then commit to trunk.
Subversive now no longer does that but forces all changes onto your working copy and then you choose what to put in the trunk.
This is not only undesirable behavior but it's also dangerous (if you ignore the possibility of a revert anyway). I prefer to commit things I know work. We have a release branch which gets changes which may or may not need to be migrated to the trunk.
Well this seemed mysterious at first, now I shall provide a decent stab at updating this answer for everyone. This regards merging using the SVN Subversive client for Eclipse:
You are doing your merge correctly, starting in Trunk and then pointing to your file under your local Branch. Your files open up in the "Text Compare" window under the Team Synchronizing tab. If you do not see conflicts over in the left hand navigation column, then your merge has just happened. Yes, this is confusing and non-intuitive.
What the Text Compare window offers you is the ability to undo your change (or any others that may have gotten into your merged file unawares) before you commit it. Remember that you are pulling in the file from Branch, so the idea is that the Branch file is in Trunk but in a kind of virtual limbo until finally committed, and changing or undoing unwanted changes here references the file in Branch (obviously). That is why you only have a one-way pipe (Trunk to Branch) to overwrite those changed merged into Trunk via your working copy. Your merge has taken place, but it's not quite official yet.
If all looks as it should, right click the file in the navigator window (left pane in my Eclipse Helios install) and choose Accept from the drop-down. Then click back over to your main code-viewing tab (in my installation it's PHP but it could be whatever you are using) and then commit the file to Trunk.
If you want to test this, do a view of the file "as is" in Trunk before committing and you should see your changes reflected there if you have done your merge correctly. This appears to be the way it is working for me on an OSX Snow Leopard Macbook Pro. Not sure if it's the same for Windows or Linux folks. I assume it's essentially the same/similar process.
it's easy
check out trunk with check out as... give a different project name.
Now you have both locally as working copy, trunk you wanna commit to and the branch you are working on and whose changes you have comitted to the repository.
Now rightclick the trunk project (and I mean the project, not single files) - merge - select the branch project (again, PROJECT)
accept all changes to local copy
commit what you need to trunk as used to
all fine, delete trunk again and keep working on the branch
especially with branches this seems super easy and worked like a charm for me

Can someone explain the perforce integration options?

Specifically:
Why do I need to explicitly enable "Enable baseless merges" all the time? I am integrating from my branch to the trunk.
What does "Enable integrate over
deleted targets" mean? Shouldn't it
do this by default? If the file
doesn't exist, and you integrate to
that branch with the file, it should
create the file, right??
What does "Do not get latest revision
of selected files" have to do with
integrating? I should be choosing a
source revision, and a target (to
create a new target revision).
What does "Disregard indirect
integration history" mean? I've never used it, since it sounds scary.
I would be grateful to know, as I am a little unsure of what options to enable when I am trying to do various integration tasks from our trunk to various branches or vice versa. (I am not the buildmaster, but hey, I want to know what he knows).
Why do I need to explicitly enable
"Enable baseless merges" all the time?
I am integrating from my branch to the
trunk.
Can't help you here. Something is not right.
What does "Enable integrate over
deleted targets" mean?
If the target file has been deleted and the source file has changed, will re-branch the source file on top of the target file. Without this option, a file on the branch, that has been changed on the branch and deleted on the trunk, would not be allowed to be integrated back into the trunk.
Shouldn't it do this by default?
Not if you are integrating a file back into the trunk, which you branched from the trunk, then deleted on the trunk. Normally 'p4 integrate' avoids mixing outstanding edits with a deleted file. You have to use the advanced options to tell it how to deal with a deleted file.
If the file doesn't exist, and you
integrate to that branch with the
file, it should create the file,
right?
When integrating a file, that previously never existed (i.e., it was added to the branch), from one location to another, yes, Perforce will simply create it in the location into which you are integrating. However, if the file originally came from the trunk, was deleted on the trunk, and now you're trying to integrate it back into the trunk from the branch, you have to tell it what to do via these integration options. Here's the command line switches to which these options correspond:
Enable integrations around deleted revisions = -d
Integrate over deleted targets = -Dt
Delete target file when source is deleted = -Ds
Try to integrate changes when source is deleted and re-added = -Di
You can learn more about them in the integrate command help (type "p4 help integrate" at the command line).
What does "Do not get latest revision
of selected files" have to do with
integrating?
This tells Perforce to use the workspace revision of the target file. By default, the head revision of the target file is automatically retrieved into the workspace before integrating. Say you have made one revision to a branch file and integrated it back into the trunk. The trunk and branch now have two revisions of this file. You submit a change to the branch file so it now has 3 revisions. You sync the branch file back to revision 2. If you were to do a normal integration right now, Perforce would assume you want to integrate everything up to the head revision and would integrate revision 3 of the branch file into the trunk. If you were to select this option, it would say, "all revision(s) already integrated" because you have revision 2 in your workspace. It would be the same as attempting to integrate with the "Limit the range of the integration:" option set to "Integrate all revisions up to:" Revision 2.
What does "Disregard indirect
integration history" mean? I've never
used it, since it sounds scary.
I can't figure out, nor find any info about, what this does.
In general, to merge two files, perforce looks for a "base", the closest revision to the two files, and uses that to provide a much better diff than just directly running a diffing the two files. See Knowledge Base Article. Without knowing your perforce setup, I couldn't say what was going wrong, however, p4win has some nice graphical tools to visualize branches, you might be able to determine why perforce can't find a base for you. This is also what "Disregard indirect integration history" does: stops it from looking for the base.
For the "don't sync to head": when integrating, your "target" is the files in your local client, which you aren't specifying a revision for; instead, perforce will either sync your revision head (if you don't use "-h"), or will use the one you currently have. You can't specify an arbitrary revision because your local client only has a particular one.
"Enable integrate over deleted targets" can lead to problems if done blindly. Here's an example: Imagine you refactor your code in your next release branch, and eliminate a source file as a result - the functionality was merged into some other source files. You then fix a bug in that original source file in a maintenance branch for the previous release. If you integrate over delete by default, the dead source file comes back, but it won't be built and the bug wouldn't have been fixed. It'd better to be warned that this occurred so you could manually merge the fix into the other source files.