Can I change the username on a mercurial changeset?

21,599

Solution 1

If you've not published your repository then this shouldn't be too hard. You need to use the Convert extension to Mercurial, which will let you 'filter' your existing repository to create a new one. the --authors switch lets you edit the author for each commit as it is filtered.

If you have published your repository, please consider the impact on your users, the mercurial wiki has some reasons not to edit history.

Enable the extension by adding these lines to your .hgrc:

[extensions]
hgext.convert=

Write a file to map the old name to the new name (authors.convert.list):

user@[email protected]

Run the conversion:

hg convert --authors authors.convert.list SOURCE DEST

I just checked it, it works for me :).

Solution 2

If you have a single outgoing changeset, there is a very simple way to do this:

$ hg ci --amend --user "My Name <[email protected]>" -X "**"

The -X "**" option can be omitted if you don't have any local changes.

Solution 3

I've tried a couple of different methods (including the Convert Extension, which I found created an unrelated repository). The Mercurial wiki instructions for editing history using MQ were the ones I found most helpful. (There are of course the usual caveats about editing any publicly-known history being a bad idea, but local-changesets that only you have are OK to edit).

I'll summarise the crucial steps here, and clarify the mechanics of changing the author. Assuming the first wrong author commit is at revision BAD (and you haven't published your changes anywhere of course), you should be able to do the following (I'll assume you're at the repository root):

Enable MQ by adding this to $HOME/.hg/hgrc

[extensions]
hgext.mq=

Convert the recent changesets into patches:

$ hg qimport -r BAD:tip

(They can now be found at .hg/patches)

"Unapply" all the patches (assume they've been applied, and reverse them), to get your repository into the state of the revision before BAD:

$ hg qpop -a

If you look at your patches, you'll see that the author is encoded in a kind of comment line in all the patches:

$ grep User .hg/patches/*
.hg/patches/102.diff:# User Firstname Lastname <[email protected]>

Now use your favourite search/replace tool to fix the patches (I'm using Perl here). Let's assume you want the commit name to be [email protected]:

$ perl -pi -e 's/f\.lastname\@oops\.wrongurl\.example\.com/f.lastname\@righturl.example.com/' .hg/patches/*.diff

Now check that you have successfully changed the author name, and re-apply the patches:

$ hg qpush -a

Then convert the applied patches into proper changesets:

$ hg qfinish -a

And you're done. Your repository is still listed as related, so you won't get any complaints about pushing.

Solution 4

I've used the histedit extension which allowed me to change the author without making new repos like "convert" would or resorting to "mq".

First, in your Mercurial config file, make sure your username is set correctly and enable the histedit extension:

[ui]
username = Your Name <[email protected]>

[extensions]
histedit =

Then, if you want to change revision 40, use:

hg histedit -r 40

In the file that appears, on the line corresponding to revision 40, change the word pick to edit. Save and close the file.

Now, hg commit. You'll need to re-enter your commit message and save.

Finally, hg histedit --continue.

The commit will appear with your new username. A side-effect is the timestamp of the commit is also updated.

Share:
21,599
Dan Goldstein
Author by

Dan Goldstein

Hi, I'm Dan Goldstein. I've been a software developer both professionally and in my spare time since 2002. I've used a large number of languages and frameworks and have a lot of public code available under the Github and Bitbucket profiles thasmin. https://github.com/thasmin https://bitbucket.org/thasmin/ I created an open source Android podcast player called Podax. It was published and popular in the open source community around 2014 but time constraints prevented me from maintaining it. I do continue to work on it, and the newest branch contains the latest Android technologies, such as Kotlin and Architecture Components. At Teralogics, we created a video distribution system that took video from drones in Iraq and Afghanistan and brought it back to the US for analysis. I created the first version alone, then grew with the project to be the software lead of the team of 10 people, then the operations lead as the project matured. Under the strength of this project, the company was acquired for $39M in 2015. My software and business experience make me a strong contributor to any project. I look forward to going into more detail in an interview.

Updated on July 05, 2022

Comments

  • Dan Goldstein
    Dan Goldstein almost 2 years

    I didn't set the username on my development computer and made a few commits. Can I retroactively change the username so it's clear who committed these changesets?

  • hhh
    hhh about 13 years
    @Andrew Aylett: how did you checked it? "$ hg clone myWrongRep name", did the changes and then "$ hg convert --authors theFile myWrongLocalRep". Now it generates ".-hg" file and the site says that there should be something with "hg status" but I cannot find anything (although there is. I had wrong author commit with name 'hh' so I created a line 'hh=hhh' to the file but after pushing, now change and after "$ hg update" and "$ hg push", no change. What am I missing?
  • hhh
    hhh about 13 years
    You can check the authors/verify whether commands work with this command $ hg log --template '{author}\n'|less, haven't yet got it working -- not understanding the authormap -thing.
  • hhh
    hhh about 13 years
    Suppose I want to change "userA [email protected]" to "userB [email protected]" and "useA [email protected]" to "userA [email protected]". What is it in that syntax above? I have tried many variants but got into many different results, not understanding the separator.
  • Andrew Aylett
    Andrew Aylett about 13 years
    @hhh: I'd suggest asking a new question about that -- I've not actually used hg since answering this question, so I'm not the best person to solve your problem...
  • hhh
    hhh about 13 years
  • Tobu
    Tobu almost 13 years
    That didn't work for me. It rewrote the entire history, whether I was the author or not. Rebase fails after that. Is there a way to convert only recent, unpushed commits?
  • Andrew Aylett
    Andrew Aylett almost 13 years
    @Tobu: It's probably worth you creating a new question too.
  • djs
    djs over 11 years
    From the context of the question, I expected this question to answer Tobu's question, but I quickly learned it did not. Instead it just tries to rewrite the entire history of the repo.
  • damianostre
    damianostre about 11 years
    It would also help if you explained what "SOURCE" and "DEST" are supposed to be. Paths? Unfortunately, even hg's help doesn't explain what they are.
  • Andy MacKinlay
    Andy MacKinlay over 10 years
    The only problem with this approach is that the repositories are then not considered related, so you can't push (without forcing) to an existing repository.
  • Meetai.com
    Meetai.com about 10 years
    Got "abort: cannot import merge revision [Revision Number]
  • user2428118
    user2428118 over 9 years
    Worked for me. I had to change the status of my commits from "published" to "draft" first, though.
  • ederag
    ederag over 9 years
    A trailing / was needed before the closing quote, otherwise the perl command yielded an error Substitution replacement not terminated at -e line 1. Otherwise perfect, thanks !
  • Alexander K
    Alexander K over 8 years
    Great solution, very helpful!
  • Alex
    Alex about 5 years
    Thanks, that just worked well for me. God, I love mercurial - I really do, but little things like this tend to be more difficult in hg then in git. Eg. in git it's --reset-author. For hg there are always many solutions like we see in this thread and all are painful and difficult (except yours though). Thanks!
  • Thomas LAURENT
    Thomas LAURENT about 4 years
    It doesn't seem to work : "abandon: can only histedit a changeset together with all its descendants"
  • Jason Robinson
    Jason Robinson about 2 years
    This should be marked as the solution. Following the instructions accordingly, made the changes a breeze. Thank you.
  • Jason Robinson
    Jason Robinson about 2 years
    This also worked for me. Will remember this one for the previous changeset