hg rebase abort fails: "unknown revision" - mercurial

Occasionally when performing a rebase using the MercurialEclipse plugin my repository gets thrown into an odd state. It will become stuck in a "rebasing" state, yet when I try to abort the rebase (e.g. "hg rebase -a") I get this error message:
abort: unknown revision 'xxxx'!
Where xxxx is a revision hash. Usually at this point I've abandoned all hope of performing the rebase -- I just want to get back to a happier time when my repository was not screwed up. So far my solution has been to nuke my project directory and clone it again. Is there a less drastic solution?

Just remove the .hg/rebasestate and your repo will work.
The patch described in this thread calls the internal function clearstate which just unlinks this file.

In situations similar to this, I usually do:
$ hg check
$ hg verify
$ hg up -C default
Instead of default, use whatever branch you're working on. This takes time, but so does re-cloning the repo.
It usually helps.

Related

Hg working directory revision is not a qtip

I'm using mercurial Hg in command line. After created a patch, I needed to revert to another changeset due to some errors happened later. Now it's needed to refresh the patch file. When executing Hg qref it says, abort: working directory revision is not qtip. Also, hg parent is a tip.
I'll add an answer to help other people that may encounter the same error message in the future. I'm not sure our issues was identical but definitely related.
I got "abort: working directory revision is not qtip" while trying to apply a patch onto my working directory.
It turned out that I had older patches in the patch queue which caused the problem and after I deleted these and tried again it worked!
Here's what I did:
Opened a console window and navigated to the working directory where I entered the command:
hg qseries
this listed the patch queue. Then to delete the old patches I entered:
hg qdelete [patch name (which was just listed)]
The response in my case was "abort: cannot delete applied patch ..." and to resolve this I entered:
hg qpop
This unapplied the patch and then I could use the "hg qdelete" command again which now work. Repeated this until all old patches were gone and tried to apply the new patch again.
Found the solution in the "Mercurial: The Definitive Guide", written by Bryan O'Sullivan, under section 12.7.1. http://tortoisehg.bitbucket.io/hgbook/1.4/managing-change-with-mercurial-queues.html#id2858507
Hope someone finds this useful!
It happened due to popping the current head out of the queue. In order to refresh, the patch should have been taken into the head of the queue by qpush.

Mercurial error: repository is unrelated

I've just started with Mercurial, I have a 'central' repository on Bitbucket which I cloned onto one machine and made changes and committed and pushed. I then cloned from Bitbucket to another machine committed and pushed which was fine. I then came back to the first machine, made changes committed and attempted to push, but got the error message. What am I doing wrong? Should I have pulled first? How can I resolve the error and push? Any help is appreciated!
Darren.
A Mercurial repository gets its identity when you make the first commit in it. When you create a new repository on Bitbucket, you create an empty repository with no identity.
When you clone this repository to machine A and make a commit and push it back, then you brand the repository. If you have cloned the repository on the second machine before pushing from the first, then you can end up in the situation you describe.
Please run hg paths on the machine where you cannot push. Then make a separate clone of the repository it says it will push to. Now examine the first changeset in each repository with
hg log -r 0
If the initial changesets are different, then you have two unrelated repositories, as we call it in Mercurial. You can then export the changes you cannot push as patches and import them in the other.
If you're pretty sure the push path is correct, it may be worth it to just export your changes to patches from the problem repo, clone again from Bitbucket and then import the patches into the new repo. This will either just work or reveal a bad/corrupted commit.
I would like to share knowledge about Mercurial internals.
Repositories unrelated when they have no any same revisions.
Corresponding piece you can find in mercurial/treediscovery.py:
base = list(base)
if base == [nullid]:
if force:
repo.ui.warn(_("warning: repository is unrelated\n"))
else:
raise util.Abort(_("repository is unrelated"))
base is a list of roots of common parts in both local/remote repositories.
You always may know how repositories are different by:
$ hg in $REMOTE
$ hg out $REMOTE
You always may checks roots of both (after cloning both locally):
$ hg -R $ONE log -r "roots(all())"
$ hg -R $TWO log -r "roots(all())"
if output from above commands doesn't share IDs - those repositories are unrelated. Due to hash properties it is very impossible that roots be equal accidentally. You may not trick roots checking by carefully crafting repositories because building two repositories looks like these (with common parts but different roots):
0 <--- SHA-256-XXX <--- SHA-256-YYY <--- SHA-256-ZZZ
0 <--- SHA-256-YYY <--- SHA-256-ZZZ
impossible because that mean you reverse SHA-256 as each subsequent hash depends on previous values.
Having this info I believe any Devs be able to troubleshoot error: repository is unrelated.
See also Mercurial repository identification
Thanks for attention, good hacking!
You get this message when you try to push to a repository other than the one that you cloned. Double-check the address of the push, or the default path, if you're just using hg push by itself.
To check the default path, you can use hg showconfig | grep ^paths\.default (or just hg showconfig and look for the line that starts paths.default=).

Force warnings about crossing branches when running Update using TortoiseHg

