Mercurial hg, am I doing it right? - version-control

We are in the process of converting from CVS to Mercurial hg.
Our infrastructure is Windows 2003/IIS6
Each developer develop on their machine
1xDevelopement server
1xStaging server
Production environment
Here's what I have done so far:
Installed Mercurial on my machine, on the development server and on the staging server.
Created a repository on the dev. server.
Imported our CVS repository in there.
Cloned that repository to my local machine.
Cloned that repository to our staging server.
For development in the past we always shared 1 branch, not ideal but merging was such a pain that we never bothered and dealt with it.
Now if I understand correctly, we should be doing this:
Local:
hg branch myfeature1 //Start work on feature1
Urgent bugfix required, using the affecting the SAME files as our feature
hg update default
hg branch bugfix1 //fix bug
hg commit --rev bugfix1 //done fixing bug we commit
hg push --rev bugfix1 -f //-f seems odd here, forcing to create a new branch
hg update feature1 //we return to work on feature1
hg commit --rev feature1 //done work commit
hg push --rev feature1
DEV
hg branches //we see the bugfix and feature1
hg merge --rev bugfix1
hg commit //commiting bugfix1
hg merge --rev feature1
hg commit //commiting feature1 //Dev master is now our main trunk ready for a new developer containing the feature1 and bugfix1.
Staging (The QA needs to signoff on that important bugfix before testing feature1
hg incoming //we see the new stuff
hg pull --rev bugfix1
hg merge --rev bugfix1
hg commit
//QA test and signoff bugfix1 we clone to a production repo and sync.
//QA can now test feature1 which we finished some days after bugfix1
hg pull --rev feature1
hg merge --rev feature1
hg commit //commiting merge feature1
//QA test feature1 and signoff
We clone to a production repo and sync.
Does this way make sense? Am I complicating things and will it bite me in the ass later?

It looks like you've got the concepts down great, but you've got some oddities and some questions in there, I'll hit them as a list below:
commit doesn't take a --rev option. It commits the current working directory as a new changeset whose parent (or parents if it's a merge) is whatever hg parents returns, which is always whatever you last hg updateed to.
your hg push --rev bugfix1 -f won't require a -f in very new (1.5+) versions of mercurial. Historically the warning "you're creating a new head" usually meant you forgot to merge, but now if the new head is a new named branch the warning is suppressed.
If I were your person doing the emergency bug fix on my local machine I'd just create a new clone and do the branch and fix in there. If you set up your webserver/webapp config to support that you can allow new instances at new path locations easily/automatically
In your staging environment, I recognize the desire to have them test the bugfix independent of the feature and that's a good idea, your QA team shouldn't be merging. Make/let the developers merge and have the QA team pull the merge revisions into their working area. For example, the developer changeset created in DEV step 3 already provides the proper integration of the bugfix and what-used-to-be, so have the QA team pull that revision, which will be on the 'default' branch. Similarly, after QA has approved the bugfix and is ready to move on to the feature, have them pull from dev the changeset created in dev step 5.
Remember, merging is coding too -- the person doing the merge is making choices about what should and shouldn't be. The QA people might be capable of it, but it's the developer's job. Also, why do it twice? The usual handoff for this is something like "QA, pull revision 897a9d9f9a7 and test please -- the developers". If you want to get fancy you can have a tag like 'readyforQA' that the developers move along the 'default' branch as they go (in this example they'd hg tag after their steps 3 and 5 and let QA know there's new stuff to pull.
The one piece of advice I'd give you is don't try to over-engineer the process. DVCSs lead to a sort-of haphazard way of working, that's a little scary at first, but tends to work out. YOu'll find sub-teams and pairs of folks have clones you never knew about and in the end so long as you have a few firm rules like "nothing goes to production without first passing through QA" the rest sort of works itself out.

Related

How can I specify commits for pull request on Bitbucket?

