Basically, I have dev branch, and what I like to do is to create a feature branch while I implement something, and then merge it back. So situations like the following occurs
a
b
c
d - dev
/
e
f - feature
Since dev isn't a head, is it still possible to bring dev up to feature such that both dev and feature are pointing to f?
I'm pretty sure git can do this just fine, but can't seem to convince Mercurial to do the same...
Carl Meyer is right. You're thinking as a git user, and Mercurial handles things differently.
You could do what Carl suggested and just force the next commit to be on the dev branch. I'd personally find this rather confusing if I saw it though, since there would be a discontinuity in the dev branch.
The way I'd handle it is to merge the feature branch back in: hg update dev && hg merge feature && hg commit -m 'Merge in the completed feature.'
This would result in a graph like:
a - dev
b - dev
c - dev
d - dev
/|
e | - feature
f | - feature
\|
g - dev
For me, this clearly illustrates exactly what happened. You branched off for a new feature and merged it into the dev branch when finished. The fact that there were no other commits on dev in the meantime is just a coincidence and doesn't have to change the workflow.
Named branches in hg (unlike in git) don't "point" anywhere. Branch names aren't movable aliases for a particular rev. Each commit has a metadata marker naming the branch that commit is on; that's all.
In this situation, if you have no separate commits descending from "d" on the dev branch, then all you need to do is run "hg branch dev" and then your next commit, descended from "f", will be back on branch dev. Which I think will achieve the results you're looking for.
EDIT: That will work, but Steve Losh's suggestion of doing an actual merge will result in a more sensible history.
Related
I'm fairly new to version control in teams. So far I've mostly used it solo.
I've read that the following workflow is recommended:
Commit locally, pull master, merge master into my branch, merge my
branch into master, push. Several times a week or even day
So that's what I tried to do. However, when I was done with my feature, and tried to push, tortoise hg told me, that this would create new remote heads.
hg help push tells me about two options:
Merge first: Did that
Use -f: I know enough not to do that.
I think I understand the concept of rebasing - which I don't think applies here, since I'm the only one who did anything in this commit tree. Of course I've pulled.
So my question is: How can I resolve this specific situation?
Also, recommendations for where to learn proper version control workflow would be nice. Everything I find tells me what the commands are, but I've failed to find clear instructions on when to use them.
I've added a picture of the project. Commit 147 was mine, and I could push it just fine. All oher commits are also made by me.
hg reports a "head" for every named branch. In your screenshot, you are needing to push rev 154, which is the head of your kjeld branch. It is an outgoing changeset because you are pushing rev 155 and you must therefore push 155's entire history as well. Others will get that branch when they pull your changes and will have a head on their version of kjeld (note that it will most likely not be numbered 154 since those numbers are repo specific). You will be fine though since that head is a close-branch changeset so it will not appear in their default list for hg heads and hg branches.
One way to avoid your current issue is to use bookmarks to temporarily note what that head represents e.g. issue-45, big-feature-2, etc. and only push when merged into mainline development.
For us, we set up a "private" repo for each dev on the server where they store/backup work in progress. It is expected that there are multiple heads, dead branches, and other gunk in these "private" repos. The dev repo, however, only ever has a single head and must pass the build and build tests.
In response to your comment about your "private" branch: When you push your tip you will also push your branch named kjeld. Others who want to work on that code must pull it to get the tip of your development. It will not be a "private" branch.
How do I get a bugfix I made on the default branch into a named branch in mercurial?
I recently started work on a new feature so thought I'd do this work in a branch (which I've not really done before) so I could keep the changes out of the main default branch until I've finished working on them and the feature is ready to deploy. The idea being that I could update to the default branch and apply any bugfixes as needed.
Now I want to get the bugfix into my named branch. The tip (rev 739) has the change I want to incorporate into the BoardSummary branch. I know I could merge but I don't want to bring my BoardSummary changes into the default branch.
I looked at the mercurial: apply a bugfix change from stable named branch to dev branch answer but it didn't make sense to me.
Edit: I'm with it up to "Then you discover that changeset 2 introduced a bug", in my case I went back to 732 fixed the bug and committed (onto the default). The idea being that the fix is in place before I branched. But now how do I get that fix into 738 without merging the 2 branches together? It looks like the bug is actually fixed in 739 - so isn't in the BoardSummary branch yet. This seems to be what the 2nd tree shows in the answer but the 3rd diagram is explained with "you would instead do this" - I don't understand that bit
Evidently, your default branch contains only one changeset not present in the BoardSummary branch. You should merge default into BoardSummary, and not the other way round. This way, BoardSummary will have the fix, and none of the BoardSummary will be in default.
To summarize:
$ hg up BoardSummary
$ hg merge default
$ hg commit -m "Merge the fix for #247"
An explanation
There are a number of kinds of branches which can be employed. The most common are:
stable (production) branches for maintaining the released versions,
default (master, trunk) branch, which contains more or less stable development activity,
feature branches, which are not mature enough to be merged into trunk.
The main idea here is that it is always safe to merge from stable to default, and from default to feature. This means that in terms of changesets, any stable branch is a subset of default, and default is a subset of feature branches.
For instance, you're reworking your data access level in a feature branch new-dal (major feature). At the same time, you've added a couple of new reports in default (minor features), and found and fixed a bug in a 1.0-stable. Well, just merge the branches going from the oldest to the newest (1.0-stable -> default -> new-dal), and that's all.
This is explained very well on the Mercurial wiki: Standard Branching: Release branches.
Your case
In your case, BoardSummary is clearly a feature branch, so you can merge default into it without any hesitation. The opposite should only be done if you're ready to integrate the new feature into default.
At first you should rollback/remove the commit 739 (which is your fix) from the history. Then you commit the fix on r732. This will create a new head and should be the new r739. Your history should look like this:
r329
|
--r232-----default branch
\
\
feature branch
Now you merge your new head (r329) into the default and the feature branch. Now the history should look like the last tree in the linked answer.
My coworker accidentally made two commits in the default branch instead of creating new his own development branch.
How can I change this situation and moves these two commits to a new branch?
Imagine the following scenario:
D
|
C
| "I want to move C and D here"
B/
|
A
Steps:
hg update B
hg branch "mybranch"
hg commit --message "Create my branch"
hg update mybranch
hg graft -r C
hg graft -r D
hg strip -r C (this should be the revision C had originally)
The strip command is provided by an extension that you need to enable. You can follow a guide on how to enable it on the Mercurial Wiki.
hg update default
A major question
Have the accidental commits reached other repositories or is it just in his own? If so, you can skip to the section below 'Maybe the cat is still in the bag' otherwise you may have a fair bit of work to do.
You are not alone
See here for more discussion on how to correct the problem elsewhere on Stack Overflow. What is described is the 'proper' way to to it
export a patch
create the branch
import the patch
delete the earlier commits.
Maybe the cat is still in the bag
If the changes are only in the local copy, then a simpler solution is to
create the new branch
switch to it
merge the changes onto that either with your fav merge tool (go Meld) or with hg graft
use the hg strip command to delete the changes on the old brach
push the changes to the world
pretend like nothing ever happened, whistle a happy tune ...
The two answers above are both correct but, assuming one has not yet pushed the commits, there's a third way.
I just successfully used the rebase command to move a string of commits to a topic branch I had forgotten to create in the first place.
I first updated to the revision from which I wanted to create the branch on which my commmits were supposed to be, then I rebased the earliest of my commits from the wrong branch on this new one and ta-da, done.
Takes more time to explain it than to do it with TortoiseHg or even the command line, really.
I have a small team and I would like to do the following:
I have my trunk, I'll just call it TRUNK
Now, TRUNK is a project that's already in production and running. Now, the inevitable defects come in, but into bugzilla and are assigned to users.
Each user clones TRUNK to their local repositories and makes changes and pushes them to a directory TRUNK/projects (projects is not a clone of TRUNK, just a regular directory)
Now, the day comes where I want to create a new build called RELEASE and I want to merge some of the bug fixes (not all, just some) into RELEASE.
Notice, I am not committed to the idea of having TRUNK/projects/[bugfixes list], but that's what I currently have now and am more than open to any / all suggestions.
What are some ideas? Is there something I can do / should do differently? Again, I am open to any / all suggestions, including completely changing the above procedure (except for using Mercurial as that's what the company makes us use)
There are two ways to do this and they diverge not at release time, but when you do the bug fixes depending on what parent you give the bugfix changesets. The "good" way uses only push, pull, and merge. The less good way (it's not entirely bad, but it's certainly sub-optimal) is called cherry picking and it has drawbacks. The tricky part is that whether or not you're going to be able to move bugfixes into RELEASE via merge without moving everything from TRUNK into RELEASE is something you have to decide before you make that change.
Here's a really complete answer for a similar question that explains what's going on: Some help with merging legacy branch in Mercurial
The key concept though, is that you can merge a changeset into any branch you want but it brings with it all of its ancestor changesets. So you want your bug fixed to have minimal ancestry. That means fixing a bug not in a new changeset in TRUNK that happens to be the latest feature you added, but instead, first, hg updateing to a changeset that already exists in both your TRUNK and your RELEASE, and there are two great candidates for that. Either:
the changeset where RELEASE and TRUNK diverged
or
the changeset where the bug was introduced
My preference is for the later. If a bug was introduced in changeset 666 then every clone, branch, and build that has changeset 666 will want your fix. So when fixing it just do:
hg update 666
.. fix the bug ..
hg commit -m "fixed bug 55" # creats changeset 999 which a new head
Then you can do this:
hg update TRUNK
hg merge 999
and you'll know you're only pulling in a single changeset. Later when you're ready to release you can do:
hg update RELEASE
hg merge 999
and you're again only getting the single changeset you want.
The advantage of this mode of working over cherrypicking (using export/import or transplant) is that your fix exists only once in your repo. If you have 99 different vendor branches for various finicky customers and you want to see if they have the fix for bug 55 you can just do:
hg log -r 'descendants(999) and heads(FUSSYCUSTOMERBRANCHNAME)'
and if there are no results then that customer doesn't have 999 and thus doesn't have the fix for bug 55 in changeset 666. When you re-do the same work with multiple changesets (which is the result of export/import and transplant) that's harder to verify.
Common practice is to create topic branches.
Each new issue/ticket/enhancement is commited into separate branch.
Anytime maintainer wants to make new release he can merge all (or only some) that branches into "default" or even new branch called e.g. "release_1_x".
To be more precise. Developer working on code can still clone repository, then create local branch and finally, after one or more commits to that branch, pushes local changes to one centralized clone (from which every other developer in team can pull/clone again).
Is there a way to remove a from a remote changeset, or to remove an entire changeset?
I accidentely pushed a .war file to a remote repo and I want to remove it.
Mercurial tries very hard to keep your data safe, so you can generally not change history.
That being said, there are numerous extensions for Mercurial that allows you to quite easily change history anyway. There is a page on the wiki about editing history. That page also explains the consequences.
In your specific case, you have to ask yourself if others will have already pulled your changeset? If so, then even if you remove it, it will still exist in their clones and you might be better off with accepting the mistake.
If you decide to remove it, I suggest using hg clone to get a copy without it. This is the safe way since it will always leave behind a backup. If you pushed [z] to the remote repository:
[x] --- [y] --- [z]
and now want to remove it, then log into the server and do
hg clone -r y repo repo-without-z
Then repo-without-z will contain all changests up till [y] — that is, [z] will have been removed:
[x] --- [y]
You can then continue working and push a new changeset:
[x] --- [y] --- [w]
If I had pulled the [z] changeset already and now pull [w] I will see two heads in the repository:
[w]
/
[x] --- [y] --- [z]
This is not dangerous per se -- but people might be surprised. If I remove [z] from my clone I will end up with the same repository as you. But, as wrote above, this might be impractical if you have many users.
You can also use the MQ extension to strip the changeset away in-place. That way you wont make a new clone.
Finally, if you're certain that the push was the very last operation done on the server, then hg rollback can be used to remove the last transaction. But don't do this if you are the only one who can push to the repository, otherwise you might end up rolling back a different transaction.
If the repository is on Bitbucket, then you cannot log into the server. But Bitbucket has recently added a strip functionality to its web interface. Look for "Repository management" in the "Admin" section.
Bitbucket does offer you a bundle (backup) upon stripping, and this does not count against your quota. The reason why it appears to do so, is only because we haven't invalidated the cache key specifying how much space you use.
This is a bug in our system, and will be remedied. Until then, rest assured that the changeset has been removed, and the backup is free :-)
I used hg mqueue extension to edit history. It seems that it worked.
Thanks all.
I had a similar case where i want to remove a merged branch "A" changeset from "Dev" branch remotely using TortoiseHg:
Create branch AA from branch A's parent branch; its origin.
Merge A into AA (working directory) and make sure that option: "Discard all changes from the other revision" is checked.
Merge AA into Dev branch (with a commit message indicating that branch A changes were removed).
You'll see that branch A changes are no longer exist in Dev.