Mercurial: Merging from unknown divergant 'branch' - version-control

I'm trying to do some work on a project called NS-3, but my problem isn't project specific so I thought I'd ask here as well as the relevant mailing list.
Basically, a copy of the then current project code was made, and a fresh repo made of that code. Work was done on both the 'forked' version and the trunk.
So cloned the forked source, cd in, and hg pull <latest-dev>, hg merge, and while it wasn't a perfect merge, the changes that were unmergable were all related to one library change, so easily fixed (in theory). Naturally this optimistic attempt failed to build.
Now I'm not entirely sure where to go from here, I'm new to DCVS so please; ideas directed towards a 5 year old!
How can I find out which changeset of the forked version was last merged against the dev-trunk since they're separate but related repos?

The Case Where You Started With a Copy Not a Clone:
If this is what happened:
Project Exists
Copy (not clone) of project is made
hg init is run in each separate copy, creating two unrelated repositories
work is done in both copies
Then to merge them you want to do this in the newest of the two unrelated repos:
hg update 0, which jumps the repository back to its earliest point -- the point where it last looked identical to the other
copy in the contents of the working directory from the other repository
hg commit, which creates a new head
hg merge, which merges the two heads and also provides a base revision, which helps the merge process.
The key is getting a base revision involved if possible. What DVCS systems bring to the table that CVS and SVN don't is that every merge is a 3-way merge between two heads and the most recent common ancestor. Faking that common ancestor by creating the new head off the last point the two repos looked the same (revision 0 in the copy) simulates a base revision.

The Case Where You Started With a Clone Not a Copy
This is the classic DVCS case and there shouldn't be much you need to do. Just go into one of the clones, hg pull from the other and fire off the hg merge. If the merge requires input you'll use hg resolve to provide it, and when you're done hg commit.
If at this point your code isn't building/running then you need to just start debugging. Use hg blame to see what was being done near the lines that won't compile and try to suss out what was being done and how to work on it.
The merge process is much easier the more frequently you do it. Pull in up-stream changes daily, not monthly.
You can turn on the GraphLog extension and use the hg log -G command to see the point at which the two lines of development diverged, but in the end merging is development, and you just need to approach a non-building merge like you would any other software defect.

Related

How best to clean up Mercurial repository with many old open branches?

I have inherited a code base stored in a mercurial repository.
The repo has about thirty open branches, including:
old release branches for releases that have long been superseded.
old feature branches that have been merged into trunk(*) but not closed.
old feature branches that have been abandoned (not merged anywhere).
Many of these old branches have not been used for years.
I would like to close these old branches so that hg branches will give me an accurate picture of current ongoing work.
If I close so many old branches, I imagine that's going to mess up my graph in TortoiseHg and make it harder to follow what's been going on in the past.
That's not a massive problem, but it has me wondering is there a better way to clean up a mercurial repo with many old and inactive branches?
(*) default was abandoned and replaced with a primary branch named 'trunk'.
Closing branch in Mercurial just hide head of this branch from hg heads output, nothing more: merged branch with not have head anyway
If you perform partial clone, you'll get in clone only needed|used parts of source repo: hg clone -r tip ... will clone only ancestors of current tip, all unmerged branches will be ignored (deleting merged branches is, anyway, bad idea)

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'.

How to avoid getting git errors/conflicts on untouched files?

I often see the below errors on doing git pull on totally untouched files which I am NOT working on.
Pull is not possible because you have unmerged files
It is clear the conflicted files have changed in the git repo. But I don't understand why git pull cannot over-write on these untouched files - which I've not touched?
What can I or my team do to avoid getting these errors?
Edited -
Along with the solution I want to understand why the errors are coming.
Just to make clear, the other team members are working on other files (say xyz). And I am working on a separate set of files having no dependency on xyz files. So if I pull the repo changes after a long time with no changes from my side in xyz, why the conflicts in those files?
use git diff to see problem files
look at this git cheat shets for usefull commands
http://www.cheat-sheets.org/saved-copy/git-cheat-sheet.pdf
http://jan-krueger.net/wordpress/wp-content/uploads/2007/09/git-cheat-sheet-v2-back.svg
There are some tips from my own experience. i'm not sure whether they're 100% corerect)
Split work with your team on paralel threads. Try not to work in the same files.
Try to avoid situations when 2 or more persons are adding new files simalteniously. When one added new files others should make pull as soon as possible
the last but not least - make git push very often. this will keep your project git up to date
Since git pull does not pull individual files, it's git merge phase will stop for manual correction of any merge conflicts. git merge and/or git pull (and by nature of the fact that git pull is essentially git fetch followed by git merge) is an all-or-nothing operation - you either successfully merge the changes introduced on both (or all) of the branches you are merging together, or you don't merge any of them. The catch in that is when conflicts arise that must be manually resolved - but in that situation, you are in an in-between state, having neither completed and committed the merge nor rolled it back to your previous state.
The message you are getting implies that you have previously done a git pull or a git merge, which stopped in the middle, requesting that you manually resolve some conflicts, which you have not yet done, but have rather continued on doing other stuff, and are now trying to do another git pull / git merge without ever having completed the first one.
Take a look at git status, and follow the suggested directions for either resolving your in-progress merge issues or resetting back to a not-in-the-middle-of-a-merge state.

How can I rollback my subversion repository to an earlier version

We've just spent two weeks working down the wrong path on a problem (with all the commits to our SVN repository that go with that). We've now come up with the right solution (which needs our code base to go back to what it was two weeks ago). We should have branched two weeks ago, but that is irrelevant now.
Clearly, I can make a second checkout of the project and then copy that over the current version of the repository and check that in.
Is there a cleaner way to do this without a second checkout?
There are many ways to do what you want. The simplest would be to check out a new copy of the codebase to a dev machine, specifying the revision for the commit made just before you went down the wrong development path. Then, simply check that code back in as the latest revision. Not only do you effectively "revert" the codebase to that revision, if you find out that some element of your wrong solution was useful after all, you still have easy access to those elements.
Also, as was said, you can branch the codebase at any time, at any revision. Simply cut a branch of the revision before you began your work, and continue along your new dev path. Keep in mind that merging this branch back into the trunk could be problematic; you'd want the end result of development in the branch to replace the codebase of the trunk wholesale. That's possible but it can get messy.
There are a few ways of handling this:
Revert your changes:
$ svn merge -r$rev2:$rev1 .
This is assuming that $rev2 > $rev1. This will back out the changes between these two revisions. If you're backing out a single revision, you can use this:
$ svn merge -c -$rev .
That is, the revision should be a negative number. This will back out just that one revision.
Recreate the Branch
If this work was not done on trunk, but on a branch, and you pretty much want to toss out that branch, you can simply recreate the branch, and even delete the old bad one. Branches (and tags) can be created from any point in time:
$ svn cp -r$rev $REPO/branches/$bad_branch/$proj $REPO/branches/$new_branch
$ svn delete $REPO/branches/$bad_branch
The solution provided by Mike works for me.
In a separate branch
$ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk
(this undoes the change between 302 and 303).
Then you can commit the changes in your branch, test and then merge back to the trunk as normal.

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.