Is there any way to delete local commits in Mercurial?

后端 未结 10 1002
小鲜肉
小鲜肉 2020-11-28 19:11

So I keep making a silly mistake in Mercurial. Often times, I\'ll start work without doing an \"hg pull\" and an \"hg update.\" When I try to push my changes, I get an err

相关标签:
10条回答
  • 2020-11-28 19:51

    I came across this problem too. I made 2 commit and wanted to rollback and delete both commits.

    $ hg rollback
    

    But hg rollback just rolls back to the last commit, not the 2 commits. At that time I did not realize this and I changed the code.

    When I found hg rollback had just rolled back one commit, I found I could use hg strip #changeset#. So, I used hg log -l 10 to find the latest 10 commits and get the right changeset I wanted to strip.

    $ hg log -l 10
    changeset:   2499:81a7a8f7a5cd
    branch:      component_engine
    tag:         tip
    user:        myname<myname@email.com>
    date:        Fri Aug 14 12:22:02 2015 +0800
    summary:     get runs from sandbox
    
    changeset:   2498:9e3e1de76127
    branch:      component_engine
    user:        other_user_name<name@email.com>
    date:        Mon Aug 03 09:50:18 2015 +0800
    summary:     Set current destination to a copy incoming exchange
    
    ......
    
    $ hg strip 2499
    abort: local changes found
    

    What does abort: local changes found mean? It means that hg found changes to the code that haven't been committed yet. So, to solve this, you should hg diff to save the code you have changed and hg revert and hg strip #changeset#. Just like this:

    $ hg diff > /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff
    $ hg revert file_you_have_changed
    $ hg strip #changeset#
    

    After you have done the above, you can patch the diff file and your code can be added back to your project.

    $ patch -p1 < /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff
    
    0 讨论(0)
  • 2020-11-28 19:52

    hg strip is what you are looking for. It's analogous of git reset if you familiar with git.

    Use console:

    1. You need to know the revision number. hg log -l 10. This command shows the last 10 commits. Find commit you are looking for. You need 4 digit number from changeset line changeset: 5888:ba6205914681

    2. Then hg strip -r 5888 --keep. This removes the record of the commit but keeps all files modified and then you could recommit them. (if you want to delete files to just remove --keep hg strip -r 5888

    0 讨论(0)
  • 2020-11-28 19:59

    In addition to Samaursa's excelent answer, you can use the evolve extension's prune as a safe and recoverable version of strip that will allow you to go back in case you do anything wrong.

    I have these alias on my .hgrc:

     # Prunes all draft changesets on the current repository
     reset-tree = prune -r "outgoing() and not obsolete()"
     # *STRIPS* all draft changesets on current repository. This deletes history.
     force-reset-tree = strip 'roots(outgoing())'
    

    Note that prune also has --keep, just like strip, to keep the working directory intact allowing you to recommit the files.

    0 讨论(0)
  • 2020-11-28 20:04

    Enable the "strip" extension and type the following:

    hg strip #changeset# --keep
    

    Where #changeset# is the hash for the changeset you want to remove. This will remove the said changeset including changesets that descend from it and will leave your working directory untouched. If you wish to also revert your committed code changes remove the --keep option.

    For more information, check the Strip Extension.

    If you get "unkown command 'strip'" you may need to enable it. To do so find the .hgrc or Mercurial.ini file and add the following to it:

    [extensions]
    strip =
    

    Note that (as Juozas mentioned in his comment) having multiple heads is normal workflow in Mercurial. You should not use the strip command to battle that. Instead, you should merge your head with the incoming head, resolve any conflicts, test, and then push.

    The strip command is useful when you really want to get rid of changesets that pollute the branch. In fact, if you're in this question's situation and you want to completely remove all "draft" change sets permanently, check out the top answer, which basically suggests doing:

    hg strip 'roots(outgoing())'
    
    0 讨论(0)
提交回复
热议问题