Mercurial extension to automatically generate .hgignore file? - mercurial

I have been thinking that it sure would be nice to have a command like "hg ignore" that would automatically add all untracked files to the .hgignore file.
Manually editing the .hgignore file is powerful, but when I am frequently creating new repositories it would be nice to be able to add only the files I want and then do an hg ignore to automatically have Mercurial ignore any others.
Does anyone know of any extensions that do this?

Try this once you've added all the files you need:
hg stat --unknown --no-status >> .hgignore
You can create a command to automatically generate your .hgignore using an alias. On a Unix-like system, add the following lines to your .hg/hgrc (or one of Mercurial's other configuration files):
[alias]
ignore = !echo 'syntax: glob' >> $(hg root)/.hgignore && \
$HG status --unknown --no-status >> $(hg root)/.hgignore
This will give you a hg ignore command that will populate the .hgignore file with all currently unknown files, thus turning them into ignored.
On Windows, the syntax for the alias is:
[alias]
ignore = !echo syntax: glob > .hgignore && "%HG%" status --unknown --no-status -X .hgignore >> .hgignore
On Windows, you must run it in the root directory of the repository, otherwise the .hgignore file will be created in the current directory, which is probably not what you want.
The ! syntax in aliases is new in Mercurial 1.7. In earlier versions you can add
[alias]
ignore = status --unknown --no-status
and then redirect the output of this command to the .hgignore file yourself:
hg ignore >> .hgignore
You will then also need to take care of adding a syntax: glob line, if necessary (the default syntax is regular expressions).

Related

Mercurial how to ignore subfolder containing files already added to source control

I have a project with following structure
project_dir/
WebContent/
es5/
...
src/
...
.hgignore
I'm tring to ignore everithing under WebContent/es5 directory using following patterns:
syntax: glob
WebContent/es5/**
or
syntax: regexp
^WebContent/es5
or
syntax: regexp
^WebContent/es5$
but modified files in the folder are still being tracked. Could anybody please help me with it?
The clue is in the documentation for ignore files:
The Mercurial system uses a file called .hgignore in the root
directory of a repository to control its behavior when it searches for
files that it is not currently tracking.
If you've added a file in a subdirectory to the repo (either explicitly or before you added the pattern to the .hgignore file) mercurial will remember it until you hg forget it.
% hg init foo
% cd foo
% ls
% mkdir sub
% cat <<EOF > .hgignore
^sub/
EOF
% touch a
% touch sub/b sub/c
% hg st
? .hgignore
? a
% hg add sub/b
% hg st
A sub/b
? .hgignore
? a
% hg forget sub
removing sub/b
% hg st
? .hgignore
? a
There's an example given in the documentation on how to forget all files which are excluded by .hgignore:
- forget files that would be excluded by .hgignore:
hg forget "set:hgignore()"

hg remove all files listed in .hgignore

I have a mercurial repo with .hgignore file. I want to remove all files from disk (hg remove) in this repo which match pattern(s) listed in .hgignore.
I can list all ignored files with hg status -i but I don't know how can I delete them.
.hgignore contents:
syntax: glob
build
\.egg*
*.pyc
.DS_Store
*.sublime-*
You can only run hg remove on files that are tracked. To remove tracked files that match the .hgignore patterns, run this command
$ hg forget "set:hgignore() and not ignored()"
This uses a fileset to select the right files.
If you want to remove files that are already ignored by Mercurial (not tracked), then see the purge extension. That can be used to cleanup a working copy so that it looks like a fresh checkout.
From hgrc help
A better example might be:
purge = !$HG status --no-status --unknown -0 | xargs -0 rm
which
will make hg purge delete all unknown files in the repository in the
same manner as the purge extension.
In order to delete ignored files instead of unknown you have ("hg help status") use --ignored | -i option instead of --unknown

Why does .hgignore appears in my patches?

I use Mercurial Queues to work with patches.
There was no .hgignore initially.
I'm not sure if I first created an MQ patch and then created my .hgignore or the other way round.
(By "creating a patch" I mean hg qnew patch_name -m "...")
Anyway, I made some changes to .hgignore after I created the MQ patch.
When I did hg qrefresh; hg export qtip I got the changed contents of .hgignore also in my patch.
So, tried adding an .hgignore entry to .hgignore itself. But that didn't work. The changes persisted.
So, I tried hg forget .hgignore and this made a bigger mess. It nows shows that I deleted .hgignore in my patch. Like so:
--- a/.hgignore
+++ /dev/null
- all
- the lines of .hgignore
- the lines of .hgignore
How do I resolve this problem?
I just want .hgignore to be part of my local repo and help in not tracking some files.
.hgignore is designed to be tracked by Mercurial (doc). The standard way to ignore files in local clone only is to use ui.ignore setting:
# .hg/hgrc
[ui]
ignore = /path/to/repo/.hg/hgignore
If you have multiple local ignore files then you can write
[ui]
ignore.first = /path/to/repo/.hg/firstignore
ignore.second = /path/to/repo/.hg/secondignore
Additional global ignore files can be configured in this way:
[ui]
ignore.first = /path/to/repo/.hg/firstignore
ignore.second = /path/to/repo/.hg/secondignore
ignore.third = ~/thirdignore
All settings live in hgrc file. More details here:
hgrc file location: doc
ui.ignore setting reference: doc
about .hgignore files: doc
original recipe: Tips And Tricks

hg remove -I PATTERN, how it works?

Ho to remove all *.bak or *.orig files in mercurial?
example:
C:\dev\web>hg stat
? Views\System\UnderConstruction.cshtml.bak
? Views\Topic\Index.cshtml.bak
? Views\Topic\MasterPage.cshtml.bak
? Web.config.bak
C:\dev\web>hg rem -I *.bak
abort: no files specified
hg remove only removes files that have already been committed. AFAIK, there is no command in mercurial to remove untracked files.
To learn how file patterns work in mercurial, run hg help patterns.
Untracked files ("?" sign) can be removed by OS, not Mercurial
You have to leave files as is, just add patterns to .hgignore and after it files, matching patterns, will not apper in hg status anymore
Correct remove command for remove tracked bak and orig files will be hg remove -I **.bak -I **.orig
You should take a look at the hg purge extension:
Delete files not known to Mercurial. This is useful to test local and
uncommitted changes in an otherwise-clean source tree.
This means that purge will delete:
Unknown files: files marked with "?" by "hg status"
Empty directories: in fact Mercurial ignores directories unless they contain files under source control management
But it will leave untouched:
Modified and unmodified tracked files
Ignored files (unless --all is specified)
New files added to the repository (with "hg add")
If directories are given on the command line, only files in these
directories are considered.
Be careful with purge, as you could irreversibly delete some files you
forgot to add to the repository. If you only want to print the list of
files that this program would delete, use the --print option.
You can do the following two commands:
D:\workspace>hg purge -I **/*.orig --all
and then:
D:\workspace>hg purge -I **/*.bak --all
Tracked files won't be deleted, but I'm guessing that's not an issue for you. Make sure that you enable the purge extension before running this, and you can do dry runs with the --print argument.

Mercurial: warn when adding files which would otherwise be ignored?

How can ask Mercurial to warn me before I add files which would otherwise be ignored?
For example, something like:
$ hg add foo.o
warning: adding ignored file foo.o
There seems to have been a patch submitted to the mailing list: https://www.mercurial-scm.org/pipermail/mercurial-devel/2008-February/004993.html
But I can't find any further references to it.
Use hg addremove. It will not add ignored files.
Extract from addremove documentation
New files are ignored if they match any of the patterns in .hgignore. As with add, these changes take effect at the next commit.
It's sort of a hacky workaround and only half what you want, but you could replace
$ hg add foo.o
with
$ hg add -I foo.o
That says "add everything but only if it's not ignored and it matches the pattern after -I".
An example:
$ ls -A
.hg .hgignore this
$ cat .hgignore
this
$ hg stat --all
? .hgignore
I this
$ hg add -I this
$ hg stat --all
? .hgignore
I this
So you can see that "this" wasn't added and is still in ignored state. Of course, that's not a warning, it's a refusal.
This won't help much on add, but you could catch it during commit by using a
pretxncommit hook.