"Unknown Parent" error on rebundle in Mercurial - mercurial

I accidentally stripped the wrong changesets; however, I saved backups, but when I try to unbundle them using hg unbundle .hg/strip-backup/faa0a1895b97-backup.hg, I get the following error:
adding changesets
transaction abort!
rollback completed
abort: 00changelog.i#561fe01204b5: unknown parent!
What can I do to correct this?
Here's the entire output from hg verify:
checking changesets
checking manifests
crosschecking files in changesets and manifests
checking files

If unbundle is telling you that it can't apply the bundle then the parent of that "first" changeset it that bundle, the bundles base, doesn't exist in your repo. Since repos never lose changesets using normal mercurial commands (strip isn't normal) then it seem you used strip or some other history-altering-not-normal-usage command to alter or remove that changeset.
Try going through all the .hg/strip-backup/ files and applying them one by one. Maybe one of them does apply and contains the parent the the strip backup you're trying to apply requires.
Tl;Dr: no normal mercurial command ever deletes anything, and the non-normal ones that do create backups. Unless you deleted the file out of band the data is there somewhere.

Related

Mercurial: Forcing unbundling a bundle that has unknown parents

I have a repository named repo1, and it's my base.
I clone it into repo2.
I have another repository containing some unrelated files and history, named other_repo.
Thanks to hg convert, I can import a subset of other_repo into repo2, while keeping the history of the files:
hg convert --filemap my_file other_repo temp_repo
cd repo2
hg pull -f temp_repo
This is working flawlessly.
However, now, if I bundle the changes in repo2, and try to unbundle them in repo1, I get the following error:
adding changesets
transaction abort!
rollback completed
abort: 00changelog.i#82dc9cd3be46: unknown parent!
Well, that's normal. The new parent comes from the other_repo, and it is needed now.
Note that hg pull in repo1 from repo2 is working fine.
In such a case (when the repository's history is fine, hg verify doesn't complain, I didn't strip anything), is there a way to force the unbundle action?
No, there isn't.
The bundle is a diff between the parent and the child, you only got the changes, and without the parent, you can't reconstruct the child changeset.
So get the parent into the repository before you try to unbundle.
Or create a new bundle, without that changeset.
Or, do some history rewriting in the source repository first, so that you don't need the parent.
Regardless, you can't force this to complete without rethinking your approach.

hg pull abort unknown parent

I'm trying to pull from an hg repo but I seem to be getting the following error:
pulling from http://hg.mozilla.org/qa/mozmill-tests
searching for changes
adding changesets
adding manifests
adding file changes
transaction abort!
rollback completed
abort: data/tests/endurance/testBookmarks_AddAndRemoveBookmarkViaAwesomeBar/test1.js.i#2daf2ef33d4b: unknown parent!
And hg verify seems to return
759 files, 2820 changesets, 5082 total revisions
2688 integrity errors encountered!
(first damaged changeset appears to be 54)
How can I fix this?
I've cloned this repo and it worked ok. Do you have any local modifications in your clone? If not, you could just reclone the repo. Otherwise I suggest you to refer to the wiki page about repo corruption.

How to rename a file using Mercurial Queues?

Mercurial Queues is about patches, and patches know nothing about file renames. Is this the reason why Mercurial Queues don't support file renames, or am I doing something wrong renaming the file? I have worked on a patch queue modifying just one file called foo. Now I go back to patch 4 and rename the file via hg mv:
hg qpop 4 # Unapply all patches until patch 4.
hg mv foo bar # Rename file and led Mercuial know about it.
hg qrefresh # Should apply changes to unapplied patch 4.
hg qpush -a # Should apply all unapplied patches.
I get the following error:
unable to find 'foo' for patching
1 out of 1 hunks FAILED -- saving rejects to file foo.rej
patch failed, unable to continue (try -v)
patch failed, rejects left in working dir
errors during apply, please fix and refresh 5.diff
So how should I do to handle file renames with Mercurial Queues? Mercurial commits handle file renames for a reason (as without, it would lose the whole history about the editing of the file after renaming).
Update
Just noticed that hg histedit folding changesets and hg collapse also lose the information of file renaming, the file shows up as a new one instead of a renamed one, and I guess this is for the same reason. Seems like collapsing private changesets is not possible in Mercurial without loosing that information?
Update 2
Found out collapsing private changesets without loosing rename information is possible with hg rebase and its --collapse option, e.g. hg rebase -s 5 -d 4 --collapse. The issue that the other commands should sostain rename information is still vacant, but using the hg rebase command there is at least a way to achieve the desired result.
Is this the reason why Mercurial Queues don't support file renames,
no.
or am I doing something wrong renaming the file?
no.
Yes, patches in chain will have troubles, if they was prepared for foo file, but later in will be bar, but due to different reasons: patches are independent, and every and each patch know nothing about changes in others - they work with context, not with sequence of operations in separate patches. You done rename correctly, but this changeset invalidates later changesets, prepared on old content

Apply mercurial bundle file on different changeset

TLDR: I have an HG bundle with parent X, but revision X does not exist in my repo. However, I am sure that the files of revision Y are identical to revision X. How do I apply the bundle?
Background:
I use hgsubversion to interact with an SVN repo.
There were some changes I did not want to commit. hgsubversion does not support partial pushes.
I used to workaround by manually creating temporary exports/patch files, or manually restoring .orig files (result of hg revert).
In this case I committed the changes I did not want to push, then used hg strip, then pushed, then tried to use hg unbundle .hg/strip-backup/file.
Problem: hgsubversion replaces the original changeset with a new one it imports from SVN after it's committed it. Result: the changeset ID changes. This is a problem because now hg unbundle no longer works, as it relies on the parent changeset being there (but it's been stripped).
Ironically, hgsubversion itself uses strip and thus has a backup file I can use to strip the new rev, add the stripped old revision, then apply the bundle with my revisions, export the patch, strip both, and restore the SVN revision. But this sounds... extremely painful and stupid. Is there nothing better I can do?
(hg transplant doesn't seem to like the bundle without having the parent in the repo, either)
It's effectively impossible to use a bundle without the bundle's precise parent changesets. Bundles consist of compact binary deltas that can only be applied to the precise binary source. There is no 'context' available that would allow Mercurial to guess how to apply them to other revisions the way patch does. In core Mercurial, this is never an issue because changesets are never removed, but extensions like hgsubversion and mq break the rules.
(If you can recover the stripped changesets from a backup bundle in .hg/strip-backup, you can then rebase your changes and strip again.)
Background: After hitting an issue with hgsubversion pushing only 1 revision successfully, I got lazy in my commits (partial commits are possible if you update to the latest revision you want to push), and ended up starting to commit everything. So I killed the push and for the first time it failed to keep my later revisions.
I tried recover, but that was not able to find the parent commit. What worked for me was restoring the ...-backup.hg file (there was a ...-temp.hg file in strip-backup too).
The strange thing (which is why I'm answering this) is that it only gave me a warning about the parent not being there (I have no idea why)...
warning: ignoring unknown working parent d5663567bc4b!
adding changesets
adding manifests
adding file changes
added 21 changesets with 1255 changes to 941 files
(run 'hg update' to get a working copy)
BTW, I'm running Mercurial version 2.0

Fixing a failed integrity check in Mercurial?

I just did hg pull on a repository and brought in some changesets. It said to run hg update, so I did. Unfortunately, when I did that, it failed with the following error message:
abort: integrity check failed on 00manifest.i:173!
When I run hg verify, it tells me there are a number of issues with things not in the manifest (with some slight path obscuring):
>hg verify
checking changesets
checking manifests
crosschecking files in changesets and manifests
somewhere1/file1.aspx#172: in changeset but not in manifest
somewhere2/file1.pdf#170: in changeset but not in manifest checking files
file3.csproj#172: ee005cae8058 not in manifests
somewhere2/file1.pdf#171: 00371c8b9d95 not in manifests
somewhere3/file1.ascx#170: 5c921d9bf620 not in manifests
somewhere4/file1.ascx#172: 23acbd0efd3a not in manifests
somewhere5/file1.aspx#170: ce48ed795067 not in manifests
somewhere5/file2.aspx#171: 15d13df4206f not in manifests
1328 files, 174 changesets, 3182 total revisions
8 integrity errors encountered!
(first damaged changeset appears to be 170)
The source repository passes hg verify just fine.
Is there any way to recover from an integrity check failure or do I need to re-clone the repository completely from the source (not a huge issue in this case)? What could I have done to cause this, so I don't do it again?
Well, since the first damaged changeset is 170, you could clone your local repository to 169 and then pull from the source. That means only pulling 5 changesets.
hg clone -r 169 damagedrepo fixedrepo
cd fixedreop
hg verify
And then:
hg pull originalsource
As for manual recovery of repository corruption, this page expounds on that better than I can. See section 4:
I have found corruption once in a while before, and although the above
documentation says it is usually from user error, my instances were on
removable USB drives with empty working directories. Sometimes things
just don't get written correctly or are interfered with somehow: it's
not always user error. But I always have multiple copies I can reclone
from so I've been able to get away with basic fixing.
If the simple fix of a partial local clone and pulling from the server doesn't fix it, you're down to 2 options after backing up your changes (if any) to a bundle or patches:
Manually hacking at Mercurial's files.
Doing a new full clone from the server. Usually the easier and faster of the two.
Beware: This method will change all hashes.
Actually there is another way to recover the repository when it is corrupted like this -
You can do a complete rebuild of the repository by using the convert extension. See Section 4.5 on https://www.mercurial-scm.org/wiki/RepositoryCorruption#Recovery_using_convert_extension
First enable the convert extension by adding the following to your ~/.hgrc file
[extensions]
convert=
Then convert the bad repo to create a fixed repo:
$ hg convert --config convert.hg.ignoreerrors=True REPO REPOFIX
This worked for me when I had the experience of suddenly finding that there were missing files in the manifests - "error 255".
Try remove your file 00manifest.i from repo and next use hg remove 00manifest.i and hg commit commands. Worked for me.
What we ended up doing was making a new copy of our 'central' repository, deleting the .hg folder in this copy, creating a new repository there (hg init), and then working with this as the central repository.
Be aware however this is only an appropriate solution if you don't need your changeset history other than as a reference (which we don't). You can still use your old central repository for this purpose.