Merging an outdated branch with HEAD in CVS (Eclipse) - java

Basically, we have a branch (call it B, it contains some branch specific code) which needs to be merged with HEAD. The problem we're having is that the branch was created long time ago. Since then, HEAD has been updated many times with lots of new features and many bugs have been fixed. The B branch still has most of the bugs already fixed in HEAD and it lacks some features. So, what needs doing is to take some features of branch B (there are probably about 50 files that contain new functionality - I don't know exactly what these files are) while leaving the rest of HEAD intact.
Currently, the merge tool in Eclipse reports more than 1700 changes, doing automatic merge overwrites code in HEAD with that from the branch (thus, introducing back bugs that have already been fixed). Is there a better way to tackle this instead of going through all the 1700 changes and manually merging them?

If I understand your problem, you want to find out what's changed on the specific branch, and apply those changes to trunk. I think the simplest way to do this is to create a patchfile.
Start by checking out the base and tip of the branch into separate directories. You said that you have a base tag, which puts you ahead of 99% of the people who use CVS. If that's not the case, then you can do a date-based checkout. Finding the correct date will be a pain; the easiest way will be to look at the log for a file that you know wasn't changed on the branch, and track down where that branch appears in the revision history.
Second step is to create a patch file that describes all the changes made on the branch. The instructions here seem complete (I did a Google search for "create a patchile" and looked at the top results).
What you do next depends on how big the patch is, and how much the trunk has changed since the branch was cut. If you feel lucky, the easiest way is to check out the trunk and apply the patch as described in the linked document. You're likely to get at least a few failures, and you need to check each of the changes anyway to verify that it still makes sense.
The alternative is to have three windows open: Window #1 is the patchfile, which will tell you the files that changed and what changed in them. Window #2 is the file on the (tip of) the branch, so you can see what it's currently doing. Window #3 is the file on your trunk. In this approach, you copy code from #2 to #3 where it makes sense, and #1 is just used as a guide to what gets copied.
For what it's worth, while CVS is particularly painful at branching and merging, no VCS is good at merging highly-diverged branches (no matter what Joel says).

Related

How do you check if two commits differ only in code formatting

I was trying to add java checkstyle to a hugh project and got arounf 7000 errors, I figured formatting the whole project will get rid of 5000 errors.
The problem is that my team refused to review this commit (on git) since it is a hugh change. Is there a way/script to easily figure out if two commits differ only in code formatting and have no logical difference.
You could start by checking the diff with some options to reduce some differences, like
git diff --ignore-all-space --allow-indentation-change --ignore-blank-lines HEAD^
It won't ignore more complex refactorings, but it's arguable that a good chunk of style changes only affect whitespace and indentation.
Solution 1
Check out one revision into one directory, another revision into another. Apply the same formatting to both directories. Doesn't matter what particular formatting you apply, it should be just the same for both directories.
Then compare directories use a diff tool of your choice like Meld, WinMerge, Diffinity. If they show no difference, then really two revisions have no differences except of formatting.
Solution 2
The easier way would be not to compare the revisions, but just format the code: revert the commit, check out the "base line" revision, format the code, commit. Then you will be sure that there are no changes except of formatting.
One solution would be to compare the build results (i.e. compile your project and build the JAR or WAR or other artifacts). If you only change formatting, then the resulting bytecode will be equal to the previous one. So a simple bit-by-bit comparison will tell you if no functionality was broken by the formatting change.
Another solution is to just use whatever automated tests you have and run them. Although i assume by the reaction of your team, that you don't have an extensive test coverage.

Which source control can be used to get code from TFS apart from TFVC?

I merged 2 branches and there are no conflicts. I saw that there are no conflicts and immediately unchecked the auto resolution of conflicts.
I merged the branches again and still there are no conflicts.
After I opened the pending changes, I saw this. I think there should generally be a button or link for conflicts. But there is no such thing.
I have a lot of conflicting code. It is just keeping my version whenever I think there should be a conflict.
Can somebody tell me in their experience why conflicts are not shown to resolve even when there is conflicting code. Can I use another source control like GIT to perform the merge ? Is it possible?
All of your changes have already been merged in your local workspace. As you can see in the pending changes list all changes there are marked with [merge, ...].
If you want to perform the merge again, without any automatic merging you will have to first undo the pending changes. Then ensure that auto-merge is turned off, then perform the merge action again.
Given that the automatic merge succeeded, I'd expect that you still won't find any conflicts. It looks like TFVC is able to figure out all of your merges on its own based on the fact that the auto merge succeeded.
There is another possibility... If in the past you have merged with this branch and have chosen "Keep mine" then TFVC registers this choice and will keep this in mind in future merges. This can cause unexpected behaviour later if you weren't aware this was happening. The only way to undo these so-called "merge tickets" is to perform a Rollback on those previous merges. Without undoing these merge tickets you have one more option to force a merge on contents only, you'll need to perform the merge from the commandline and supply the force switch:
tf vc merge /recursive /force /noautoresolve $/Project/BranchA $/Project/BranchB

Reversing a refactor in Eclipse

