At the moment I have 5 differently branded products with almost the same codebase (the differences are brand related) and all those products live in the separated mercurial branches.
Bug fixing and development is done in the default branch and all changes are transplanted to the branches with hg transplant command. This approach is working but number of the brands might be increased it'll take longer to keep all branches in up to date state.
I'm wondering if there is any other/easier way for this task.
Using transplant in this case sounds like overkill. You should simply be making the bugfix changes in the default branch and use hg pull (on the branded repositories) and merge the changes on all of the branded repositories.
transplant was added to Mercurial to allow for cherry-picking changesets that needed a special case to go backward in the normal flow of changesets (i.e. a single change introduced in the fork/branch needs to be spliced into the original repository)
Related
I have two repositories with tho different mercurual named branches, say V1 and V2. The branches are divergent since about one-two years. I'd like to graft some changesets from one repo into the other, without pulling the changes.
I don't want to pull the changes for multiple reasons.
I don't want to conflict developers with history of multiple branches, because there will be enough local branches to care about.
I want to have single branch central repos and developers could accidently push the second branch. The central branches would interact with SVN and should have only one branch per repo. I know I could use central hooks, to prevent such a push, but I don't want questions like, can't push, or how can I do that.
The size of the repo would grow to multiple gigabytes (before pull about 700MB). As I understand, it's because of deficites of current mercurial storage format.
I know, the transplant extension can do the work. I tried it, but I can't force other developers to handle rejects instead of simply use a merge tool. Is there an other way?
In fact there are more then two repos with each a branch, but for the example simplicity two should be enough.
You might be able to do the work in an intermediate repo:
Pull in the changes
Do whatever grafting/rebasing/transplanting you need
Strip out the things you pulled in step 1. or if that doesn't work:
Pull only the changes from the branch you want into the actual repo
You'd end up with a repository that includes your desired change sets, but not all the history from the unwanted branch.
Follow-up to #DanMan
Pull needed branch into intermediate repo
Strip unwanted changesets in clone
hg pull CLONE in real target
Write a tool, a hg-extension or extend the graft command so it can graft from a second repository, similar to the transplant extension.
Yes, the implementation is not so easy as adding the second-repo-functionality in the transplant command. The transplant extension simply uses a patch from an other repo instead of one from own repo. But I think also for graft there is no technical reason, not to do that.
If I understand right, grafting of a single file change is not more than calling the merge tool with the files:
(base) the parent of the to-graft changeset
(my changes) the target revision, on which to graft
(theirs) the to-graft refision
So in order to graft a file change from an other repo, the whole file from other repo is needed before the to-graft changeset was applied (base) and after it was applied (theirs). Technically it should be no problem.
Additionally the implementation
need to determine, which files are affected by the changeset to graft
need to handle deletions correctly
need to handle file renamings (not sure, how complicated it is)
All that should be possible, I see no real technical problems.
I really like the Hg Flow for Mercurial repositories. we are currently using Bitbucket, and in each product multiple developers are working. basically they can work as below:
a team might work on a single feature.
another team might work on a release/hot fix.
So do i keep the "develop" branch in BitBucket or local repositories. and how about feature branches, should i push them to the central repository and remove when required. i assume we should do so right?
Thanks
I personally neither use git flow or hg flow as tools, but I do use some of the methods for my own projects (manually).
Before going into detail, you always need to provide branches in the main/bitbucket repository when multiple people need to merge or branch from them.
This definately includes "develop" and probably also features/fixes multiple people need to work on (unless you have another repository or method to exchange branches/commits between them)
The difference between using git and mercurial/hg is relevant here, since the branching models are quite different.
See A Guide to Branching in Mercurial for details. Using hg bookmarks would be quite similar to what git does with branches, but there is no full support for the bookmark branching model on BitBucket (see this ticket).
hg flow (the tool) uses named branches. In contrast to git branches, these are not at all light-weight, but permanent and global (they can at least be closed now).
This means whenever any commit created on any (named) branch other than "default" is pushed to bitbucket (even after merging) this will create the branch in the bitbucket repository.
So you don't have any other choice than keeping all branches in the main repository.
However, You can decide when to push and when to close these.
I would advise using hg push -r to push only the branches/heads you want to push and only pushing these when they are either needed by somebody else or finished and merged.
Branches should be closed as soon they are not needed anymore. (This is probably done by hg flow automatically)
You should close branches locally whenever possible. This way they might not even appear in the bitbucket interface. Some might reach the bitbucket repository only in closed state (which hides them from the interface).
Obviously you should often push any branches multiple people need to merge from.
In my understanding of the workflow the "develop" branch is always exactly one branch per project that should be pushed frequently (after local testing).
In case you are either not using hg-flow or named branches things are a bit different.
Both, using forks/clones or bookmarks as a branching method doesn't generate permanent or necessarily global branches.
Like mentioned above, you can't use bookmarks (reliably) when you also want to use bitbucket pull requests. You have to push bookmarks separately. A normal push will only update (a head of) the branch so you might miss commits from other team members when marging later. Hg will tell you when a new head is created. In that case you might want to merge the branch with the remote bookmark into your branch before pushing.
When using forks as branches it works a bit like with bookmarks, but bitbucket has full support for that. You need to have a new fork on bitbucket for every branch.
You naturally only want to create extra forks if you need different people to work on it and you don't have other means of commit exchange for them. You will need at least a separate "develop" repository then.
I personally wouldn't use the full "flow" with hg on bitbucket.
For my projects the "develop" branch is the same as master/default, since I don't roll out releases with git (other than development builds, that wouldn't use the release branch anyways). I don't need a separate "production" branch, since tags can mostly be used for production usage.
I also don't create a separate "release-preparation" branch. There is only a point in time when I only apply bugfixes on develop and stop merging features. That obviously won't work when you need to work at the same time on features that are dependendant on features not to be released in the next release.
Always using the full "git flow" is easy because git branching is easy and light-weight.
Depending on the branching model you use and how supportive the other tools are,
using the full "hg flow" might not be "worth it".
The hg guide actually discourages use of named branches for short-lived branches.
See Feature separation through named branches.
The "easy" branching concept promoted in the guide is forking/cloning. Bookmarks would be the natural way to translate git flow if the tool/bitbucket support would be better (and bookmarks longer a core hg feature).
Disclaimer:
I prefer git when I can choose. I do use hg, but not as my personal choice.
You also might have considered most of this, but since you didn't state any of these details and accept an answer (in the comments) that is quite different to what you are asking, I wanted to elaborate a bit.
Edit:
To follow-up on the comments:
I think hg bookmarks are comparable to git branches because both are just movable pointers to commits.
The main difference is, that when you delete a branch in git, the commits are possibly lost (when not part of other branches or pointed to in a another branch before they are garbage collected). When you delete a bookmark in hg, then the commits are still part of the repository (part of the (named or default) branch) unless manually stripped.
Anonymous heads are related, but only as something the bookmarks point to. Without bookmarks pointing to them the anonymous heads are not usable as a branch to work with (for more than just a local merge) and share. When you have anonymous heads in a repository you don't know what they are supposed to be or where they came from, unless you remember or have other clues. In my eyes anonymous heads are only a workaround for late implementation of bookmarks and no good implementation of remotes/remote heads.
Named branches are rather unrelated, as the only thing they have in common with git branches is having a name. They are light-weight in comparision to cloning the whole repository (forking as branch model), but not in terms of "you can't get rid of them". They are permanent.
Most places tell you not to use named branches unless you have a very good reason or it is a long-running branch.
The problem is following:
We have default and feature branch and at some point we have to bring changes from default to feature branch.
The changes are numerous and cannot be merged by one team member because the different changes were introduced by different people and the conflicts that are numerous need to be resolved by the people who introduced them.
Is it possible to perform multiple stage merge so that everybody on the team resolves their own conflicts on their workstation using some mechanism within the Mercurial itself?
Any idea how to do it other then put everyone into one office on one computer and lock them up until they are finished?
You can merge specific changesets from one branch to another. If you're willing to to do them in order you can just use hg merge one after another - but that will require scheduling the developers. Identify a range of changesets that should be merged (from when the default and feature branches divererged), identify the developer that should merge them. Do the merges in sequence.
If the changes from the various developers are independent then you could also use hg graft which would allow a more parallel merge. Each developer would graft their sets of changes to the feature branch, and then you would do a final hg merge (which may be a no-op) to finish everything up.
In both cases it might be easiest to branch one or more merge branches off the feature branch and merge/graft to there, resolve any issues, then merge that branch to the feature branch.
I've forked a project from the internet, and I want to write some new features. I want to write several orthogonal features at the same time, (eg. debug helpers, new feature X, new feature Y), and have the code for all of them in my current directory, but when I commit, I want to be able to say "these files go to branch 'debug'", "those files go to branch 'feature X'", etc. Where these are branches in the 'hg branches' sense.
The reason for this is the project upstream may not want to merge my debug helpers or hacked bug fixes, but I certainly want to use them whilst developing my features.
Effectively, I just want to apply the changes in those files to the branch, but keep several branches checked out & merged to my current working directory.
Is this possible? Perhaps there's some hg extension to do this?
Thanks!
Look at mercurial queues (MQ) for things like debug helpers or local hacks. Very useful for patches that you only want locally and may want to apply to any revision/branch.
Doing the same thing with branches becomes tedious IMHO as you have to be very careful to do the changes for debug and features on different branches, and then merge them in to a local, throwaway branch in order to run anything. You can end up with lots of changesets on the feature branch that leave the tree in a broken state because you can only test after you commit.
I don't fully understand why you'd you would want to do things that way. If your features are orthogonal, you can work on them independently until they are ready to be merged. That is exactly what branches are for after all!
But to answer your question: you could commit on a branch and then, as a matter of workflow, always up to default and merge it in. That would keep the default branch as the sum of the other features. You would need to update to the feature branch before you commit, though and that could get tedious.
The other option for post-facto determining which branch you want to commit to is to use the rebase extension. In this case, you'd commit your changes and then do hg rebase -d targetBranch.
I don't recommend using history revisions as part of your standard workflow, though. That smells to me.
I've been working with Mercurial now for some time. When making (private) changes to some third party software, in the past I always created a separate named branch for these changes. When the upstream code updates, I simply merge it into my named branch.
Today I read about MQ (Mercurial Queues - chapters 12 and 13). I think I understood the concept behind MQ, so my question is:
Is there any advantage of MQ over (named) branches in Mercurial (for my scenario)?
The main advantage of MQ over named branches are:
You can revise your patches. This lets you edit history and so you can maintain a clean and logical series of patches on top of the upstream code: if you notice a mistake in a patch you refresh the patch instead of making a new commit.
The changes in your patches will be cleanly separated from the changes made upstream. When you merge two branches, you mixing the two streams of development. This makes it difficult to see the changes you've made without also seeing the changes coming in from the upstream branch.
The patch names are transient. When you hg qfinish an applied patch, there's no trace of the patch name left in the commit. So you can use MQ without coordinating first with the upstream repository since they'll never notice MQ.
You avoid merges. Instead of merging with the latest code from upstream, you rebase your applied patches. This gives you a simpler history. The history is obviously fake since you pretend that you made all your patches after seeing the code from upstream — when infact you made it in parallel with upstream and later moved your patches to the tip of upstream.
You have no permanent branch name in the changesets. People sometimes treat named branches as disposable and become upset when they realize that a named branch is fixed in history. (You can actually set the branch name with hg branch before pushing patches so this point is not so bad.)
Disadvantages of MQ are:
It's an extra tool to learn. It's powerful, but it also gives you more opportunity to shoot yourself in the foot. Running hg qdelete will really delete the patch and so you can throw away data. (I think this is fine, but we've had a Git user coming to our mailinglist complaining about this.)
You make it much harder to collaborate with others. You can turn .hg/patches into a repository and push/pull patches around between repositories but it's difficult to do that if you're more than a single developer. The problem is that you end up merging patches if more than one persons refreshes the same patch.
You have no permanent branch name in the changesets. If you're using named branches right and use stable, long-term branch names, then you will miss that when using MQ.
Good question. It depends. Personally I dislikes mercurial branching system, and I try to avoid it when I can (using pushed bookmarks instead of branch).
MQ is a great tool, with great power and great pitfalls. You can also consider using pbranch.
MQ is a great tool if you need to produce and maintain a patch-set for a project, something like adding feature-x to a project and keeping patches updated with the upstream code.
Bookmarks (or branches if you like) are good for short-development task that require to be merged into the upstream code.