Now many may think I have over complicated the problem or completely lost the plot, but
We adopted Mercurial last year, and moved all our processes over. I wanted to make this as clean as possible and not worry about how did things before.
We have multiple projects working on different releases all at the same time, I had to find an adoption route for Mercurial that had minimal impact on those projects and then a route to wean people off PVCS in stages.
All is well, but I have a small issue to deal with namely support work that is being applied to PVCS that I need to merge back into Mercurial.
I did not have the foresight to create every branch I would need , but I want to creat some branches now.
I want to save a snapshot of the code stored in PVCS in Mercurial, by putting put it in a branch , but I don't have a parent branch to apply it to .
So
I have Branch "Version 5" this is based on revision "0", how can I create branch "Version 3" now , and then later perhaps Branch "Version 2" or "Version 4", whilst showing the ancestory is not desparately important it would be nice.
Related
My question is similar to: Mercurial branches with different codebase
But the solution given there was to do all the work on the one customer branch and merge it to default. I don't see how that is workable in my case.
I have a project that gets distributed to 4 customers. I've setup a named branch for each customer. What is an effective way of merging changes to common code, while leaving alone some customer specific data and/or requirements?
Edit:
I have customers a,b,c. Machines M,N. and parts 1,2,3,4,5.
Right now I have subrepos a,b,c,M,N,1,2,3,4,5 and repos aM1,aM2,bM1,bN1,... . I am considering having subrepo customer (branches a,b,c). machine (branches M,N). parts (1,2,3,4,5)
Are there techniques for making change propagation easy, but also keeping some differences permanent. Maybe something like this:
TipsAndTricks.
Based on your question and clarifying comment, what you want is both impossible and not really what hg is supposed to do.
Everything I am about to say, I say as someone who has made exactly the kind of mistake you are about to make and who has lived to regret it (and slowly, painfully, try to undo it).
As I said in the comments, this seems like a faulty design. If you want something to be part of a code base only for some purposes, then that's a good indicator that what you really need is one of the following:
more configurability to turn features on or off,
a custom build script to assemble various versions of the project, or
a core code base and several customer- or purpose-specific code bases for plugins and add-ons.
You probably don't want customer-specific functionality---and definitely don't want customer-specific data---in your main project's source tree. Anytime you are about to commit a change that includes either customer configurations or code that only one customer will ever use, you need to step back and ask (1) why it should be in your core project instead of a plugin and (2) what the implications would be if another customer or third party ever got access to it by mistake.
I see at least two possible ways:
Customer-specific changes are always in separate changesets, and you move common changes from customer-specific branch into mainline not with merges, but using hg graft, cherry-picking only needed changesets
Using MQ extension, you can have customer-specific changes in MQ-patches (patch per customer), applied|unapplied individually on demand and just merge branches
In the last case separate named branches may be not needed at all (you have default and different patch applied for each customer) - at least I moved to this workflow, when I had to maintain a set of clones with only slightly different configurations and merging from default to each branch become boring
I've read similar posts of SO, the official Hg guide, many articles and guides, and it's still unclear to me what the best Hg workflow is for developing by feature. Maybe some of the articles on the web are years old and don't include the latest features from Hg. Obviously there's also a lot of options in how to approach it.
I'm a solo developer working on a project where a request for a fix or feature will be submitted to me as a task, like "Task #546 - Change whatever". Some of these tasks take a few days, and some tasks are open for months and there's often up to a dozen going at one time. A task is shipped to the final site after it's approved by the requestor.
The Hg guide seems to recommend having a clone per feature. But having a dozen full copies of the site on my drive seems... wasteful? I'm up for trying it, but I've seen other suggestions that make more sense. Do people really have a dozen copies of each site on their dev machine at a time?
Name branches at first sound like what I'd want, where's I'd name a branch "task 546" work on it, then merge it back in when it ships. I see a lot of discussion about the permanence of the names and having so many branches (though they can be closed). Some people seem to care about that and some don't. I don't know Hg enough to know if I care or not, and what the downsides really mean.
Finally, bookmarks seem to be popular with the more recent articles and it would seem that the best way to use them would be to set a bookmark like "task 546" then when you merge it back into the main branch using a commit message that has the task number in it to keep a reference to what was being done in the work. I know you can delete bookmarks, but it's unclear if I'd need to do this after the final merge.
So my thought for a combined approach is to have:
one repo
three named branches:
"default" which holds the released version of the site
"dev" on which I do feature development
"test" which would hold all of the tasks being reviewed by the client
on the "dev" branch I would use bookmarks for each of the tasks that I'm working on, so I'd have a head for each task
My workflow for a task/feature would be to:
Update to the main line of the "dev" named branch
Start a new branch using a bookmark for the task "task #123"
Commit changes until I'm ready for the client to review
Merge "task #123" into the "test" branch
Deploy "test" to the test server
Repeat the commit, merge, deploy until ready for production
When approved, merge with the main line of the "dev" branch with a commit message that includes the task name
Merge "dev" into the "default" branch.
Deploy the "default" branch to the live server
Merge "default" into the open feature branches
Thoughts? Would I be better off just having a clone for each feature, and a "live" and "test" repo that I push to?
Edit: I see from some links that I should be doing the development off of "default" so my first change to my listed process would be to use a name "production" branch instead of a named "dev" branch.
Bookmarks-style of branching (Git-like "branches") works poorly in, at least, two common cases
Cross-tasks merges in the process of development
Time-back machine, when you'll want to see "the whole history of changes for task#123" (you can do it visually and, with some grimaces and jumping, using revsets)
While using named branches haven't such problems and, btw, workflow with named branches (and only default branch as aggregation point) will be less complex and more logical way
Default contain only mergesets from task-branches, head of default is always "stable version"
Heads of named branches are WIP; branches, merged to default - finished (and accepted by customer - see below) work
Default, merged to task-branch (after development of task, before merging task-branch to default) is equivalent of your "test": without affecting mainline you can test final state of feature, integrated into your stable app, show results to customer
Accepted work added to stable mainline by merging named branch to default
History (full history) of changes for every task in the past can be easy restored by using single, easy, short, memorable revset for log: -r "branch(TASK-ID)"
I like it. +1. This is the way I'd do it.
My dev team is just starting out with Mercurial and we're confused on the following point:
We are a php webdev team.
We have 3 developers. Most of what we are doing now is bugfixes on a very new product. Also doing some new feature development.
We have 2 QA people. Every bugfix and feature must be tested before it is allowed to go live.
So far, each developer has his own repository. We have a central sever called WebDev with it's own repo. A developer pulls from WebDev, then makes some changes (ie, fixes a bug), and pushes to Webdev. Then a QA tester will test the code on the central server (so testing on the code in WebDev) and if it works, he will push that code to our production server.
This does not work well, because... what happens when Developer-1 (dev-1) fixes a bug, and pushes to WebDev. At the same time, dev-2 fixes a different bug and pushes to WebDev. the QA person tests the code there, and approves the second bugfix but not the first. How would he push the second changeset to production without the first one as well? We seem to be losing all the advantages of a version control system.
I've read up a lot on branching, but I cannot figure out how to make this work for us... do we create a new branch for every bugfix and new feature, and the only after it is tested, QA will merge into the default branch on WebDev? Is that the best way, or is there something I am missing?
Thanks!!
----UPDATE----
thanks to everyone who answered so far. here is where i am holding now... i can think of two solutions.
1) dev-1 fixes a bug for bug-101. he pulls from webdev, merges and commits locally. he sets it in-testing. QA pulls directly from his repository, and test locally. if it passes, QA will pull from webdev ->merge -> push to webdev (and if its a big change, can review again there to make sure it is fine). so we are only testing one thing at a time, WebDev only contains changes that have been tested locally by the testers and is always stable.
2) create branches for everything. dev-1 creates branch "bugfix-101" then pushes to webdev without merging it. QA can test the branched code, and if it's approved, merge it with the default branch. I have four questions on this method - (a) is it possible to push an open branch to a remote repository? (b) if QA merges and closes the branch on webdev, the next time i pull, will my local repo also close and merge the branch? and (c) how do you test from the branched code? when i run the web app in the browser, how do i test from the branch?? (d) are there performance issues with creating so many named branches (assuming that most of them will get closed quickly)?
Thanks again.
Folow up to Bassam:
Your team is obviously missing the (really easy) branching and merging in Mercurial and working with a monolitic (?) default branch.
Just change your thinking and workflow slightly and you will see a big difference:
Each QA-member has a permanent clone of the repo and only pulls a developer's repo on request (it's faster, pulled changes are more visible); maybe branch QA also have sense
Use a separate branch for each and every big change (feature or bugfix)
When a dev has a changeset X in branch "Bugfix Y" in his repo finished and ready to test, he asks QA to "pull and test changeset X"
QA does that, maybe merges "Bugfix Y" to the "QA" branch in his repo (as a "test passed" sign?) and merges the "QA" branch to mainline ("Stable" or "default" branch), and finally pushes the results to needed destinations (WebDev and Prod?)
On every next request step 4 must n\be repeated
This way you never mix in one approve-cycle more than one development action
This is a good place to use tags. Have either the dev or qa person tag the release containing only the changes they want, and then the qa person can clone the repository at the tag level (or update the repository to the tagged changeset if that fits better for you... your preference). Then do the test using the tagged version of the code.
As a side note, it would be worth looking into these two answers on the Kiln stackexchange site to see Fog Creek's repository strategies (see how they eat their own dog food):
http://kiln.stackexchange.com/questions/354/release-repo-suggestions/355#355
http://kiln.stackexchange.com/questions/500/should-i-use-more-than-one-repository/504#504
Update
There is a good description in this post about why it is better to fix bugs in a stable branch and push them back to dev, while using a dev branch for features (which get pushed back to the stable branch as well... two way pushing/pulling). This is how we do it as well. It is not directly answering your question, but is related enough that I thought I'd include it.
Creating branches with Mercurial is a breeze, use that :) I would create separate branches for different feature and different bugs and have the QA person merge them to the main branch whenever the ensure that a bug is fixed.
Another alternative is to use named branches which is essentially the same thing but instead of seperate branches, your named branches is going side by side with the default branch until they are ready to be merged in.
Note: We have been alternating between both strategies at my work place.
We are looking to move our team (~10 developers) from SVN to mercurial. We are trying to figure out how to manage our workflow. In particular, we are trying to see if creating remote heads is the right solution.
We currently have a very large repository with multiple, related projects. They share a lot of code, but pieces of the project are deployed by different teams (3 teams) independent of other portions of the code-base. So each team is working on concurrent large features.
The way we currently handles this in SVN are branches. Team1 has a branch for Feature1, same deal for the other teams. When Team1 finishes their change, it gets merged into the trunk and deployed out. The other teams follow suite when their project is complete, merging of course.
So my initial thought are using Named Branches for these situations. Team1 makes a Feature1 branch off of the default branch in Hg. Now, here is the question. Should the team PUSH that branch, in it's current/half-state to the repository. This will create a second head in the core repo.
My initial reaction was "NO!" as it seems like a bad idea. Handling multiple heads on our repository just sounds awful, but there are some advantages...
First, the teams want to setup Continuous Integration to build this branch during their development cycle (months long). This will only work if the CI can pull this branch from the repo. This is something we do now with SVN, copy a CI build and change the branch. Easy.
Second, it makes it easier for any team member to jump onto the branch and start working. Without pushing to the core repo, they would have to receive a push from a developer on that team with the changeset information. It is also possible to lose local commits to hardware failure. The chances increase a lot if it's a branch by a single developer who has followed the "don't push until finished" approach.
And lastly is just for ease of use. The developers can easily just commit and push on their branch at any time without consequence (as they do today, in their SVN branches).
Is there a better way to handle this scenario that I may be missing? I just want a veteran's opinion before moving forward with the strategy.
For bug fixes we like the general workflow of Mercurial, anonymous branches that only consist of 1-2 commits. The simplicity is great for those cases.
By the way, I've read this, great article which seems to favor Named branches.
You're definitely thinking about this right, and it sounds like you're going down a good path. I'm a branches as clones person, but named branches have come a long way.
Having a central-ish repo to which all named branches are pushed is convenient for control and backups. Teams working on only branch X can easily create their own branch X only repo by doing hg clone -r X central-ish repo.
The best thing you can do to help the teams out is to let them do clones themselves somewhere that's sitting behind a hgwebdir.cgi instance (as, presumably your central-ish repo will be). You'll find not just teams, but sub-teams and pairs of teams will set up their own repos for mini-efforts you never new about. They'll put them on the named branches that make sense to them and merge back into central as appropriate.
I would make the decision if these three projects should go into one repository by the coupling between these projects (and how many patches are interchanged within them). The more independent they are the less are the advantages of having them in one repo (backup and management aside). There are some different kind of setups:
As you showed, one repository, with one branch for the shared code, and one branch for each project. When the projects itself are generated by forking the shared code base care must be taken when merging back to common (cherry-picking). When inside of each project-branch updates to the common-branch are generated as direct ancestors of the common-branch, and get merges into the project-branch, chances are good they can also be merged back into common. But if changes to common are developed on top of the project branch, merging back will require cherry-picking. I don't have experiences with such a setup, but I fear that the merges can get problematic.
one repo for the shared code and one for each project, connected by symlinks or as subrepo. Here care must be taken to not step on each others feed. In my experience this kind of usage has the potential to grow into a very big PITA. OTOH you seem to have this setup already and your fellow developers can work with it.
one repo for shared and one for each project, with the code from the shared one used as internal releases. I would go for this setup when there are not big regular changes on the shared code base.
All these situations can also be combined with customization-branches for each project within the common part. But I would try to minimize the number of currently active branches, since every new branch requires additional care of merges.
I'm sorry to not give a concrete answer, but "The right thing" (TM) depends to much on the local details.
...so I've gotten used to the simple stuff with Mercurial (add, commit, diff) and found out about the .hgignore file (yay!) and have gotten the hang of creating and switching between branches (branch, update -C).
I have two major questions though:
If I'm in branch "Branch1" and I want to pull in some but not all of the changes from branch "Branch2", how would I do that? Particularly if all the changes are in one subdirectory. (I guess I could just clone the whole repository, then use a directory-merge tool like Beyond Compare to pick&choose my edits. Seems like there ought to be a way to just isolate the changes in one file or one directory, though.)
Switching between branches with update -C seems so easy, I'm wondering why I would bother using clone. I can only think of a few reasons (see below) -- are there some other reasons I'm missing?
a. if I need to act on two versions/branches at once (e.g. do a performance-metric diff)
b. for a backup (clone the repository to a network drive in a physically different location)
c. to do the pick&choose merge like I've mentioned above.
I use clone for:
Short-lived local branches
Cloning to different development machines and servers
The former use is pretty rare for me - mainly when I'm trying an idea I might want to totally abandon. If I want to merge, I'll want to merge ALL the changes. This sort of branching is mainly for tracking different developers' branches so they don't disturb each other. Just to clarify this last point:
I keep working on my changes and pull my fellow devs changes and they pull mine.
When it's convenient for me I'll merge ALL of the changes from one (or all) of these branches into mine.
For feature branches, or longer lived branches, I use named branches which are more comfortably shared between repositories without merging. It also "feels" better when you want to selectively merge.
Basically I look at it this way:
Named branches are for developing different branches or versions of the app
Clones are for managing different contributions to the same version of the app.
That's my take, though really it's a matter of policy.
For question 1, you need to be a little clearer about what you mean by "changes". Which of these do you mean:
"I want to pull some, but not all, of the changesets in a different branch into this one."
"I want to pull the latest version of some, but not all, of the files in a different branch into this one."
If you mean item 1, you should look into the Transplant extension, specifically the idea of cherrypicking a couple of changesets.
If you mean item 2, you would do the following:
Update to the branch you want to pull the changes into.
Use hg revert -r <branch you want to merge> --include <files to update> to change the contents of those files to the way they are on the other branch.
Use hg commit to commit those changes to the branch as a new changeset.
As for question 2, I never use repository clones for branching myself, so I don't know. I use named branches or anonymous branches (sometimes with bookmarks).
I have another option for you to look into: mercurial queues.
The idea is, to have a stack of patches (no commits, "real" patches) ontop of your current working directory. Then, you can add or remove the applied patches, add one, remove it, add another other one, etc. One single patch or a subset of them ends up to be a new "feature" as you probably want to do with branches. After that, you can apply the patch as usual (since it is a change). Branches are probably more useful if you work with somebody else... ?