When getting the latest code from a Mercurial repo on the command line, if there are changesets that need to be merged Mercurial raises a warning:
hg up
abort: crosses branches (merge branches or use --check to force update)
This is what I expect, and from the Mercurial book it says "Mercurial is telling us that the hg update command won't do a merge; it won't update the working directory when it thinks we might want to do a merge, unless we force it to do so." At this point I know I need to merge.
How can I get the same behaviour using TortoiseHg? When I hit "Update", it happily updates me to the most recent changeset. Is there a way to warn me that a merge is probably needed? The "Always merge (when possible)" option seems to only apply when you have uncommitted changes.
The reason you get an error from hg update on the command-line is that it doesn't know which revision to pick. There are 2 divergent default heads.
If you were to execute hg update -r <specific rev>, the command completes without error.
When using TortoiseHg, you update by:
right-clicking a specific changeset
selecting Update...
This translates to hg update -r <rev>, so there is no error.
Using TortoiseHg, you always have the revision graph in front of you. The graph shows when newly pulled changesets create a new head.
The Mercurial abort you are seeing is occurring because you have outstanding (ie: non-committed) changes in your working directory, are trying to perform an update, and Mercurial has decided that you should probably perform a merge instead.
TortoiseHg should also warn you about this, but it will do so in a different way. It will spawn a dialogue that asks if you want to Discard, Merge, or Shelve your outstanding changes. This is what it looks like in TortoiseHg v2.X.X, but it should be similar in v1.1.X:
If you're not seeing this in TortoiseHg, you may not have any outstanding changes. Try it again - are you seeing these options?

How do you delete a commit in Mercurial?

I want to completely delete a Mercurial commit as if it was never entered in the repository and move back to my prior commit.
Is this possible?
If it was your last commit and you haven't pushed it anywhere, you can do that with rollback. Otherwise, no. Not really. Time to change your passwords.
Edit: It has been pointed out that you can clone from an older revision and merge in the changes you want to keep. That's also true, unless you have pushed it to a repo you don't control. Once you push, your data is very likely to be very hard to get back.
You can try to remove mq info about your commit.
For this you need to go File->Settings->Extensions.
There check mq and restart gui.
After that just right click on unneeded commit and
ModifyHistory->Strip
To edit the history I would use the Histedit Extension extension.
hg histedit 45:c3a3a271d11c
However keep in mind this only makes sense in a situation where you have not yet pushed the commits to the public repository, you own the public repository and/or you can account for all the clones out there. If you receive the following error:
abort: can't rebase immutable changeset 43ab8134e7af
It means that Mecurial thinks this is a public changeset (see phases) that has already been pushed - you can force it to be a draft again doing:
hg phase -f -d 45:c3a3a271d11c
I encounter this fairly often. I make a commit and then pull to push. But then there is something incoming that makes my newly made commit unnecessary. A plain hg rollback isn't enough because it only undoes the pull...
This is the thing to do:
hg strip <rev>
Things are painless when you don't push your changesets anywhere.
If it's more than one commit and/or you already pushed it somewhere else, you can clone your repository and specify the last changeset that should be cloned.
See my answer here how to do this:
Mercurial: Fix a borked history
If you only committed locally and didn't push, you can just create a clone locally (as described in my link) and you're done.
If you already pushed to some remote repository, you would have to replace that with your clone.
Of course it depends if you are able (or allowed) to do this.
You can use "hg backout" to do a reverse merge basically. All options are discussed in the freely available book "Mercurial: The Definitive Guide":
http://hgbook.red-bean.com/read/finding-and-fixing-mistakes.html
If using tortoise you can use modify history > strip...
Yes. Unless I am mistaken, as of v2.3 (rel. 2012/08/01) you can use the HisteditExtension with a drop command to drop a commit, along with strip or backout to remove changes.
A simple Google search on the feature: https://www.google.com/webhp#q=histedit+drop
In 2022 I do use evolve extension. It is one of the best extensions for this purpose.
To prune unwanted changeset, if you for example did a quick hack to get the code working:
$ echo 'debug hack' >> file1.c
$ hg commit -m 'debug hack'
Now you have a proper patch you can do hg prune .:
$ hg prune .
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
working directory is now at 2a39221aaebb
1 changesets pruned
If you push the change to the remote repository you will find only obsolescence markers:
$ hg push
searching for changes
no changes found
remote: 1 new obsolescence markers
To check the changes to your local repo you can pull from the remote one:
$ hg pull
pulling from ssh://userid#server/repo
searching for changes
no changes found

Is it possible to clone with hgsubversion in steps?

I'm trying to clone a rather large subversion repository with hgsubversion.
hg clone --startrev 8890 svn+https://my.reposit.ory/trunk trunk_hg
After about an hour, the clone operation aborts with an out of memory message:
[r20097] user: description
abort: out of memory
Is it possible to specify an end revision for the clone operation and get the remaining revisions with a pull? Or somehow break up the clone in smaller steps?
You can specify a stop revision with -r for clone, as others have suggested. Another option (if you kept the clone where things crashed) would be to just run hg pull in the trunk_hg copy. You might have to edit/create .hg/hgrc yourself to add the [paths]\n default = svn+https://my.reposit.ory/trunk, since I think we add that at the end of the cloning process. Maybe run hg svn rebuildmeta before your pull just for good measure in case the tracking metadata for hgsubversion got hosed when the OOM happened.
I hope this helps!
http://www.selenic.com/mercurial/hg.1.html#clone
Could try using the -r <revid> flag to clone only a particular changeset. Though that may or may not work with hgsvn.
Cloning with a limited range of revisions and then pulling is the recommended method and I can confirm that it works flawlessly for svn repositories in the several GB size range.
Here is a workaround to clone the whole svn repo:
start cloning
abort it immediately (Ctrl+C in windows)
than hg pull
you've got out of memory
repeat step 3 until you check out all commits