How to deal with committer name change in Mercurial - version-control

I have a project in Mercurial with a group of committers. Unfortunately, some of the committers has changed names several times, e.g. first it was "nickname", and then it became "Name Surname ", and then something else.
Most of the repository analysis tools expect committer to have same name over the course of the project, so ideally I'd like to rename committers of previous revisions in our main repository and have everyone make a fresh clone. Is it possible?
Are there any other ways to deal with this problem?

Yes, it's possible. Use the Convert extension and then hg convert from the repository with the bad names to the new repository with the good names and use an authormap. There are many things you can accomplish using the convert extension and converting from Mercurial to another Mercurial repo.
Authormap file, supposing Eric Hopper <bumpy#bar.com> is the canonical name for the author:
Eric Hopper <bouncy#foo.com>=Eric Hopper <bumpy#bar.com>
Eric M. Hopper <bouncy#foo.com>=Eric Hopper <bumpy#bar.com>
Eric Hopper <bouncy#baz.com>=Eric Hopper <bumpy#bar.com>
Then:
hg convert -s hg -d hg --authormap authormap badnamesrepo goodnamesrepo
Note: that while converting an hg to an hg repository will not always create lots of new changesets, in this case it will, and they will be equivalent to (but different from) changesets in the original repository. This means that everybody using this repository is going to have to erase any clones they have and fetch new ones.
In the general case, converting an hg repository to an hg repository is likely to create at least a few new changesets or there wouldn't be a reason to do it. And that will almost certainly necessitate everybody destroying all their clones and re-cloning.
If your analysis tool has the ability to remap author names, that's probably the better way to go. But that's not what you asked for, so I gave you the answer you asked for. :-)

Related

How does Bazaar handle file renaming?

I was curious to know more about how different version control systems track renaming files in a repository, especially in the case of a merge. On this question, comparing Git, SVN and Mercurial's strategies for file renaming, someone posted this blog post from an author claiming that Bazaar's file rename strategy is much more robust than any other VCS. The author states that Bazaar "treats renames as a first class operation".
What the author didn't explain was how this works, what it means to treat renames as a first class operation, and why its strategy is better than, e.g. Git's "best guess" rename detection algorithm.
I have no experience of Bazaar, but I'd like to know:
How does it handle file renaming?
What makes its algorithm more reliable than other popular VCS (if anything)?
I couldn't find this information easily from Bazaar's own docs.
Preface
Bzr is dead
Text without facts from 2007 is just a piece of shit
Face
In bzr or hg, you have two things: the fileobject (doesn’t change across rename) and the filename (change across rename). Both applications are keeping this information, but the difference is in the implementation. The primary storage of a fileobject in hg depends of the filename (with a pointer to the previous fileobject if the previous fileobject doesn’t have the same filename, that is the couple (filename, revision)). In bzr the fileobject is stored directly on disk.
Source: https://www.markshuttleworth.com/archives/123#comment-110483
Answers
Bzr record(ed) renames at repo as single transaction "rename", in hg it's (still) "remove"+"add", also recorded in revlog and give the same result: traceability of the whole history of every object)
In 2022 Bzr's rename isn't "more reliable" than Hg, but better Git's guessing (just because every guessing instead of recorded event may be wrong in edge cases)
Resume
In 2022 you haven't reasons to prefer Bzr (or its successor Breezy) or Darcs or Pijul over Hg pure due to rename possibilities

Fossil SCM - Revert to a specific revision like Mercurial

