We've recently moved our codebase from subversion to mercurial, and are doing our first release to production from the mercurial codebase this weekend.
We have a three repo setup, let's call them dev, stable and release, where dev is a clone of stable and stable is a clone of release. At the moment, dev has our version 7 code, and stable has our version 6 code. We've just pushed the version 6 code to release. Our next release, version 6.1, is scheduled for next week.
The problem is that, since we're also doing a major upgrade in the v6 release, we're expecting to release multiple times (6.0.1, 6.0.2, etc) before the 6.1 release. Going forward this won't be a problem as all three repos will have different version numbers, but right now both stable and release are v6.
If I change the version numbers in our poms on stable to 6.1, this change will have to be pulled back to dev, which will mean fixing it there before any of those artefacts can build (so as to not pollute the v6.1 release with what are really v7 artefacts).
Is there a way to tell mercurial to pull this change into dev without actually accepting the change, similar to what svn's merge --record-only does? Is the only option to pull the change to dev and then do a backout?
Thanks
I can't say I follow your version-management logic; what do different version numbers have to do with which changes you pull or merge? But if I understand you correctly, you want to modify the explicit version number in the stable branch (say, to 6.1), then continue pushing changes to dev but prevent the version number of dev from becoming 6.1.
Here's how you do it: Make sure the version number is in its own changeset-- you don't want it sharing a changeset with changes that you do wish to apply. Now merge this changeset, telling mercurial to always use the "local" version of a file during the merge by means of a special "merge tool":
hg merge --tool internal:local -r REV
As hg help merge-tools explains:
A merge tool combines two different versions of a file into a merged file.
...
"internal:local"
Uses the local version of files as the merged version.
See the full help for the details.
Merging revision REV will also merge any changesets that REV depends on. So you should first merge the revision immediately before REV (in the normal way), if necessary. This could be automated with
hg merge -r 'parents(REV)'
Related
I'm getting errors when pushing and pulling from a repo on a server. We have a repository (a folder) on a LAN-server which we push our commits to. This worked from the beginning but now it seems to not find the changesets on the server anymore, so tortoisehg ends up by trying to push all the revisions it locally has, to the server.
Also, when I view the repository on the LAN-server in HG workbench, it doesn't show any revision, the only one I can see is a revision -1?
So my question is, what have could gone wrong? And is there a way to fix this? I already replaced the repository on the server with my local one, and that went well for a few days until it happened again.
Revision -1 is what mercurial shows on an empty repository right after a hg init without any commit whatsoever.
If your LAN server exports the repository over a windows network share, indeed it might have been a serious bug fixed in Mercurial 3.3.2 (see https://bz.mercurial-scm.org/show_bug.cgi?id=4546 - maybe you can reproduce that with a new test repo. Upgrade, if that's the case for you)
What Mercurial version are you using?
It's possible that you have been impacted by the bug fixed in Mercurial 3.3.2 (released yesterday).
The solution in that case is to upgrade to Mercurial 3.3.2.
we use Kiln with mercurial.
Simplified description we have 2 kind of Repositories.
Some Kind of
"CurrentDevelopment" and repositories for each released version for example 13.1 for the released version 13.1. (There are also user repos and more, like descriped in hginit.com but this can be ignored for the moment)
Now sometimes we need to make a fix to a released version. So we fix it in the Repository for the released version. For 13.1.
Then we cann pull from 13.1 to the currentDevelopment repository
This seems to work fine.
But now we could make something in "CurrentDevelopment" and a month later we recognize that this change will also be needed in 13.1 But I can't pull from CurrentDevelopment to 13.1 because there are a lot of other changes i don't want to have in 13.1
I know this is some kind of "cherry picking" which i isn'T easy realized. But if it wouldn't be many source code i code recode them in 13.1.
But after that when i make changes to 13.1 which i pull to current development i would also pull the changes that are already included in CurrentDevelopment :-/ so in worst case i may get merge failures and duplicate code? I'm not sure if mercurial will safely recognize that this code is also contained.
What is the recommended approach to realise these version specific repositories and handle changes between them ? In especial if a change of the current development repository is afterwards needed in a child verison branch?
The graft mercurial command is your friend here.
It allows you to back-port a change to an old branch.
If your Kiln version is older & doesn't have a version of Mercurial that includes the graft command, you could use the (similar but less reliable) transplant extension.
(graft uses Mercurial's merge logic, transplant just uses the patch logic)
edit...
I don't think that graft command is exposed in the UI of the version of TortoiseHg that is currently bundled with Kiln. See how to use graft in TortoiseHg
The command line should still work though.
I'm new with HG, I'm looking for some advice on how to handle this scenario.
We have a central repo hosted at Kiln. The three guys on my team code away and eventually are ready with our code which we tag and release as Version1. We then happily start working on our next major version. While working on it, there's the need to fix a critical bug in Version1 so James clones his repo using hg clone -r Version1 http://centralrepo where he makes his change and tags it as Version1.1.
Now, how does Version1.1 get back to the central repo? Using hg push causes an abort because there are two remote heads. Without it being in the central repo, Doug can never come along and make a fix to Version1.1 if it ever becomes necessary.
How can I modify my process so that all my tags are always stored on the central repo and easily pulled into the dev branch?
UPDATE/EDIT
With the suggestion from Joel, I made the following tweaks:
On the Kiln website, I create my main active dev repo. Once I have the code in there, I create a new branch from it.
I clone my ActiveDev branch: hg clone http://activeDev code-activeDev
I clone my Stable branch: ht clone http://stable code-stable
I setup a tag on my stable branch: hg tag V1.0 and then push it to the stable branch and to the active dev branch. When going to activeDev I use the -f command. Now both branches are identical.
I do an hg pull and start on a new feature in ActiveDev. Then push that feature back to central:
hg com
hg push
Stable gets a bug fix, then pushed to it's own repo using the same two commands. Now when I try to push that fix to the activeDev branch, I'm again given the 'you are making two heads, use -f' message. However, if I force it, the new feature I pushed earlier in activeDev is blown away by the fixes I did in stable.
Did I do something wrong? Am I missing a step somewhere?
Basically, you need to merge the fix so that there is only 1 head again. There is a way of managing 2 branches that makes doing bugfixes on released versions (in parallel with development) easier:
The process I use is to create a named branch called Stable in addition to the default branch. I work on new features and whatnot on the default branch. Whenever I do an actual release of code, I merge that over to the Stable branch and only tag things like v1.0, v1.1, etc. on that branch.
Then I can continue development on the default branch, but when a bug comes up that is relevant to a previous version I can put that fix on the Stable branch and recompile. When ready, I merge fixes from the Stable branch over to default to make sure that Stable is always just a subset of default.
If you start using this, the first time you push that named branch to central you will have to use hg push --force, but only once.
I'm new to Launchpad and Bazaar, and I'm trying to figure out what the best way is to submit bug fixes. I'm using some reasonably popular open-source software that's hosted on Launchpad, but it's not very stable. I've created my own branch of the project to stabilize it and apply just the bug fixes we need without adding other changes from ongoing development.
When I file bugs and then figure out how to fix them myself, I push the fix to our stable branch. How should I publish the fix back to the main project? I could create a patch file and attach it to the bug, or I could propose a merge for our stable branch.
If I fix multiple bugs, can I make a separate merge proposal for each one, or are they cumulative?
Update: It looks like the OpenERP project's official documentation now has guidelines for making merge proposals. I'll also leave my version here because it has some different details.
After playing with Bazaar and Launchpad for a few days and submitting a few patches and merge proposals, I thought I'd write a summary of what I found. Launchpad and Bazaar provide some powerful tools, particularly for community-driven projects, but I don't think new users are likely to fall into the pit of success yet. There are several ways to make the process slow and frustrating, so I hope this walk through helps some people avoid a few mistakes.
Here's the work flow I've learned for working on bug fixes and submitting merge proposals back to the team for a project that's hosted on Launchpad. I'm working on a GNU/Linux workstation, but I assume the Bazaar commands would be equivalent on other platforms. In this example, I'm working on one of the projects in the OpenObject project group called OpenObject Addons. The maintainer's user name is openerp. I'll put my workspace in the ~/workspace folder.
If you want to learn more about any of the commands here, use bzr help plus the command name.
Create a shared repository
Because I'm going to be creating a branch for each feature I want to contribute back to the project, I don't want to have a separate copy of the project's entire history for each branch. To avoid that, I create a shared repository and then create each branch within that. One thing to be careful of is that your repository format has to match the official branch's format to make some of the later steps work.
Check the repository format on the official branch:
bzr info http://bazaar.launchpad.net/~openerp/openobject-addons/5.0
Get the code
Now create a workspace folder that will hold any local branches on your machine - I just name it after the project. Then create a shared repository in it using the format you found on the official branch.
cd ~
mkdir workspace
cd workspace
mkdir openobject-addons
cd openobject-addons
bzr init-repo --format=rich-root-pack .
The next step is to check out the source code from the official branch. It's usually called trunk, but you might prefer to work with a stable release branch that is just being used for bug fixes. In this example, I'm going to work on the 5.0 release branch.
cd ~/workspace/openobject-addons
bzr checkout lp:~openerp/openobject-addons/5.0/ feature-x
That step is probably the slowest in the whole process for a large project, because you're copying all the code plus all the history for the entire project onto your hard drive. Note that I name the branch after the feature I'm going to work on.
Create a branch
At this point you can experiment with building and running the code on your local workstation. You can make changes to the code, but you don't have anywhere to commit them yet, because you're probably not allowed to commit directly into the official branch. To publish your code changes you need to create a public branch. If you're new to Launchpad, you'll need to create an account and register a public key first.
Once you've set up your account, you can publish your own branch as a copy of the official branch, and start working with it. The lp-login command tells bazaar what account name to use on the launchpad site, and the whoami command tells bazaar what name to use on each revision you commit. The e-mail address you use in whoami should match one of the e-mail addresses you configured for your Launchpad account.
cd ~/workspace/openobject-addons/feature-x
bzr lp-login donkirkby
bzr whoami "Don Kirkby <donkirkby#example.com>"
bzr branch --stacked --switch lp:~openerp/openobject-addons/5.0/ lp:~donkirkby/openobject-addons/feature-x
You switch to the new branch so that commits will be recorded in your local history and in your public branch. You might want to learn about the difference between a checkout and a branch. Making this a stacked branch means that it's very fast to create because it only contains the history that's not in the official branch. This blog post makes it sound like branches of public projects should default to stacked, but that hasn't worked for me. Notice that I named the branch after some feature I want to add. As bialix suggested, I create a separate branch for each feature that I will eventually propose merging back into the official branch.
Commit and make a merge proposal
Now that you have a branch, you can make code changes and commit them.
cd ~/workspace/openobject-addons/feature-x
bzr commit -m "Fixed bug lp:12345 by fleaking the woverbinate() function."
You can commit from anywhere within the branch structure, and it commits the entire branch by default. Run bzr help commit for details. You might also find bzr status and bzr diff useful.
Once you're happy with the changes and you've committed everything to your feature branch, you can go to the Launchpad web site and create a merge proposal. Here's a handy shortcut that you can run to launch the branch's web page:
cd ~/workspace/openobject-addons/feature-x
bzr lp-open
Once you create the merge proposal, Launchpad will generate a diff for it. It's well worth reviewing that diff. Sometimes I've selected the wrong branch as a target, and I only noticed because the diff had way more changes than I expected. There's also a bzr send command for merge proposals, but I haven't used it.
There's an e-mail interface for shepherding your proposal through the process, or you can just use the web site.
It's also useful to attach the branch to the bug so that other people can use it like a patch on their own systems.
Ongoing changes
If you work on several features and the maintainer isn't very speedy at reviewing your proposals, it's probably worth setting up your own mainline branch. This branch collects all your features together and it holds the code that you would run on your servers. It's also useful if the official branch isn't very stable and you want to stabilize a branch for your production environment. Then you can decide when to upgrade to the latest, and when to take specific patches for bugs that are hurting your users.
The first step is to create another branch that is stacked on the official branch:
cd ~/workspace/openobject-addons
bzr checkout lp:~openerp/openobject-addons/5.0/ main
cd main
bzr branch --stacked --switch lp:~openerp/openobject-addons/5.0/ lp:~donkirkby/openobject-addons/main
Now there are two sources of changes you'll need to merge from. First, merging from a feature or bug fix branch:
cd ~/workspace/openobject-addons/main
bzr merge lp:~donkirkby/openobject-addons/feature-x/
bzr commit -m "Merged feature x"
Of course, if you still have a local copy of the feature branch, it will be faster to do a local merge:
cd ~/workspace/openobject-addons/main
bzr merge ../feature-x
bzr commit -m "Merged feature x"
Second, you'll occassionally want to merge the latest and greatest from the official branch:
cd ~/workspace/openobject-addons/main
bzr merge --remember lp:~openerp/openobject-addons/5.0/
bzr commit -m "Merged from 5.0 branch"
After using --remember when you merge from the official branch, you can just use bzr merge on its own to merge from the official branch. If the project uses tags to mark release points, you can view a list of tags and merge from a tag.
cd ~/workspace/openobject-addons/main
bzr tags -d lp:~openerp/openobject-addons/5.0/
bzr merge -r tag:5.0.7rc2
Such policy (using merge proposals or patches) should be defined by core developers or maintainers of the project itself. But as general rule using separate branches for each fix is preferable way over just plain patches.
Because plain patches may become out-of-date when trunk branch development moving forward. When you keep the branch for the fix then you can update your fix according to recent changes in trunk.
Fixes in branches are simpler to analyze, because other developers can see all your intermediate steps for fixing the problem, or how your fix has evolved over the time as trunk changed.
Also patches attached to bug reports often tend to be missed or forgotten. While the list of all active merge proposals is prominently shown on "Branches" page of every project.
Merging your fix from your branch means the history (and annotations) will keep your name as path author, not the core dev who applied your patch.
Keep all fixes in one branch is not good for using it in merge proposal. But it's useful per se for testing all your fixes or using it as stable branch (e.g. for dogfooding). So I'd suggest to use separate (feature) branches for each separate fix, file for them separate merge proposals, and merge these branches into your stable branch as you doing today. This way you can get full freedom over applying additional changes to each your fix and then merge it again to your stable branch.
If you need to split your existing stable branch to several separate branches you can use the recipe from John Meinel described in his blog: http://jam-bazaar.blogspot.com/2009/10/refactoring-work-for-review-and-keep.html
I'm forced to use Visual Source Safe 2005 at work. I'd like to combine that with a DVCS, so that I can check in files locally without disrupting my co-workers if there's a bug or it doesn't compile.
In my attempts with Mercurial, it works, but causes a few weird issues. Namely, it thinks someone else has checked out the files I have checked out.
Here's my thoughts on how I should manage it:
Disable auto-checkout.
Work locally in Mercurial
When I'm ready to push my changes...
Clone my Mercurial repository.
Update my Visual Source Safe repository
Pull and merge the two repositories using Mercurial.
Check everything into Visual Source Safe.
Does this sound reasonable? I'm always hearing bad things about VSS, is this just asking for me to see those problems firsthand?
WBlasko
I've found the same problem. I wanted to change files and merge them when needed instead of waiting for some other developer to unlock it. The solution that worked for me was:
1) Get the latest version of a VSS project (I placed all VSS projects under vss):
c:\vss\projectA
2A) Initialize with Mercurial
cd vss\projectA
C:\vss\projectA>hg init
2B) Clone the project to the place where it could be changed at will
hg clone vss\projectA myProjects\projectA
3) Grab the latest changes from the VSS copy (skip if you came from 1 and 2)
C:\myProjects\projectA>hg pull
C:\myProjects\projectA>hg update
(solve conflicts if any)
4) Work at will with the cloned version. Later, push your work to the vss copy:
C:\myProjects\projectA>hg push
(don't run hg update yet, wait for VSS latestes version)
5) Now, perform a checkout of all files to the VSS project
6) Run "hg update" on the VSS project to merge your changes to the latest VSS changes.
C:\vss\projectA>hg update
(if there are conflicts, resolve them)
7) Commit the changes
C:\vss\projectA>hg commit
8) Perform a VSS checkin (releasing the locks to the other folks)
Go back to step 3. repeat steps 3-8 forever then... ;-)
This way you can work with a good version control system while still being able "talk" to legacy projects. You will be also be able to enjoy:
a) No problem with locked files
b) you can share your repository with others that know how to use Hg
c) make branches , etc
Just be carefull to first update/solve conflicts, test and then perform VSS checkin
Cheers,
Luis