We're using a local central repository where everyone pushes to and pulls from. Until recently this repository only contained the .hg folder. Then someone we开发者_开发百科nt ahead and committed directly in the central repository creating an "island" changeset with no parent (parent = -1) nor child. The correct way would have been to add it in a local repository and push the changes.
Is there any way to get the working copy of the central repository to get back to the state where it only contain .hg and not be associated with a specific changeset?
The command:
hg update null
Updates a repository's working directory to the point before the first commit, so there are no files in the working directory and hg parents
shows -1
.
You'll still need to remove the commit if you don't want it, but that's a separate question/issue.
Since this is your local central repository and these are commands that edit history, please take every precaution, like trying things out on a copy of the repository first.
hg rollback
(to remove the last repository change)https://www.mercurial-scm.org/wiki/Rollback
Roll back the last transaction in a repository.
hg strip
(to remove specific revisions)https://www.mercurial-scm.org/wiki/Strip
hg strip rev removes the rev revision and all its descendants from a repository.
- Also see:
https://www.mercurial-scm.org/wiki/EditingHistory
If you catch your mistake immediately (or reasonably soon), you can just use hg strip REV to roll back the latest (one or more) changes. ...
Edit: This answers the question in its original form. The OP has since edited the question.
Just delete everything except the .hg
folder.
If I understand correctly what happened, someone changed into the repository directory and committed a single file as an 'added file' without first checking out any changeset from the active directory.
What you ended up with is something like the following history graph:
0:a43f 1:2843 2:bc81 3:2947
o ------ o ------ o ------ o
4:228f
o
where changeset 4:228f has the "null id" as its parent changeset.
Depending on whether you want to keep changeset 4:228f or not, you can follow one of the following strategies:
Option 1: Clone the repository without the offending change
You can create a new clone of the repository, specifying revision 3:2947 as the target revision. This will pull change 3:2947 and all its ancestor changesets into the new repository. Since the offending changeset is not linked into the ancestry of changeset 3:2947, it will not be part of the new clone.
I recommend saving the old repository first, and then moving everything over to a new clone, e.g. any repository-specific setup files you keep in its .hg/
directory.
If your current repository lives in /work/repo/foo
, one way to do this would be:
$ cd /work/repo
$ mv foo foo.bak
$ hg clone -r 2947 foo.bak newfoo
Now copy over any .hg/
setup files, e.g. your original .hg/hgrc
file:
$ cp foo.bak/.hg/hgrc newfoo/.hg/hgrc
Finally move the new foo
repository in place:
$ mv newfoo foo
Option 2: Clone the repository and keep but rebase the change
Do the same as before, but before you move the newfoo
repository in place, use the "hg export" command to extract a copy of the offending change from the old repository. Then check out a working copy of the tip-most changeset in the newfoo
tree and import the file changes of the offending change as a normal changeset of your current history graph.
So, right before mv newfoo foo
, save the patch of the offending change by typing:
$ cd /work/repo/foo.bak
$ hg export -r 228f --git > /tmp/patchfile.diff
then you can check-out the latest revision of the new repository, and re-import the patch on top of your current history:
$ cd /work/repo/newfoo
$ hg update --clean tip
$ hg import /tmp/patchfile.diff
If the offending changeset merely adds a new file, this should work fine and you are ready to move the new repository in place!
Before doing the final rename though, it may be a good idea to remove the working-copy files of the new repository:
$ cd /work/repo/newfoo
$ hg update --clean null
精彩评论