I'm new to mercurial, so may be my question is stupid.
Let say you made a mistake when you first started working on your code. For example, you putted
<!html DOCTYPE>
instead of
<!DOCTYPE html>
Now you want to change this, but not only to the latest revision, but to all revisions and versions of your page. Is this possible?
Omar, mercurial is about an immutable, historical record of you work. You can/should fix your error in all the heads, but it stays in history forever like a scientist's logbook.
There are plenty of ways to go about Editing History including histedit, convert, mercurial queues, and import/export/transplant, but none of them a strictly speaking Mercurial as it should be used, and all of them alter the hashids for all subsequent changesets which breaks the clones of anyone else working on the project.
Short answer: If at all possible make your peace with keeping the old data in history and correct it in a new revision.
Related
I had some code changes that I accidentally pushed to the team repo and as such I created extra heads.
Usually I keep those changes in my own repo but I just forgot to refer to the changeset to push and ended up with extra heads.
To solve this problem I used the tip in How to merge to get rid of head with Mercurial command line, like I can do with TortoiseHg?
Works great to me, in fact I am quite happy with the fact that this way my changes are not lost at all and that team members don't have to strip any files in their repo. As matter of fact even though this head is not used, I might want to refer to it in the future and do take some of those changes.
Now after I did this change I got a reaction from a colleque who is our mercurial expert as follows : [begin quote]
The main issue now will be that everyone also in MS will have have these changesets, will see merge ‘arrows’, will see this in history despite that it is not included. Also the ‘merge’ commit does not mention at all that this is a dummy merge. So in case you add other heads that later on have to be dummy merged, please clearly comment this in the next merge commits to clarify this is the case.
Also the adding and removing and changing files, can become a problem now. I am not sure if this will be the case now due to the dummy merge, it might optimize that these files were not impacted, this will have to be tested.
[end quote]
my reaction is that a dummy merge is easily seen, if you select it in TortoiseHg, you just don't see any changes. A commit message 'dummy merge' is probably a good idea. So that point is taken.
The fact that my changes are seen by everybody, is hardly a problem for me, on the contrary this way they are kept and are a future reference. I don't see the problem here.
But the last bullet in bold about the adding removing and changing files ? Can this really be a problem in mercurial? Is this not the essence of using a versioning system in the first place ? What should I test, like he seems to suggest ?
Is his comment correct ?
Your friend's fears are unfounded. He or she is right that a good detailed comment is always appreciated, but there's no pain coming in the future.
When the Evolve mechanism graduates from experimental extension to core functionality it will offer an even better solution. You'll strip the changeset, but it won't actually be removed (as strip does now). Instead it'll be marked obsolete and folks pulling will get it and the "obsolete" marker saying not to show it in normal usage.
I've somehow marked a bunch of files as being "copy/renamed" instead of just marking them as new files.
I've also published these changes to our central repository and can cannot strip them out (we've already got some changes on top and I don't have the permissions/ability to fiddle with the central repository anyway).
Context:
I've actually done it to a whole bunch of files, but here's an example of what I did to one: I've copied a file called "Labels.properties", to a new file called "Labels_ja.properties" (the new file contains a subset of the original properties, and eventually all the values will be translated to a different language). The "Labels_ja.properties" file has been marked as a copy/rename of "Labels.properties" (the only way I've been able to see exactly what's happened is by looking with SourceTree, which shows "File copied/renamed from Labels.properties").
Our environment is a sort of central repository with automated "pull request" style merging tools built on top, so solutions involving all our developers magically knowing exactly how to drive Hg in order to resolve these conflicts aren't going to work - it's the scripts that are getting the merge conflicts.
These copy/renames are causing a lot of hassles: when people touch the original versions of the property files (they don't even know about the copied files yet) - it looks like Hg is trying to merge those changes onto the copies, but because the files are very different, those merges are failing with conflicts.
Problem:
What can I do to sort out all these merge conflicts that our automated merge scripts are getting?
Ideally, I'd like to go back in time and just mark all these files "new" - but there's no going back now that the changesets have been published.
Can I just make a big backout commit, then re-add the files (making sure that they are marked "new" and not "copy/renamed")?
I cannot think of a good solution. Even if you delete the files, Mercurial will still complain repeatedly when they get changed and merged. The simplest solution I can think of is moving the bad files into some "attic" directory where they don't hurt anyone and never touching them again. Then add the real files where they belong.
If I understand correctly, the problem is in fact that the developers are still based on a revision that does not have your move.
When they change the original file, an 'hg merge' will then smash together the changes from the developer and the changes to the new file in that new file.
I see a few solutions for this:
You can tell the developers to rebase their changes on top of the new changes. This will actually not work, since rebase will make the same mistake as merge.
The developers can turn their changes into patches and apply their patches on top of your changes. Their patches will refer to the original files, not the changed files, so this should work fine for the tools that merge later on.
The above flow can be done in a more sophisticated way using Mercurial Queues: import the existing developer commits as patches, then qpop all of these, update to your newer revision and qpush all of the revisions again.
Mark the head with your changes as 'closed' using '--close-branch'. However, if your tools are not equipped to handle this correctly (by ignoring the closed branch), this may cause issues. Branches are reopened when a new commit is done on top of the branch. So if you merge developer changes with the closed branch, it will open again.
Trying to migrate a repository from cvs to hg, I found the tool cvs2hg, and it seems to do nicely he job (conversion goes fine, and I have all the tags and branches).
However, the hg documentation warns about "fixup commits" making the repository somewhat corrupted or at least dangerous.
Is this still a problem ? Maybe hg or cvs2hg have benefited from fixes since this warning was written.
If it is, potentially, how can I check if I am in such a dangerous situation, on the resulting hg repository ?
Fixup commits are good and necessary. And cvs2hg does much better job than hg convert.
But maybe first about the problem. In CVS repository you can play various dirty tricks with tags and branches. For example, you can manually fine-tune some tag tagging today's version of 3 files, yesterday's version of 4 others, and month-long version of yet another. In practice, I did it a lot of times to make "patch tags" (there is some old tag, I have various commits afterwards, there turns out to be a bug, I fix the bug, make fixup tag by old tag, moving it on 1-2 files).
In the result, you get tag which points to release which naver has existed or will exist at any point of repository history, if the history is taken for whole repo.
Similar tricks could be made with branches. Or branches can start from "ugly" tag.
Any kind of „natural” conversion of CVS to HG is dead lost on such cases. There is no place in the time-based history at which such tag or branch could be hooked. And hg convert just binds such tags at more-or-less random places, and branches at very ugly places.
Fixup commits simply are those missing revisions: artificial commits which are bound at appropriate place and introduce changes which put repository at state at which it should be at given tag. With those, we get both "artificial" tags, and branches, properly bound to proper code.
So if you:
commited a.c(1.1), b.c(1.1) and c.c(1.1)
commited a.c(1.2), b.c(1.2)
commited c.c(1.2)
artificially created tag blah_1.0 which points to a.c(1.1), b.c(1.1) and c.c(1.2)
commited a.c(1.3), b.c(1.3)
...
then hg convert based history will have 4 edit changesets (just like those above) and blah_1.0 bound at some ugly place with wrong content. At the same time, cvs2hg will create "fixup commit" which will artificially create changeset at which we really have a.c(1.1), b.c(1.1) and c.c(1.2), and tag there. In a history, such changeset is reasonably similar to transplanted/grafted/cherry-picked commit.
You should carefully check the resulting repository to make sure it represents your code history and doesn't contain any of these crappy fixup commits.
BTW, it might be worthwhile to check out the newer http://www.catb.org/esr/reposurgeon/ tool.
I have recently cloned an HG repository into another one, since the project had to be slightly changed and i couldn't keep it with the other codebase.
Some changes though are common, and so needed to be updated in the older repository as well.
How can this be done?
I'd like to know more specifically:
Are changes that are not group together in a commit (sporadic changes i've made to code files) can be somehow grouped together and updated in the 1st repository (the one i cloned from).
If not, how can this be done if i make all changes grouped in the same commit?
Other recommendations for strategies for handling such cases will be great!
Thanks
What problem are you seeing exactly? What have you tried?
Can you clarify the issue, it seems like you are just looking for a way to pull from another repo, in which case:
hg pull -r {RevisionYouWantFromOtherRepo} {pathToSecondRepository}
The problem that I'm running into is that I have some code reviews to do, with ~10 commits per review. It's an active repo with constant commits from developers. I have TortoiseHg filtering my changesets so that I am looking only at the ones that I care about.
What I would like to see is the difference between the changeset before the first change, and the last (without all the non-related changesets showing). I simply want to see the final results of all these changes. I don't care that there was some horrible code in changeset 1, that was fixed in 3. I just want to see the diff of what ultimately got merged through all these changesets.
I feel like I'm missing the obvious, and this isn't a bright question. Nevertheless, I'm asking anyways. Anyone?
I'm not sure about 1.1.8, as I'm using the 1.9/2.0 candidate release, but I believe you could left-click on changeset1, right-click on revision3 and select visual Diff. This should open your diff tool of choice and only show you the diffs between the 2 versions.
When I did this in the newer tortoise, it opened BeyondCompare in directory compare mode, with revision1 on one side, and revision2 on the other.
Don't merge in between commits and diff off the developers clone between start and finish changesets.
Or If merges occured, update and merge everything and then take the entire codebase (or just changed files) and dump it onto a clean tip clone (make sure you are working with the same version to avoid overwriting anything). Recommit all at once.