Bringing devel and QA branches in sync in Mercurial: should I transplant? - mercurial

In our team we have a single repo with two branches: development and QA. QA was branched off at one point from development and acts as a frozen code branch. Only showstopper bugs that are fixed in the development branch are transplanted to the QA branch using HG transplant command.
What I am wondering is the following: after releasing a certain version, we need to bring the QA branch back into sync with the development branch. I am not sure that this would also be done using the transplant command? or is there a better (more proper) way/command to do that?

I suspect you want to merge from the dev branch into the qa branch:
$ hg checkout qa # get to the QA branch
$ hg merge dev # merge in the dev branch
$ hg commit # and commit the merge
You might also want to consider using hg tag to tag versions after QA is done with them (for example, after the QA -> fix bugs - > QA -> ... -> QA approves cycle, you could use hg tag qa-approved-2011-12-09 to mark the current revision as one QA approves of).

It depends on your workflow, but you should merge development into QA (probably when you're going to freeze the next version).
If you made any commits in QA apart from transplanted ones, you'll better merge QA into development before doing dev -> QA merge.
Transplant if only good for cherry-picking.

Related

Mercurial how to achieve prod-test-dev

I want to follow the structure of prod-test-dev.
In a git environment I would have a single project folder with 3 branches(prod-branch, test-branch, dev-branch).
How is this achieved with mercurial? As far as I understand you need to have 3(!) different projects. A project representing the production branch, another the dev etc.
This seems inefficient. Is there another way to achieve this? It can be that I have not really understood branches.
Update with pic showing the flow when I create this 3 branches in Mercurial:
Basic prod-test-dev flow would look like this:
Create new repository (or start with existing one). For start you have to create three named branches with following commands:
hg branch prod
hg commit -m"prod branch"
hg branch test
hg commit -m"test branch"
hg branch dev
hg commit -m"dev branch"
After you are done your repository will look like this:
For development process you would update repository to dev branch and do some development there. After you have commited all changes to dev and are ready to release that code to testing do following update to test branch select dev branch in and perform merge with local (dev branch). Do the code fixing in test branch and when you are done merge back changes from test to dev branch (update to dev, select test branch - merge with local). Repeat cycle until you are ready for production. Then update to prod branch, select test and merge with local - and you will have your production code ready in prod branch.
After one development test production cycle your repository would look like this:
You should also never close any of those three branches since they represent base for your workflow.
As Lasse noted - just use Mercurial branches (named branches better) in The Right Way (tm)
Here my log of 2-branches repository with single-direction sync

Mercurial merge repository as branch

I have two Mercurial repositories that are for different major revisions of the same project. The latter version is a massive change to the functionality, and especially the UI, of the project, but it will still have a lot of common code with the earlier version. (For shorthand I'll call these versions 4.6 and 5.0 and the repositories project-4.x and project-5.x going forward; that's basically what I'm dealing with.)[1]
As we thought more carefully about the structure of our repository, and thinking especially about how to handle the related code, it became apparent that we wanted to simply pull the repositories together and used named branches for the ongoing work in each (from which people can branch or bookmark and merge as necessary). To do that, we decided we basically need to pull the project-5.x repository into the project-4.x repository. From what I can see, combining the repositories should be fairly straightforward:
$ hg pull -f project-5.x # in project-4.x
$ hg merge
So far, so good. My concern is handling the branching issue.[2] These are going to come in as two completely unrelated chains (which is fine), but I'd like the branch structure to look something like this:
---4.6----- }
\ } original project-4.x
5.0----- }
/
------- } original project-5.x
The problem is, I'm not exactly sure how to do it.
Edit: See below; the answer I devised worked.
Footnotes
If you're wondering why this is only coming up now… well, the project only got version controlled as of starting 4.6. Which, yes, is a little bit crazy. And I'd never been in charge of a major version change like this before, so I decided originally to make a new repo entirely, which I of course now regret. Live and learn.
Answers I've already read on the subject (but which left me unsure how to do this exactly):
Mercurial - merging branches
How do I merge two Mercurial repos into a single one
How can I import a mercurial repo (including history) into another mercurial repo as a subdirectory, without using subrepos?
I originally thought I'd need some way to pull into just the branch, but after chewing on it some more, I concluded the best way to do this is roughly as follows:
Create the desired new branch structure (i.e. create the 4.6 and 5.0 branches).
Remove the old default branch into the 4.6 branch in the base repository.
Pull the project-5.x repository into the project-4.x repository.
Merge the default (or in the case of this repository, experimental) baseline, which is pulled in during the merge, into the 5.0 branch, closing out the experimental branch along the way.
Restrict write access to the old repository's central push/pull location; we still have it for historical reasons, but people can't accidentally push to it.
Preparation (steps 1–2)
$ cd <project-4.x directory>
$ hg branch 4.6
$ hg ci -m "New 4.0 baseline"
$ hg branch 5.0
$ hg ci -m "New 5.0 baseline"
$ hg up default
$ hg ci --close-branch -m "Close default branch going forward.
$ hg up 4.6
$ hg merge default
$ hg ci -m "branch merge default -> 4.6"
At this point, the repository is set up: it has the new baseline branches and has removed the old default branch we wanted to get rid of.
After this, I made the changes to get the repository structure looking more the way it needed to for the 5.0 branch in the project-4.x repository (since massive restructuring is part of the version change effort).
Repository merge (steps 3–4)
The next step was actually merging the repositories together and pushing the content from the old repository into the desired branch.
$ hg pull -f <path to project-5.x repository> # still in project-4.x repository
$ hg merge -m "Merge in project-5.x repository"
$ hg up experimental # experimental is the name of the "default" branch
$ hg ci --close-branch -m "Close experimental branch"
$ hg up 5.0
$ hg merge experimental
$ hg ci -m "Merge old experimental into new 5.0 baseline"
This proceeded perfectly, with no merge conflicts whatsoever (except that I needed to resolve some small differences in my .hgignore file).