While using Mercurial if I want to change the current working copy with a specific revision I just do:
$> hg revert good_revision
$> hg commit -m "Now I'm in the good revision"
Then I can see that all my files are int the good_revision state and can start working on it.
So far on fossil I can do a revert but only on specific files, not the entire repository, and update or checkout don't seem to work as I would expect.
How can fossil revert my entire repository to a certain revision?
I'm not sure I quite follow but I think what you want is to be able to create a "multiple heads on one branch" sutuation in Fossil. If yes, then Fossil does support this, just it calls branch's heads "leaves", and this process is called "forking".
To do that, you
fossil update good_revision
and then
fossil commit --allow-fork
You may now spawn fossil ui, navigate to your branch and see it having two leaves.
You now may close the then-current leaf.
Note that, while supported, this does not appear to be a recommended practice. Instead, Fossil recommends a rather peculiar approach for throwing away changes:
Rename the branch at the "bad" leaf to "mistake" (or create that branch if it doesn't yet exist). By doing this you effectively "mark" the resulting subleaf as a mistake.
Note that the name "mistake" name is just a convention; this branch does not exist in a freshly created repository.
Close the "bad" leaf.
Return to the last-good state using fossil update, continue hacking.
Since that "last-good" commit still inherits the branch tag of its parent commit, the next commit you record will also inherit it and won't be on the branch "mistake".
For an example, see how it looks in the SQLite repo—there's a bunch of assorted short chains of commits on this branch. See also this.
My slightly different solution to what I think I understand the question to be (paraphrased: how to work on an older "good_revision" than current leaf of this branch/trunk that I'll call bad_leaf, and treat changes since "good_revision" as bad), which is sort of equivalent to applying diffs between the two versions but in reverse from/to order:
Merge in a (empty) fork from the good_revision, using the baseline from the bad_leaf instead of the default, last common commit; hence the diffs that will be applied are the original branch's differences back to a good_revision fork you create as it won't see they've already been applied. Using the latest as baseline "hides" those which would otherwise make it ignore all changes as they're already applied.
fossil update good_revision
fossil commit --allow-fork --allow-empty
# note the uuid from that commit (for use as forked_basis below)
fossil merge -f --integrate --baseline bad_leaf forked_basis
Then of course once happy,
fossil commit
It doesn't create any branches that should be called "mistake", it just applies the reverse diffs from good_revision to bad_leaf into bad_leaf to put you back where you were and you can continue committing to that same (new) leaf that used to be at bad_leaf.
A diff (straight gnu, not fossil diff) against a checkout at the original good_revision compared to a checkout after the above commands matched. Except for empty directories that had lost their files, but fossil doesn't track/tidy-up dead directories anyway.
caveat: I haven't been using fossil that long and its different in several ways to the common ways I've been used to with cvs/svn/git/hg/ perforce/clearcase.
Reason for adding this answer: I found the existing answers harder to understand and wasn't sure I trusted myself to do them correctly as a result.
If I understand your question correctly, there was a problem somewhere along the development cycle and you would now like to go back one or more revisions to a known good revision and start using that. Furthermore, you'd like that revision to become your trunk. The approach in Fossil is similar to that of Mercurial:
fossil revert -r good_revision
fossil commit -m "Now I'm in the good revision"
This will replace the files in the working directory with the ones from the specified revision. The commit will commit them to whatever branch you're working on (I am assuming that it is the trunk in this example). If you don't specify the revision number, it will use the last committed version.
One of the more common usages of the revert command is to roll back a single file:
fossil revert -r good_revision my_file
(or)
fossil revert my_file_from_the_last_commit
However, as shown in the first example, leaving out the file name causes all files to be reverted. For further information please see https://www.fossil-scm.org/index.html/help?cmd=revert
Sorry for the latest response, but I just came across the question while looking for something else. I post this in case someone else is looking into how to revert to a previously committed version stored in Fossil.

I was working in the wrong repo. They are almost the same but not associated data. How do i diff/merge?

Can you diff with the reverted copy?
I was doing work in the wrong repo. They are almost the same, but have no actual relation.
I just did a pull and an update, can i then copy my changed files into the Right head and then run a diff on it or something similar and then properly merge the 2 together?
I feel an alternate option would be do something like
copy the code over and commit it, then revert back, and merge with the commit to diff what has all changed..
I have changing something like 1500 lines over 9 files, so i dont want to rewrite a bunch of code segments.
How should i handle this?
It really depends on how similar the "almost the same, but have no actual relation" repositories are.
If they extremely similar (as in files have the same names and text is almost identical), you might get by with exporting a patch at the source repo and then importing the same patch into the target repo.
In the source repo:
hg export -r tip > path\to\oops.patch
and in the target repo:
hg import path\to\oops.patch --no-commit
I used --no-commit since I assume you will need to do some cleanup first to make sure that everything looks ok.
Alternatively, you could just compare the two directories using kdiff or BeyondCompare3 and bring over the differences that you want from the source repo to the target repo and commit it that way. This would probably be my approach.
(I am intentionally ignoring the question about why you have two repositories that are that similar but don't have a shared history. For all I know, it might be the right thing to do.)

How to prevent divergent mercurial branches from merging?

I have a project stored in mercurial which has grown well beyond its original remit, and now I want to split the repository into two separate projects. Say the file tree looks something like this:
src/
a/
a.h
a.c
b/
b.h
b.c
Say I've hg cloned this repository twice, and in the first clone I've performed an hg rm src/b/*, and in the second I've performed an hg rm src/a/*. This gives me the two separate source trees I want, with history and revision numbering preserved in each branch.
The problem I now have is what happens if, in the future, I ever accidentally pull from the a/ clone into the b/ clone. What I'd like is for mercurial to simply refuse to pull from, or push to, the other branch, if I ever try to do so, as if the two had never shared history.
Is this possible? If not, is there a canonical way to create two parallel projects from one original which preserves history and revision numbering?
The canonical way would be to use hg convert with a filemap like this:
exclude b
rename a .
(and afterwards with the roles of a and b reversed to create the second repository)
This way you end up with two unrelated repositories (which Mercurial will refuse to push/pull without the use of force) only containing the history of a single directory.
Also see this question for reference.

Which Version control?

If a project has multiple people, say, A,B,C working together and they all edit a same source file.
Couple months later, they realize that what A has been doing is wrong and they want to roll back the file in such a way that only parts/functions/lines/... that A "touched" are removed and the work B and C did is still in the roll back version. In other words, the roll back version has only the work of B and C up to the time they decide to remove A's work.
Is there any version/source control software out there (free/commercial) can do that?
Thanks.
Git and a bit of scripting will do that. Probably a bit of hand work too, but you can resort commits using interactive rebase.
Most VCSs should be able to do this -- it's a reverse merge. In Subversion you would identify the revisions made by A and merge them in again, but the other way round. To oversimplify, this means turning line additions into line removals, and vice versa.
# Don't want revision 37 because A made it.
$ svn merge -r 37:36 path
http://svnbook.red-bean.com/en/1.5/svn.branchmerge.basicmerging.html#svn.branchmerge.basicmerging.undo
I use TFS and Git. But, there are a lot of free and open source version control softwares. You can find all the source control softwares here.
In Git, you would probably do something like
git revert `git rev-list --author=A`
[Note: completely untested.]
I bet it can (easily) be done with Monotone by using `mtn local kill_certs selector certname [certval]' command (see reference) which:
This command deletes certs with the given name on revisions that match the given selector. If a value is given, it restricts itself to only delete certs that also have that same value. Like kill_revision, it is a very dangerous command; it permanently and irrevocably deletes historical information from your database.
So, by using A's certificate, the above command will eliminate 'wrong work' done by him.