I was asked to do a name change and to maintain consistency, I refactored several classes to change their names. Now, the boss has decided he's a bit nervous about all this and just wants me to forget the name change altogether. But, I've already refactored my code, although I haven't committed it to CVS. Is there any way to get Eclipse to reverse the refactoring so I don't have to just grab the last committed code? I can't find a way to get Eclipse and CVS to work together to pull back the original code with the original names.
Thanks.
Option 1:
Refactor to previous name.
Perform CVS update to get CVS to see files as not changed.
This may not be 100% perfect due to formatting differences, but it should be close.
Option 2:
Use this if you don't have other outstanding changes besides refactoring.
Right-click on the project and select Replace With -> Latest From [whatever]...

Subclipse merge issue - Dry run not matching with merge results

I'm using Subclipse 1.6x plugin in Eclipse. Let me explain the scenario first:
Say I have the trunk of my project with revisions r1 to r100.
At revision r100 I created a branch and started committing say r101 to r105.
At this point, I thought I will bring in any changes from trunk so that my branch is updated.
But due to a merging mistake, I end up merging r80 from trunk to my branch and committed it as revision r106. So I revert my change in r106 in the branch and do another commit r107 to this branch.
During this time there has been commits say r108 and r 109 in the trunk.
Now after reverting my bad commit in r106, I correctly bring in all changes from trunk until r109 to my branch (by merging) so that my branch is up to date, and commits this to my branch as r110.
All is good. Now I decided I don't need the branch so let me merge all changes in branch (r110) back to trunk. So after this merge all I should see is the changes I made in the branch (revisions r 101 and later in that branch) as my branch is up to date with trunk.
I do a Team -> Merge with From url as trunk and To url as my branch path. The From revision is the last merged revision in trunk (r109) and the To revision used is the latest in my branch (r110). I tried a Dry Run and also creating a Unified Diff file option in the Merge window. Both of them looks correct and the only updated files are those I changed in my branch.
Now I run the Merge and and the merge result is different from Dry Run. First it correctly merges files shown by Dry Run (which is what I expected). But it doesn't stop there. It then tries something like this:
--- Merging r80 through r110 (May be because of my wrong merge in the branch???)
and then does something like:
--- Reverse-merging r110 through r80.
The end result was merging in all my changes exactly as the Dry Run result plus a lot updates/changes to other files (due to second Merging and reverse-merging I guess).
Any thoughts on why this might be happening and how to make the merge result correct/same as the Dry Run result? Even the Unified diff file created is correct.
Thanks for reading through the lengthy post.
The Subclipse merge dialog has not been worked on since before Subversion 1.5 and the introduction of merge tracking. I would suggest you install the CollabNet Merge Client plugin that is included on the Subclipse update site and see if you get the same results.
The Team > Merge option should bring up a wizard if this client is installed.
Ok I figured this out or at least solved it for my case. The issue was because on my branch I wrongly merged r80 from trunk and committed as r106. Then I did Team > Revert > last commit to revert this merge-commit and checked this as a new commit r107.
There are 2 issues with this. First this is not the best way to revert a merge commit in SVN. Google for more details.
Second issue is when you merge these changes (in multiple commits) back to trunk, SVN will try to apply each commit one by one to the trunk. As I messed up r106 on branch by merging r80, SVN gets confused about the change because of conflicting ancestry for the files. In order to avoid this, and to tell SVN don't worry about the ancestry but just merge the differences/changes in my branch to trunk, check the "Ignore ancestry" option in the Merge window. This took care of the problem for me.
Also as a side note, in SVN merge, the result of Dry Run is equivalent to running Diff between the files. But when you do the Merge, it will look into the ancestry of the file and brings in each commit one by one to do the Merge. Hence the results may not always be the same. There is more details on this in SVN documentation.
This is what I understood from my experience and am posting this here as answer as I didn't get any other responses to my post. Please add any comments if I'm not fully correct.

What is the "best practice" to remove support for a feature?

I have a library that deals with several message formats. Each of these formats is closely related, they're a common base XML then each has some additional constraints or extra data on top of it.
One of these formats was created just to support a proof-of-concept or pilot effort. The pilot is over, its no longer being used, and it imposed some awkward constraints. I've gotten permission to remove support for it. What is the correct way to do this?
I'm thinking:
Open an issue to track/document the changes
Tag the SVN revision, "FEATURE_X removed here"
#Deprecate the specific classes. Cite the issue. Commit.
Watch the warnings and see what the deprecation affects
Let it sit for a bit, give the team a chance to deal with the deprecation
Finally remove the code. Verify that the tests are OK. Commit.
I think you have a good list. To echo #hvgotcodes, this presupposes the API is not used by anyone outside your team. In either case, inside the deprecated method, I would log stacktraces for any calls to it. This would catch both internal and external uses.
To the steps above, I'd suggest to clearly communicate to others that the feature will be dropped by the given deadline. And if the feature and/or team is big, I'll suggest get others commitment to remove their code dependencies by that date (the bigger team is, the more important the commitment is, consider managers support for this task). As my experience shows, removing something is a big surprise to a few users, and there is always someone somewhere with somecode that still depends on the FEATURE_X. And last but not least, additional step to do a dry-run removal, that can be easy and quickly undone.

Categories

Resources