A common scenario when using source control is to have a development branch along with versioned release branches. We use CVS, with HEAD as the development branch, and a branch named e.g. release-6-2 for the current release of a product.
Development of new features go into the development branch only, but bug fixes sometimes have to be checked into both the development branch and the current release branch. This can get quite tedious at times, so I am looking for practical ways to accomplish this.
When a file to be commited is in synch on the two branches, I am in particular looking for a quick "commit to these branches" solution.
(We use CVS as our source control system, so any CVS-specific answers are nice. However, it is also interesting to see whether other source control systems can offer a better way.
On the client side we use Eclipse, so Eclipse solutions are good. But if you have a non-Eclipse solution, that is fine too.)
Apply your fix to the oldest release branch required. Then merge the change to the next release branch and so on until you merge from the last release branch to the HEAD.
Say the oldest version of your product is 1.0 and you also have 1.1 and 1.5 releases. New features for the next release are being added to the HEAD. If a bug is found in 1.0, you apply the fix to the 1.0 branch. Merge from 1.0 to the 1.1 branch. Merge from 1.1 to the 1.5 branch, and finally merge from the 1.5 branch to the HEAD.
Merging from branch to branch is better than applying the fix manually to each branch.
With CVS you have to mannually keep track of what versions are merged, so that you do not include the same revisions when you do your next merge.
If you change to use Subversion, merging from branch to branch is easier. Eclipse's subversion tool will keep track of what revisions you have previously merged, greatly simplifying the task of doing repeated merges between two branches.
Changing to Subversion from CVS is easy(ish). You won't be the first to have made such a move.
Like awalshe said, it's better to merge between branches. To cherry-pick a merge, the method described in Pragmatic Version Control using CVS is very good:
In the branch - tag (PRE_FOO) before the change, make the changes and commit, tag after the change (POST_FOO). Then, in trunk, merge using the tags:
cvs up -j PRE_FOO -j POST_FOO
Merging between branches is much easier and safer in SVN, and it's trivial to convert your entire CVS history to SVN - see cvs2svn. You should use either SVN 1.5, or - with earlier SVN versions - svnmerge.
Related
I have a general workflow question: I get a patch from a co-worker and would like to further edit one of the affected files. How do I isolate my changes? I'd like to be able to keep my changes when re-patching in the latest changes from my co-worker.
Feel free to point out special features of your favorite version control system.
You can use Git as your version control system and create different branches for you and your co-worker. After that you can work on your own branches with out interfering with each other. And you can always isolate your changes/patch in a commit.
When you want to "re-patch" the latest version from your co-worker, you can either use git merge to merge your co-worker's updates into your branch or use git rebase to redirect the branching point of your branch to a newer version. Git can automatically merge different versions unless there is an conflict.
We're using TortoiseSVN and TeamCity, and the project have now a trunk and a branch (trunk and release201301). Sometimes, not often, the developers forget to merge our changes in the realese201301 down to trunk - which of course can cause all sort of problems at some stage.
Anyone knows a tool or technique for validating when a Commit has been merged from a (or many) branch(es) to some other branch?
In recent TortoiseSVN versions, each merge step your team perform is registered into a special property called svn:mergeinfo. You just need to check if the revisions from the branch that should be merged are registered into this property (you can use SVN Log, SVN Revision Graph or other features, at your discretion).
Our dev team works inside existing projects, and deploys on completely separate environments. The work we do is not never expected to be merged back into theirs, but we are required to stay in line with them. They use the traditional trunk-branch (but not really tags) setup. A branch is created for a production release, and then development continues on it as they release.
The way our team does it, we copy their release branches to our own trunk (initially), which itself contains trunk/branches/tags. During development we are on trunk, and tagging for production releases. When we update from their latest release, its often impossible to do a straight merge from that branch to our trunk. It seems much cleaner and trouble-free to start with their branch, merge in our work, and eventually rename it to trunk.
All of a sudden I feel like a subversion dummy text generator...
Given the constraint that we can't change the other team's workflow, is there a better flow for us? Let me know if I'm missing something in the explanation too.
thanks.
Two main principles:
Vendor branches
Merge often
Due to ignorance of rule 2 you get "Merge hell" as expected
For more reasonable workflow (read about Vendor branches in Net, it has a lot of information) you can
Not just copy upstream branch to your trunk, but create vendor-branch (branch) in your repo, link it with svn:externals to source branch (without fixing source-revision in URL, link to moveable HEAD)
Copy branch to (empty) trunk
Monitor commits into upstream repo (SVNMonitor, CommitMonitor) and on every commit to upstream branch merge your vendor-branch with your trunk (svn 1.6-1.7 will be better than older versions)
After finishing upstream brach and starting new you can or edit externals definition in old branch (for next branch URL) or delete branch completely and start new (deleting all from your trunk not needed, only merge from new branch content)
Our team uses Eclipse to develop a software product, and recently we switched to Subversion to do our source control/version management. At first our team was still committing directly to the trunk as we were new to Subversion's way of source control and things needed to be drawn out still.
At some point I made my first real branch from the trunk to do development for a specific project within our product. Suppose the branch is called DEV_PROJ.
Later as our team knew better how to work with Subversion from Eclipse, I put the team on our first real development branch, not for a specific sub-project but to keep track of different versions. Suppose the branch is called DEV_VERS. Now we are working on that branch and no longer committing directly to the trunk. DEV_VERS was branched from the latest version of the trunk and there have been no commits to the trunk since then.
In between the two branches about two/three months passed and there have been a lot of changes to the trunk before I made the version branch. Now the time has come for me to merge the changes from DEV_PROJ to the DEV_VERS branch to incorporate the project in our new version branch.
What I did first was merge the latest version of the trunk to my DEV_PROJ branch (forward merge?), thinking that would minimize the difference between the two branches while keeping the changes specific to the project.
What I'm trying now and what I'm having problems with is merging the DEV_PROJ to the DEV_VERS branch. Right-click, Team/Merge my DEV_VERS project to start the merge, there are three tabs to choose from: URL, 2 URLs, Reintegrate. As far as I know this is not a reintegration merge, that would be from branch toward the trunk and not between branches that are not directly related. I also don't need to merge two branches towards my branch so I skip 2 URLs tab.
So I choose the first one, URL. As the source I take my project from the DEV_PROJ branch, Revisions: Start from copy, Depth: Working Copy. In a second try, I also chose to Ignore Ancestry. Both tries I push the Preview button to get an overview of what files are target for merging.
What I see is that there are a lot of files that are candidate for merging, that have not been changed in my DEV_PROJ branch. So the (subversion) merging process sees a lot more merging candidates than I had expected. The files I added to the DEV_PROJ branch appear as "Added", but a whole lot of files that I know I didn't change in that branch appear as "Modified" or "Tree Conflict" in the merge overview.
My questions:
Is this the right way to merge between branches? If not can it be done directly using the merge menu (URL, 2URLs, Reintegrate)?
Is my first step (forward merge trunk to DEV_PROJ) the reason why there are merge candidates that were not supposed to be there?
If there is no direct way of merging these branches correctly, then I only see one option. That is merge the DEV_PROJ to the trunk (reintegrate), and then merge the trunk towards the DEV_VERS branch (forward merge). Would this be the right way to do this? If so, is it the only way to do this?
Eclipse: Helios Service Release 2, build: 20110218-0911
SVN server: 1.6.15
Eclipse SVN plugin: SVNKit 1.3.2 (2.2.2.I20100512-1900) // SVN Connector (2.2.2.I20100512-1900) // SVN Team Provider (0.7.9.I20100512-1900)
If I understand your question correctly, this is the state of your project:
_________________ B DEV_PROJ
/
A /
---------------------------------- trunk
C \
\_____________ D DEV_VERS
And you want all changes from A -> B in your DEV_VERS branch.
If so, what I would do is the following (the following is the command line equivalent, but it should be easy to find the Eclipse SVN GUI equivalent):
Find the revision of A:
svn log --stop-on-copy URL_OF_DEV_PROJ
The earliest commit revision number is the revision number of point A
Find the revision of B:
Assuming you want to merge all changes in the DEV_PROJ branch, the value of B is simply HEAD
Checkout DEV_VERS:
svn co URL_OF_DEV_VERS
Inside the directory of the checked out code from step 3, merge the changes from A to B as follows:
svn merge -r<RevisionOfA>:HEAD URL_OF_DEV_PROJ .
In short, what you're doing is taking the difference between A and B and merging it to DEV_VERS
I am trying to contribute to a project that uses Subversion. I used Mercurial and its hgsubversion extension to clone the repo. My work takes place on a feature branch.
How do I keep the feature branch up to date with stuff that happens on the default branch (hg speak) aka the trunk (svn speak)?
So I used hg up feature to update to the feature branch, then hg pull which gave me changesets on the default branch. So I did hg merge default, the committed the merge, then tried hg push to send my changesets to Subversion. And Mercurial said: "Sorry, can't find svn parent of a merge revision."
I have finally figured out how to get my repository un-wedged after an event like that described in the question, so that I can continue work without having to re-clone the parent repository (which is, obviously, a quite slow operation when you are pulling from Subversion!). If the "tip" of Subversion outruns you so that you cannot push any more, just make sure that you have the built-in "rebase" extension activated in your Mercurial through a $HOME/.hgrc line like this:
[extensions]
rebase =
And then you should be able to run this command when your repository gets wedged:
$ hg rebase --svn
If I understand this correctly, it dissolves your current branch that has taken you away from Subversion HEAD, and rebuilds it atop the branch "tip" in Mercurial that corresponds to the HEAD in Subversion. From there, you can keep working and successfully do pushes again. It has always worked for me so far; let me know if you run into any problems!
Mercurial as a few different branching modes: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
The one you're describing is 'named branches', which is the most popular when you're working with a repo that's accessed only via mercurial (or hg-git).
However, when you're using hg-subversion so that you're pushing changes to/from subversion, which only nominally has branches, you're better off keeping all of your mercurial changes in the 'default' named branch, and using the 'clones and branches' pattern (which I prefer anyway).
Specifically, that message Sorry, can't find svn parent of a merge revision. isn't a descendant of a revision that has a direct match in subversion.
Were I you, I'd reclone from svn, and then move my work into that repo's 'default' branch with the 'transplant' command (packaged extension). If you want multiple features in parallel w/ hg-subversion use separate clones (they're so cheap), as it's more in line with how subversion thinks about branches.
I needed to figure this out for myself and wrote it up here:
http://notebook.3gfp.com/2010/05/pushing-a-new-feature-from-a-mercurial-repo-into-an-svn-repo/
I haven't yet figured out how to close a branch in subversion and have the mercurial graph look correct.