I have a mercurial repository on Bitbucket that is forked from another repo. I made several commits to my fork and now want to make pull-request to the main repo.
But I want to include in pull-request only last 2 commits, not all that I have done as Bitbucket offer. Is it possible to do pull-request through Bitbaket, which includes only those commits that I want?
On a pull or push, you can specify a revision, but it necessarily comes with all its ancestors that are not on the repo. If you planned it correctly, and the last two commits are the sole constituents of a separate branch, started from the main trunk, yes, only those 2 commits should be pulled. But from your question, I doubt this is the case.
In Bitbucket, it seems to be possible to request a pull on a branch. So my suggestion is to create another branch, started from the main trunk, and replicate your last 2 commits. There are many ways to do that, but the fastest, albeit not recommended in a normal workflow, but considering your current state, is to graft the 2 commits on that new branch.
hg update default
hg branch <new feature branch>
hg graft -r <commit 1>
hg graft -r <commit 2>
Then, request a pull on <new feature branch>.

How should I structure my git-svn workflow to avoid "revision1 is merged into revision2, but does not have git-svn metadata"

I am using git-svn in my workplace since our current version control server is subversion and switching completely to git does not seem to be on the horizon for now (*cry*)
My workflow is as follows
I have the following branches
master tracks remotes/trunk
local/0.4 tracks remotes/0.4
work is my development branch for the master branch
work-0.4 is my development branch for the local/0.4 branch
I work in my work branches, then I merge to master and local/0.4 using
git merge --no-ff <branchname>
After that I check in to svn via
git svn dcommit
and I use
svn.pushmergeinfo=true
to update the svn:mergeinfo properties so my colleagues won't get angry with me messing up that metadata for them :)
However, I just had the following problem which stumps me.
I had done two commits on the work-0.4 branch, then I merged these to my local/0.4 branch with git merge --no-ff work-0.4. After this, I did git svn dcommit and recieved the following message
Committing to https://svn-server ...
e138050f6ebd2f2ca99cbefc5e48acae412e1f86 is merged into revision f5f2345e8e5fc64
20423bdc00397b5853b3759c4, but does not have git-svn metadata. Either dcommit the
branch or use a local cherry-pick, FF merge, or rebase instead of
an explicit merge commit.
After some rebasing and reset'ing of branches I managed to push everything to svn, but my solution entailed doing a rebase of my local/0.4 branch to the work-0.4 branch which in turn meant that I did not get to squash my two git-commits into one svn-commit :/
I feel that I'm probably doing something wrong with my workflow here, and it might be related to svn.pushmergeinfo. The docs for svn.pushmergeinfo says
config key: svn.pushmergeinfo
+
This option will cause git-svn to attempt to automatically populate the
svn:mergeinfo property in the SVN repository when possible. Currently, this can
only be done when dcommitting non-fast-forward merges where all parents but the
first have already been pushed into SVN.
and to be honest, I'm not quite sure that I understand that correctly? Am I doing something weird here that makes svn.pushmergeinfo not work correctly? How should I structure my workflow to optimally work with git-svn correctly (setting proper mergeinfos etc)?

Git-SVN: how can i merge branch to trunk?

I am working on a git-svn project with two branches, lets call them
trunk
branches/foo
How can i merge branches/foo to trunk?
they both have the latest update
Thanks
It is inadvisable to merge two SVN branches via Git. If in Git you merge from your branches/foo clone to your trunk clone and then managed to successfully push back to SVN, the files would be correctly updated on trunk, but SVN wouldn't be aware that it's the result of a merge - no merge-tracking information will be updated in SVN.
In fact it gets more complicated than that - when you merge between two Git branches that are both tracking remote SVN repos, git-svn can get really confused and it's very easy to mess up your repository. This is because git-svn looks back through your Git log to find the SVN tracking information, and if it finds a merge then it won't necessarily head down the branch you expect. So even if you've merged from branches/foo into trunk and you're now on trunk, it's possible that a dcommit would push back to branches/foo.
Better to switch back to your regular SVN tools to do merges and just use git-svn for development.
Another roof option could be next:
checkout your trunk branch # git checkout -b trunk git-svn-trunk
and cherry-pick dev commits into trunk branch,
i prefer pick one by one and solve conflict slowly
after that you have a 2 branches with the same commits
maybe do you want remove dev branch and create a new dev branch from trunk branch,
now this branch (new dev branch) has a correct git-svn reference to your svn trunk...
keep recommendations write by #simonp answer
i hope this help to you

