Editing a patched file - version-control

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.

Related

svn: merging changes from a branch to a working copy without updating trunk

My development team recently doubled in size from one (myself) to two. As the sole developer, I was maintaining the trunk as the stable version of our software. I'd make changes in my working copy, test, and only push to trunk once I was sure it was stable.
With the new team member we are trying to come up with the best flow for co-developing the codebase. We have decided that trunk will stay stable; changes are pushed there only after code review and thorough testing. The teammate will create feature branches for features he works on; when he requests a code review, I will do it and then once approved, he will merge the branch into trunk and delete the branch.
We are both using eclipse and the subclipse plugin to manage our working copies.
The problem is that while I can view differences between my working copy and his branch (Team -> Compare To -> Branch), I do not know how to get the code from his branch to merge with my working copy. I want to be able to get his changes without losing any local changes I have made, run his code locally, and have none of this affect trunk. That seems to rule out the option in Eclipse/SVN to switch to another branch/tag/revision, since I need to have his code merged with mine (in order to make sure my working copy's code is consistent with my local database).
We've looked at the SVN Patch feature, instead of using branches perhaps he should send his changes over through a patch which I run?
So the concrete question here is: how do I merge/incorporate changes from a branch with my working copy without touching trunk? I would also be grateful to get suggestions on how we should implement our workflow in a way that takes advantage of the power of svn and eclipse in a way I am missing.
Both of you should have checkouts of trunk and any branches you're both working on. When he is ready to have his branch merged into trunk, you should:
Ensure that his branch builds successfully.
Ensure that your trunk checkout is pristine (no SVN added, modified, deleted, unversioned or ignored files).
Conduct the merge, resolving any conflicts with his help.
Perform a code review, including ensuring that trunk is stable with his changes.
Commit the merge.
Conduct the merge outside of Eclipse, using the SVN command-line. I've seen enough questions here on SO related to Eclipse and Subclipse that tells me the plugin is unreliable.
If it was me managing this workflow, I'd have two checkouts of trunk: one which is meant for merging and is always in a pristine condition, and another in which I can actively develop. That way, I wouldn't need to create a patch of my changes, then merge, then apply the patch.
Hope this helps.
The sad truth is that SVN will probably not be fit for this pattern. Branching creates a lot of pain in Subversion
Check here to get more details.
It was enough for me to update the branch from command line with 'svn up'.

SVN: Synchronize branch with trunk in Eclipse?

I have an SVN branch and a trunk. The trunk changes regularly and the branch doesn't.
Every now and then (let's say once per week) I want to update the local working copy of the branch with the latest changes of the trunk.
Ideally I would want to do this the same way as I do it with the latest version of the branch: with Eclipse : Team->Synchronize, so I can review all changes before updating.
Is this also possible with a different repository (for example : trunk) ?
If not, how do people review the changes before updating then??
I looked at Team->Merge, but this seems to update the changes directly to my working copy, without the possibility to review the changes first (the Preview-function is confusing, I think, and doesn't provide the nice side-by-side view of changes/conflicts that Synchronize has).
The right way to do this is with Merge. Subclipse includes a merge client that makes this easy to do. You are right that it does not give you a true preview, but the way it works is better from a Subversion perspective. The Merge Results view UI is basically the same as the Synchronize view. It lets you easily examine every change that the merge made in your working copy and the Eclipse compare editor that it opens makes it very easy to take out any parts of the change that you do not want in your code before you commit.
The problem with trying to do this from the Synchronize view is that you are then doing the merge yourself using code editors and Subversion has no awareness of what is merged. If you let Subversion first do the merge, then it can update all of its metadata properly and it is perfectly fine for you to then fixup the code to be the way you want it before you commit the results of the merge.
I'd checkout both branch and trunk as a separate eclipse projects into workspace. Then use some merging tool, for example meld to merge changes between them. After merge you can refresh branch in Eclipse and synchronize it with svn repository - now you can review all changes. (it's how I do it, since I do not believe svn eclipse plugin ;))
I agree that it is not really intuitive by design, but Mark is right, you "synchronize" your changes when committing them back to the trunk:
first make sure your local branch is completely synchronized with your repository branch (no changes)
Team -> Merge... your local copy of the branch with the repository trunk
you now have a local version of that merge
you can locally edit this version, make sure tests are working and there are no compiler errors
finally you synchronize your local merged branch version with the repository branch and commit all changes that have been made
besides, the same way you'll merge your branch back into the repository trunk
make sure all changes of your branch are committed to the repository branch
switch to the trunk Team -> Switch...
merge your trunk with your branch Team -> Merge... (Tab 'Reintegrate')
you now have a local version of the merge, you may edit the changes and review them, make sure that you have a working version now
synchronize your local trunk (merged version) with the repository trunk
commit all changes that you want to appear in the trunk
i recommend to commit all changes that you've made locally to your merge, since you've tested them locally. if you commit just a few changes, make sure the repository version is still working then with missing changes

How to handle merges with hgsubversion?

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.

What are some best practices for maintaining multiple versions of a project?

I've got a project where we're rolling out v1, and beginning work on v2. I'm afraid that we're going to see bug fixes and minor feature changes to v1 over the next few months, some of which we're going to need to roll into v2, some of which we're going to need to keep separate. (We need to maintain v1's major feature set, but fix any bugs as they're found.)
We're using SVN at the moment. I've considered switching to Git, but I'm a little reluctant to change tools. Aside from that possibility, what are some general strategies and best practices to make managing this situation as easy as possible?
Update: everyone's suggesting I branch the code in Subversion. That was so obvious to me that I thought it was implied by the "we're using SVN" statement. Apparently not. :) I am going to look at Mercurial and Bazaar as well as Git, though. Anything else?
Using SVN, the best you can do is branch your repository:
In the trunk, keep the latest version - not necessarily a stable one.
Whenever you need to separate a new major version from there, branch to, say, 2.0 and you can keep both latest version and stable versions in the same repo.
If you find changes in branch 2.0 that need to be merged into the trunk, you can do it seamlessly.
we are using TFS, but for your specific problem, the solution will be quite similar: create a new branch.
[Depending the application environment you are using, apparently not Microsoft]
We have benefited from TFS because:
You can do merges between branches [baseless merges]
You can work with workitems, [for bugtracking]
With sharepoint support, you may have documents, test scripts can live together happily at one portal.
With powershell scripts, you can have nightly automerges
For different versions the best practice is to store the named versions in the "tags" subfolder. (SVN docs recommend you have a trunk, tags and branches folder for each project).
Whenever you release a version, copy the trunk to the tags folder and give it a name. That version can live on and bug fixes can be made to it separately and merged back and forth.
SVN docs on repository layout:
http://svnbook.red-bean.com/en/1.2/svn.branchmerge.maint.html
You should use SVN to tag the v1 code. That way you can create a separate branch of the code to support fixes to that code base.
Have you considered branching your trunk and doing v2 development on the second branch once the v1 branch is frozen? If you fix bugs on the v2 branch that affect v1 and you'd like to release an update/patch for v1, just merge those specific changes back to the v1 branch from the v2 branch.
All of that is perfectly doable in SVN, but it is much easier to do branch management with a tool such as Mercurial or Git. I can't tell you if it's definitely worth switching or not since I don't know your company or codebase, but it's something to consider if you can forsee this situation arising repeatedly in the future as you release more versions.
Using git you can use the following approach:
Your git repository could have the following branches. Each hotfix branch contains a feature release that must be maintained.
master - version: 3.0.0 (latest release)
\
dev - version: 4.0.0 (next release)
|\
| hotfix-1.x - version: 1.0.1 (current hotfix 1.x)
\
| hotfix-2.x - version: 2.0.1 (current hotfix 2.x)
\
hotfix-3.x - version: 3.0.1 (current hotfix 3.x)
Fixes:
Bugfixes are made in hotfix-1.x and merged "up" into hotfix-2.x and from there to hotfix-3.x.
hotfix-1.x -> hotfix-2.x -> hotfix-3.x ...
Bugfixes can also be backported using git the cherry-pick command from hotfix-3.x to hotfix-1.x (if needed). With the cherry-pick command it is possible to pick one single commit and apply it in a different branch. Git will also detect moved and renamed files and still apply the change correctly.
You can also add release branches in parallel to your hotfix branches in order to prepare the releases in those branches (omitted for this example). This is useful when you don't want to block the hotfix branches for new commits. Please checkout gitflow if you want to know more about the details of hotfix and release branches.
Feature Releases:
New features are based upon the dev branch and merged back into the dev branch once completed. A new hotfix branch is created for each new feature release.
Steps:
Merge changes from current hotfix branch into dev
Merge feature branches back into dev
Create new hotfix branch from dev
Release from new hotfix branch
Merge back into master
Notes:
I think the master branch is no longer very important when you decide to keep your hotfix branches. I belive the common gitflow scheme works that way that you trash your hotfix branches and release branches once you are finished. Your releases should all be tagged and are therefore accessible.

Practical way to commit changes in source control to multiple branches

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.