Leave the branch head behind in Mercurial?
I have a local repository just for me (no remotes) for tracking changes to a website. The website has a staging server and a live server, and the branching methodology I'd like to use is to have a named "live" branch that is the literal representation of the state of the live server (live server could clone the head of that branch and should have no changes). Current development changes as side branches off of 'live' (named for long projects, unnamed (technically also 'live') for short projects), and 'live' merges them back in when they're ready to move off the staging server. So the ideal branching I'd like is something like:
--A---------E------------L----------O-- live
\ / \ / \ /
B--C--D F--I--J--K \ / minor features
\ \ /
G--H---------M--N major feature
However, If I have my working directory up开发者_Python百科dated to revision A (on branch 'live'), and I want to start a new minor project, how do I branch to B?
I can create a new branch name, and then commit on top of A (which leaves the head of 'live' at A, and creates a new branch/head at B), do my work, and then merge the two branches to create the A-E that I want, but now there's a named branch that I need to close. And if I'm creating many smaller features, I need unique names for them all, since "closed" branches are still really there and claiming their name, just marked inactive.
If I just commit B on top of A without a new branch name, the "tip" and "live" tags move up to revision B, and A is no longer a head (meaning after C and D are created, it can't merge with D to make E). Plus, if I clone the head of 'live', it's not representing the live server (which is back at A).
--A--B--C--D live
After creating B, I could update my working directory to A and do a no-changes commit, which would create a new head, but that means I'd have to do a useless commit on my live branch every time I started a new feature.
--A--A' live
\
B--C
So is there a way to submit a commit as a new, unnamed, head in Mercurial?
The problem you're facing is that you don't want to do named branches for short-lived things, but since you're doing the off of the live
branch, there isn't much to see which head on the live
branch is actually the correct representation of live
.
I think this would be solved by having 2 main branches: one represents development, and one represents released code. In your case, instead of branches default
and stable
, you'd probably have default
and live
.
All your major features would be named branches based on default
, and your minor features would just be anonymous branches on default
. You can have however much development in-progress as you want on default
, and it won't change anything when you clone from the tip
of live
to update the live server.
- When one of your major feature is done, you merge that to your main branch on
default
. - When there is stuff on
default
that is ready to be released, you merge it over tolive
, as selectively as you want to.
Because you don't want to use named branches for minor features, you may want to keep track of which changesets/heads of default
represent minor features in-progress and which changeset/head represents development that's finished. For that, I recommend bookmarks.
Another possibility
Bookmarks would also allow you to have a bookmark called livetip
at A, then create a bookmark myMinorFeature
at the same and do changes and commit B, C, and D. The default behavior would be such that livetip
and myMinorFeature
would move to B, then C, then D, but you can change it so that only the current bookmark follows by adding this to your .hgrc
/Mercurial.ini
:
[bookmarks]
track.current = True
As you pointed out, hg will not merge D and A, but give a "nothing to merge" message, even with the bookmarks. Once myMinorFeature
were ready for the live server, you would need to move the livetip
bookmark yourself up to where myMinorFeature
is.
You could also tag whichever changeset you wanted to be cloned for the live server, though you have to manually move that every time.
精彩评论