Bazaar: Merge bubble in mainline after pull - merge - commit

I'm new to Bazaar, coming to it from a background of Subversion and git. I thought I had a working grasp of some basic concepts, but have already hit a stumbling block in my first major commit.
The project is hosted on Launchpad. I created a local branch ("working") with bzr branch. I made changes, added new files, renamed others. In the interim another person on the team committed and pushed their changes. At this point the commit history looked something like this:
3. Team Member A
2. Me (trivial commit of .bzrignore)
1. Original commit
This morning I bzr commit my changes locally. The commit number was reported as 3, which I assumed (wrongly) would be reconciled when I sync'd with the server. When I did a bzr pull I got this message:
Using saved parent location: bzr+ssh://bazaar.launchpad.net/...
bzr: ERROR: These branches have diverged. Use the missing command to see how.
Use the merge command to reconcile them.
I did bzr merge. No conflicts were discovered but three files were left as modified in my local branch. I inspected and committed those with a comment, which was reported to me as commit 4. Then I did a bzr push, which reported no errors.
Now the commit history (bzr log --include-merges) looks like this:
4. My merge commit
2.1.1 Team Member A
3. My commit this morning
2. My .bzrignore commit
1. Original commit
There's a high desire here to keep the trunk line serialized and avoid these merge bubbles. (Annoyingly, Launchpad doesn't display the 2.1.1 commit, making it look like I overwrote it.) What is the best workflow in this situation to avoid these bubbles? Should I have pulled first? I'm wary of having to merge other people's code into my local uncommitted changes.
In addition, although rebase is commonly used in git, it appears it's not generally approved of in the Bazaar world. If we can avoid using the bzr-rebase plugin, that would be great.
One way to have a cleaner mainline history would be to do your work in a separate feature branch, while maintaining a mirror of the mainline branch. I'm assuming branches with working trees here, but you could use treeless branches and a checkout to save disk space.
// setup the mirror branch
cd <mirror directory>
bzr pull <mainline>
// setup a feature branch
cd <feature directory>
bzr branch <mirror directory> .
// work on your feature branch
bzr commit -m "Did some work"
...
bzr commit -m "Did some more work"
// ready to commit your feature
cd <mirror directory>
bzr pull
bzr merge <feature directory>
// your integration testing is done
bzr commit -m "My shiny feature"
bzr push

How to develop on a branch in HG?

I would like to do some experimental work in a hg project. So I would like to create branch, commit to it. And if the experiment works, I can merge it back to main branch.
In git, I can do
$ git branch experimental
$ git checkout experimental
(edit file)
$ git commit -a
$ git checkout master
I've read A Guide to Branching in Mercurial. It said hg branch feature. But what is next?
I don't follow.
$ hg branch experimental
(edit file)
$ hg commit
$ hg update default
First note that git branch is different from hg branch. Branches created with hg branch are permanent and live in a global name space, whereas branches made with git branch are transient. The nearest equivalent of git branch is hg bookmark: bookmarks can be renamed and deleted and behave more like Git-branches.
I've recently written a guide for Mercurial bookmarks. Compare this with the named branch guide. Both guides contain worked examples of how to use (named) branches in Mercurial for keeping track of the development. It shows how to merge branches and how to close them or delete the bookmark when you are done.
If it's not a big feature (i.e. the branch doesn't have to have a name), it's quite simple.
Let's say your repository is at changeset X. You work on the feature as much as you like, commit, commit, commit and if you're happy with the result, continue as if you knew it would work all along. ;) If you aren't happy, do a hg update X and continue development from there. All the work you did on your experiment will become an anonymous branch.
Strangely enough, it appears that Git doesn't provide such a way to work with anonymous branches which is what might be confusing you.