I am in my first days of Mercurial, I did my google homework, but I can't find a solution to this.
Here is the output from the server which should explain things better than I could:
david#triton:~/www/triton$ ls -l -a | grep .hg
drwxr-xr-x 4 david david 4096 2011-11-19 17:44 .hg
-rw-r--r-- 1 david david 0 2011-11-18 22:23 .hgignore
david#triton:~/www/triton$ hg init
abort: repository . already exists!
david#triton:~/www/triton$ hg serve
abort: There is no Mercurial repository here (.hg not found)!
I am trying to push from tortiseHG on a windows client to this server but it too is complaining about there being no repo.
What the heck, guys?
hg init is just checking if a .hg directory already exists, which it clearly does. Try
$ ls -l .hg
ls: cannot access .hg: No such file or directory
$ mkdir .hg
$ hg init
abort: repository . already exists!
How did that .hg directory get there? If you created it yourself, you shouldn't have. You should have let hg init create it as it puts a lot of other stuff in there. What output do you get from hg summary?
This could happen if the versions of mercurial differ between server and client. In that case you'll have to convert the repo to the older version (or upgrade your client to the server version) in order to fix the issue. HTH!
If you run a hg stat or hg summary like R4yan said, you might see a more helpful error message. If it's a difference in version you might see something like: 'abort: requirement 'dotencode' not supported!'
Related
I have a mercurial repository hosted on bitbucket containing several folders. My goal was to split each of these folder into a separate repository. After trying a few things suggested on stackoverflow, which failed, my last throw of the dice was to replicate a mock example in the bitbucket tutorial
Even though I followed the instructions to the letter, this also failed:
hg convert -s hg -d hg --filemap mymapfile hgsplitpractice hgfreshrepo
initializing destination hgfreshrepo repository
hgsplitpractice is not a local Mercurial repository
abort: hgsplitpractice: missing or unsupported repository
This is the same error that appeared in my previous attempts to split my actual repo.
The questions are:
1. why is this failing?
2. is there any other way to split these repositories?
I was getting the same error as you did.
In my case, the problem was something really silly: I was referring to both repositories by their names instead of specifying their full path.
I hope it helps someone else.
This was failing:
hg convert -s hg -d hg --filemap mymapfile "My-old-repo" "New-repo"
This worked like a charm:
hg convert -s hg -d hg --filemap mymapfile "d:/allrepos/My-old-repo" "d:/allrepos/New-repo"
You can try to use the convert extension.
After the command:
--filemap
you can use:
exclude path/that/you/want/to/split
rename path/that/you/want/to/split .
See this thread for more: Can I split a Mercurial repository?
Is there a problem with Mercurial's guide for fixing case-folding collisions or is there a problem with the way I am implementing the solution.
The solution as provided on the Mercurial wiki is as follows:
hg clone -U repo repair
cd repair
hg debugsetparents <bad revision>
hg debugrebuildstate
At this point, Mercurial will think you have the bad revision checked
out and all the files are missing (status '!'). To fix the repo, we
simply have to do:
hg rm -A <file causing the collision>
Now hg st should show the troublesome file in state 'R' and all other
files in state '!'. Now we can check in our fix:
hg ci -m"fix case collision"
To get all our files back, we just check out again:
hg co tip
The problem files are: SomeFile.bash and Somefile.bash. I originally had Somefile.bash and I would like it to now be SomeFile.bash. Also to note, version 157 is happy, no collision, but version 158 is where I have introduced the collision. The head of the repository is currently at revision 160.
I have implemented this solution as follows:
hg clone -U my-repo-url repair
cd repair
hg debugsetparent 160
hg debugrebuildstate
hg status (reveals that everything is 'missing' (!))
hg rm -A Somefile.bash (responds that SomeFile.bash has been removed, notice case change)
hg ci -m "Fixed the collision... I hope."
hg co tip
hg update -C tip
According to the guide, this should have removed the case-folding collision and brought the rest of the missing files back, yet another hg status reveals that everything is still missing (!).
Edit: By appending that last command (the update) to the existing commands, I was able to recover the missing files which solved the remainder of the problem.
Note: I had to use the most recent 'problem' version for <bad revision> to fix this problem (that was 160 in my case).
Try
hg update -C tip
That should bring the files back. If not, try reverting everything:
hg revert -r tip -a
If you do hg log myfile -v you see a list of changesets that the file was modified in.
In our case, in the most recent changeset, the file was removed. But you can't tell this by looking at the verbose (-v) output of hg log. Is there an easy Mercurial command you can use to determine if and when a file has been removed from the repo?
Update: Note that this is on a Windows client, and we are using Mercurial v 1.4.3
Update 2: Appears the answers below would work with a more recent version of Mercurial, however an upgrade isn't in the cards right now. Any other ideas for v 1.4.3 ???
You can check which revision deleted a file (any many other interesting features) using revsets:
hg log -r 'removes(<myfile>)'
Some examples:
hg log -r 'removes(build.xml)' // where build.xml used to be in the current directory
hg log -r 'removes("**/build.xml")' // where build.xml may have been in sub directories
See hg help revsets for details.
The --removed flag should get you what you are looking for:
hg log myfile -v --removed
From the help for hg log:
--removed include revisions where files were removed
This is what I use to list all the deleted files in my repository:
hg log --template "{rev}: {file_dels}\n" | grep -v ':\s*$'
I am working on a system that performs continuous integration and I am looking for a method I can use to get the most recent changeset from a Mercurial repository without creating a repository locally.
I have considered using clone but this method will only work if you have set a working directory locally (since this will be occurring on a build server, I would prefer not to do this because of inclusion of the .hg file and the diffs - all I want is essentially an export of the files from the tip revision and nothing more.)
This request may not even be possible, and it's very likely that I just do not understand DVCS very well. However, if I cannot do what I want to do, is there a workaround?
It's possible using 'hg archive' depending how your remote repository is set up.
If it's available over HTTP using hgweb.cgi or hg serve you can hit the archive link programmatically to get the files you want. Example:
wget https://www.mercurial-scm.org/repo/hg/archive/tip.zip --output-document=- | unzip -
or it's available over ssh:
ssh you#there.com hg archive --type=zip - | unzip -
You can use:
$ hg clone http://your_repo
$ hg archive ../export/
$ rm -rf *
$ cd ..
$ cd export
From Mercurial's help files:
$ hg help archive
hg archive [OPTION]... DEST
create an unversioned archive of a
repository revision
You can use:
http://merc/raw-file
to retrieve a list of files in the repository or
http://merc/raw-file/filename
to get a specific file.
I've seen a number of blog posts, and have experienced for myself, that Mercurial does not preserve the permissions on files pushed from one repo to another. Does anyone know of a Mercurial extension that would preserve the permissions? I'm assuming it can't be done with a hook, because what does a hook know about permissions at the originating repo?
Requested elaboration:
If the only change to a file is a change in permissions (e.g., chmod o+r filename), attempts to commit the file fail with a message saying that the file has not changed.
If I commit a file with permissions 600 (rw-------), then clone the repo, the same file in the clone has permissions 664 (rw-rw-r--):
: nr#yorkie 6522 ; hg clone one two
updating working directory
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
: nr#yorkie 6523 ; ls -l one two
one:
total 4
-rw------- 1 nr nr 8 Aug 18 21:50 foo
two:
total 4
-rw-rw-r-- 1 nr nr 8 Aug 18 21:51 foo
This examples shows that hg clone does not preserve permissions, but hg push does not preserve them either.
In my application, one repo is on a publically accessible path, and it's of major importance that
Multiple users have the right to change the repo
Files in the public repo become readable only when explicitly made readable.
It looks like it can be done using hooks and an auxiliary tool (and a little chewing gum and baling wire):
Get David Hardeman's Metastore, which saves and restores file metadata.
Alter the sources so it will ignore directory .hg as well as .git.
Use the following Mercurial hooks:
precommit.meta = metastore -s
changegroup.update = hg update
update.meta = /usr/unsup/nr/bin/metastore -a
You have to add the .metadata file to the repo.
This lashup will work most of the time, but if you change only permissions and want to propagate it, you'll have to run metastore -s in order to push those changes into the .metadata file where hg will see the change; otherwise the commit thinks nothing is new.
What about using this solution from the Mercurial FAQ:
If you're using Mercurial for config
file management, you might want to
track file properties (ownership and
permissions) too. Mercurial only
tracks the executable bit of each
file.
Here is an example of how to save the
properties along with the files (works
on Linux if you've the acl package
installed):
# cd /etc && getfacl -R . >/tmp/acl.$$ && mv /tmp/acl.$$ .acl
# hg commit
This is far from perfect, but you get the idea. For a more sophisticated solution, check out etckeeper.
For the specific case of the /etc directory, etckeeper looks interesting.
I assumed that metastore was abandonware due to the dead git link on author's site so I whipped the below which is placed directly in repo's .hc/hgrc configuration file:
[paths]
default = ...
[hooks]
# NOTE: precommit is different than pre-commit, see https://www.mercurial-scm.org/repo/hg/help/hgrc for list of hooks
pre-commit =
# export permissions
hg st -camn0 | sort -z | xargs -0 getfacl > .hg.hook.pre-commit.acl.export
hg add .hg.hook.pre-commit.acl.export
# export timestamps
hg st -camn0 | sort -z | xargs -0 stat > .hg.hook.pre-commit.stat.export
hg add .hg.hook.pre-commit.stat.export
update =
# import permissions
setfacl --restore=.hg.hook.pre-commit.acl.export
# import timestamps
# TODO: use touch to restore timestamps
It is not good idea to store permissions in VCS. However, Mercurial supports "executable" flag (that is not the same as permissions, although in Unix executable flag is part of permissions).