Mercurial is presently ignoring a file which I believe shouldn't be ignored. The .hgignore file is remarkably large, and after a cursory read-through it's not obvious which rule(s) is/are the culprit.
Is there a way to get Mercurial to tell me which rules in the .hgignore (if any) match a file?
You can't do this out of the box, but you can write Mercurial extension for this.
I've written extension hg-isignored that can show you which rules in .hgignore match specified folder or file.
Installation
Clone extension source somewhere, i.e. in ~/.hgrc.d/hg-isignored folder:
hg clone https://hg#bitbucket.org/rpeshkov/hg-isignored ~/.hgrc.d/hg-isignored
Add extension in extensions section of your .hgrc file:
[extensions]
isignored=~/.hgrc.d/hg-isignored/hg-isignored.py
Now Mercurial will be able to use isignored command that's implemented by extension.
Usage
While you're in Mercurial repository, run command hg isignored PATH, where instead of PATH insert folder or file that you want to check, i.e. hg isignored readme.txt. Extension will tell you if specified PATH is ignored and will show you used rule.
Testing
Init
[~/hgtest]% hg init
No .hgignore
[~/hgtest]% touch readme.txt
[~/hgtest]% hg st
? readme.txt
[~/hgtest]% hg isignored readme.txt
abort: .hgignore file not found
Added .hgignore
[~/hgtest]% echo "syntax: glob" > .hgignore
[~/hgtest]% echo "readme.txt" >> .hgignore
[~/hgtest]% hg st
? .hgignore
[~/hgtest]% hg isignored readme.txt
Path 'readme.txt' is ignored by:
relglob:readme.txt
Not ignored file
[~/hgtest]% touch readme2.txt
[~/hgtest]% hg isignored readme2.txt
Path 'readme2.txt' is not ignored
Ignore folder
[~/hgtest]% mkdir build
[~/hgtest]% touch build/keep.txt
[~/hgtest]% echo "build/" >> .hgignore
[~/hgtest]% hg st
? .hgignore
? readme2.txt
[~/hgtest]% hg isignored build
Path 'build' is ignored by:
relglob:build/
[~/hgtest]% hg isignored build/keep.txt
Path 'build/keep.txt' is ignored by:
relglob:build/
Ignore everything in folder
[~/hgtest]% echo "syntax: glob" > .hgignore
[~/hgtest]% echo "build/*" >> .hgignore
[~/hgtest]% hg st
? .hgignore
? readme.txt
? readme2.txt
[~/hgtest]% hg isignored build
Path 'build' is not ignored
[~/hgtest]% hg isignored build/keep.txt
Path 'build/keep.txt' is ignored by:
relglob:build/*
Related
Mercurial is presently ignoring a file which I believe shouldn't be ignored. The .hgignore file is remarkably large, and after a cursory read-through it's not obvious which rule(s) is/are the culprit.
Is there a way to get Mercurial to tell me which rules in the .hgignore (if any) match a file?
You can't do this out of the box, but you can write Mercurial extension for this.
I've written extension hg-isignored that can show you which rules in .hgignore match specified folder or file.
Installation
Clone extension source somewhere, i.e. in ~/.hgrc.d/hg-isignored folder:
hg clone https://hg#bitbucket.org/rpeshkov/hg-isignored ~/.hgrc.d/hg-isignored
Add extension in extensions section of your .hgrc file:
[extensions]
isignored=~/.hgrc.d/hg-isignored/hg-isignored.py
Now Mercurial will be able to use isignored command that's implemented by extension.
Usage
While you're in Mercurial repository, run command hg isignored PATH, where instead of PATH insert folder or file that you want to check, i.e. hg isignored readme.txt. Extension will tell you if specified PATH is ignored and will show you used rule.
Testing
Init
[~/hgtest]% hg init
No .hgignore
[~/hgtest]% touch readme.txt
[~/hgtest]% hg st
? readme.txt
[~/hgtest]% hg isignored readme.txt
abort: .hgignore file not found
Added .hgignore
[~/hgtest]% echo "syntax: glob" > .hgignore
[~/hgtest]% echo "readme.txt" >> .hgignore
[~/hgtest]% hg st
? .hgignore
[~/hgtest]% hg isignored readme.txt
Path 'readme.txt' is ignored by:
relglob:readme.txt
Not ignored file
[~/hgtest]% touch readme2.txt
[~/hgtest]% hg isignored readme2.txt
Path 'readme2.txt' is not ignored
Ignore folder
[~/hgtest]% mkdir build
[~/hgtest]% touch build/keep.txt
[~/hgtest]% echo "build/" >> .hgignore
[~/hgtest]% hg st
? .hgignore
? readme2.txt
[~/hgtest]% hg isignored build
Path 'build' is ignored by:
relglob:build/
[~/hgtest]% hg isignored build/keep.txt
Path 'build/keep.txt' is ignored by:
relglob:build/
Ignore everything in folder
[~/hgtest]% echo "syntax: glob" > .hgignore
[~/hgtest]% echo "build/*" >> .hgignore
[~/hgtest]% hg st
? .hgignore
? readme.txt
? readme2.txt
[~/hgtest]% hg isignored build
Path 'build' is not ignored
[~/hgtest]% hg isignored build/keep.txt
Path 'build/keep.txt' is ignored by:
relglob:build/*
Situation
$ cat .hgignore
.hgignore
$ hg status
M file1
M file2
M src/project.xml
I don't want to track the project.xml so I run
echo "project.xml" >> .hgignore
and the result is
$ cat .hgignore
.hgignore
project.xml
$ hg status
M .hgignore
M file1
M file2
M src/project.xml
So the .hgignore is now as modified even though it shouldn't be tracked and nothing happend with the project.xml. What does this mean?
You wrote:
"M src/project.xml"
which means that src/project.xml is under version control.
A file already under version control cannot be ignored! The
.hgignore file is for ignoring files that are untracked (status
will show a "?").
You have two solutions to ignore your file:
You can either "hg forget" the file, the opposite of "hg add" (i.e.,
telling Mercurial not to track this file anymore), or
You can use the ”-X” option as a default for status/diff/commit
in your .hg/hgrc configuration file, e.g.,
[defaults]
status = -X <file>
diff = -X <file>
commit = -X <file>
which will tell hg not to include this file in the use of status, diff, and commit.
What is the Mercurial equivalent of the command git checkout removedFile? The word removedFile means the removal by the basic-shell rm -command, not by git rm -command.
hg revert removedFile
should put your missing file back.
What does git checkout removedFile do for you? For me it give a nice, sensible error:
ry4an#four:~$ git init test
Initialized empty Git repository in /home/ry4an/test/.git/
ry4an#four:~$ cd test/
ry4an#four:~/test$ echo this > file
ry4an#four:~/test$ git add file
ry4an#four:~/test$ git commit
[master (root-commit) 1b017c5] file added
1 file changed, 1 insertion(+)
create mode 100644 file
ry4an#four:~/test$ git rm file
rm 'file'
ry4an#four:~/test$ git commit
[master ec695d4] dsdfsdf
1 file changed, 1 deletion(-)
delete mode 100644 file
ry4an#four:~/test$ git checkout file
error: pathspec 'file' did not match any file(s) known to git.
If you're asking how you can view the contents of a removed files hg cat is a fine command to do it, and you can find a revision id using hg log removedFile.
working directory
Did a
hg commit (resulted in rev3)
Copied some directories inside ... changed some files. Did
hg add
hg commit (resulted in rev4 - tip)
How to get back exactly to the state of rev3. hg update 3 will change the files to the state they were in rev3, but it will also leave all the copied directories inside. I want to get the working directory without the copied directories and files, which were added after rev3.
That doesn't happen for me:
> hg init
> mkdir first
> jed first/foo.txt
> hg add
adding first/foo.txt
> hg commit -m asd
> mkdir second
> jed second/foo.txt
> hg add
adding second/foo.txt
> hg commit -m asd
> hg update 0
Now first exists, but second doesn't...
Are you sure you added everything in the new directories before your commit?
Like Jon writes, Mercurial will normally try to clean up after itself. So when you hg update you should get back exactly what you committed. What I guess you're seeing is the following behavior:
$ hg init repo
$ cd repo
$ echo "# some C program" > foo.c
$ hg add foo.c
$ hg commit -m first
$ mkdir dir
$ echo "$ other C program" > dir/bar.c
$ hg add dir/bar.c
$ hg commit -m second
$ echo "object file" > dir/bar.o
$ hg update 0
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ ls
foo.c dir
$ ls dir
bar.o
So the untracked dir/bar.o file has been left behind, but the tracked dir/bar.c file has been correctly removed. That is: Mercurial wont delete untracked files since it doesn't know if they contain valuable data. This applies even if the files are ignored by a pattern in .hgignore. If the directory had only contained the tracked dir/bar.c file, then the directory would have been completely removed when you update to a revision where it isn't needed.
The normal way to clean up untracked files is to use the purge extension.
In the documentation they use a mapfile with these contents:
$ echo include subfoo > /tmp/myfilemap
$ echo rename subfoo . >> /tmp/myfilemap
$ hg convert --filemap /tmp/myfilemap /path/to/repo/foo /tmp/mysubfoo-repo
What are the advantages of merging 2 repos like. Is there a valid reason not to do this:
hg pull -f other_repo
hg merge
What are they accomplishing via the rename of subfoo to . ?
Their example (the subfoo filemap you posted in your question) is for converting a subdirectory of an existing repo to a repository of its own, with all the history of the files under that subdirectory. The rename of subfoo to . means that all files and directories of the directory subfoo in the source repo will now be under the root of the new repo.
You could use a filemap with rename to do the opposite and to make the contents of the root of repo A now the contents of a subdirectory, then combine it with repo B using pull:
> echo rename . subfoo > /tmp/myfilemap
> hg convert --filemap /tmp/myfilemap /path/to/repoA /path/to/repoA_converted
> hg -R /path/to/repoB pull -f /path/to/repoA_converted
> hg merge
However, subrepos might be a better alternative to that.