I want to implement the following workflow for Continuous Integration scenario using Mercurial/Jenkins

The main repository is where all the developers check-in, lets says its located at
http://hg.main.com:8000/project
Now, we also have http://hg.qa.com:8000/project where all the LATEST code need to be in Sync, PLUS the tests and other artifacts are in this repository. which will ONLY be "pushed" to central repository if 85% of the tests will PASS.
Is there a better way to implement this?
What hg commands would i need, to make sure that i dont overwrite latest commits
start with something ilke:
Approval Management: Auditing and QA
For whom?
If you need explicitely approved code history with a full track record using a team of developers and a seperate QA team, this workflow might be right for you.
Requirements
You need just Mercurial (command line), a shared repository for exchanging data (a simple SSH-server suffices, as does a single private bitbucket repository) and the GpgExtension.
Flow
This workflow uses the default branch for development, as well as a QA named branch and a release branch.
The advantage is that merging default into QA requires an explicit merge which can subsequently be GPG signed by the developer responsible for it.
When QA finishes applying their changes, they first of all merge back into default (so that developers work on the QA version) and then merge into release, GPG signing the merge commit.
Developer
hg pull # get the latest changes
hg update
hg commit -m ""
hg update -C QA
hg merge default
hg commit -m "merged default branch for QA"
hg sign
hg push
QA
hg pull
hg update QA
hg commit -m "QA fixes"
hg update -C default
hg merge QA
hg ci -m "merged QA fixes back into the development branch"
hg update -C release
hg merge QA
hg commit -m "merged finished QA into release"
hg sign
Modifications
If you need more layers than just developers and QA, just add additional named branches, for example staging-release before release.
To make sure that the code has really been checked by all, you can require that all heads must be GnuPG signed in order to enter a higher-up repository.

Mercurial How To Merge 2 Repositories that share a common ancestor but are not clones of the same repo

I am using hg-subversion, and I have 2 different hg repositories one from our svn trunk, and one from a branch of the trunk. I would like to link them somehow. At some point in the history both Hg repositories will be identical is there some way to join them?
In other words is there a way to relate the repositories from within Hg?
The technique I am currently using is to just export the second repository over top of the working copy of the revision they share, and then commit that working copy as a branch in Hg, but I lose the history this way.
Any advice would be great
You could try importing the two repos into one as if unrelated, then merging them. (When you say they share a common ancestor, do you mean that those ancestors have the same revision ID? If so there is a good chance that this will work well.)
hg clone repoA
hg pull -f repoB # may not need -f
hg merge
Can you re-clone the Subversion repository, giving the root of the Subversion repository as argument instead of trunk or one of the branches? I used hg clone svn+ssh://foo/bar/baz once, where svn+ssh://foo/bar/baz/trunk was the trunk and svn+ssh://foo/bar/baz/branches/quux was a branch, and in the end I had two named branches in Mercurial, the "default" branch representing Subversion trunk and the "quux" branch representing the like-named Subversion branch.
If you have outgoing changesets in your existing hg repos, you might be in a bit of a bind there. If there are just a few outgoing changesets, it might work to enable the mq extension and to convert the changesets into patches. These patches can then be re-applied on the new clone (in the appropriate named branch) and eventually pushed to Subversion.

How to repeatedly merge branches in Mercurial

We're using Mercurial where I work and I want to have a setup similar to how I used SVN:
Trunk
Tags
Production
Branches
Since Mercurial supports branches natively, I know how to create a named branch, but I can't find any documentation on how to repeatedly merge 'Trunk' with 'Production'.
Quite simply, I want to have a development branch for normal work and a production branch that I routinely pull changes from the development branch into. How do I do this with Mercurial?
As the previous poster mentioned, the transplant extension can be used for cherry-picking individual changes from one branch to another. If, however, you always want to pull all the latest changes, the hg merge command will get you there.
The simplest case is when you're using clones to implement branching (since that's the use case Mercurial is designed around). Assuming you've turned on the built-in fetch extension in your .hgrc / Mercurial.ini:
cd ~/src/development
# hack hack hack
hg commit -m "Made some changes"
cd ../production
hg fetch ../development
If you're using local branches:
hg update -C development
# hack hack hack
hg commit -m "Made some changes"
hg update -C production
hg merge development
hg commit -m "Merged from development"
Something like hg transplant? That's what we use on our dev and prod branches.