hg remove -I PATTERN, how it works? - mercurial

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.

Related

Mercurial: how to revert changes purging files except those ignored (covered by '.hgignore')?

I made some exploratory changes to my code in a project under mercurial version control, so afterwards I wanted to discard all changes and go back to the last version in the remote repo.
hg pull
hg update -r default -C
hg --config "extensions.purge=" purge --all
What I didn't realize is that this will delete any untracked file, including those ignored. In particular eclipse directories like .settings. Obviously I don't want to delete those.
I know I can use patterns with the purge command, and most of the time I will want to use it only with changes under the source code directory, but if I had made changes not only under src, but also config, added a file at project directory level and whatnot, is there any way that purge could automatically pull files and directories from the .hgignore file to be excluded so I don't have to think all that directories and files in which I have untracked files?
Well... you explicitly used a flag which means "delete everything, even if ignored". From hg help purge:
--all purge ignored files too
So it should work, if you skip the '--all' parameter to purge.

Why don't mercurial file sets work when adding files?

I'm trying to use mercurial file sets to add all the files in a directory tree, excluding very large files and any binary files. Cribbing from the mercurial documentation, this command should do it:
hg init
hg add 'set: size("<1M") and not binary()'
However this returns a status code of 0, and hasn't added anything to my new, empty repo. I've tried just 'set: not binary()' and that didn't work either.
The frustrating thing is that although I can google for mercurial file sets, and find lots of examples, I can't find anything to help troubleshoot when it doesn't work!
I don't have a .hgignore file, and it's a fresh empty repo. Mercurial 4.2.2.
The directory where I'm testing this has a couple of artificially created files for the purpose of testing. In my real use case, I inherit a multi-gigbyte tarball of assorted sources and binaries from a client, and I want to get all the sources into mercurial before I start hacking to fix their problems, hence the need to exclude the binaries and large files that otherwise choke mercurial.
Here's my little test script:
#!/bin/sh -ex
dd if=/dev/urandom of=binary_1k bs=1 count=1024
dd if=/dev/urandom of=binary_2M bs=1 count=2097152
echo "This. Is, a SMALL text file." > text_small
hexdump binary_1k > text_1k
hexdump binary_2M > text_2M
ls -lh
file binary_1k
file binary_2M
file text_1k
file text_2M
hg init
hg add 'set: size("<1M") and not binary()'
hg status -a
hg add 'set: not binary()'
hg status -a
hg add 'set: size("<1M")'
hg status -a
At the end of this, each status command reports no files in the repo, and the add commands report no errors.
The problem is that file sets do a query of Mercurial's repository data base, which knows only about files that are part of the repository or have been added.
One solution is to add all, and then to get rid of the files that you don't like, e.g.:
hg forget 'set:size(">1M") or binary()'
This works, because the query also requires recently added files, even if they haven't been committed yet.

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

hg remove directory from repo?

I'd like to remove a directory and all the files in it from a repo.
I have removed all the files with hg remove, but how do I remove the directory itself?
Will it just automatically vanish once I commit all the removed files?
Yes. Because mercurial doesn't track directories at all, only files, it only creates directories that have files in them, and if someone hg updates to a revision any directories that become empty are automatically removed. So if you do:
hg remove directory/*
hg commit -m 'removed all files in directory'
hg update -r 0 # updates to a different revision
hg update tip # jump back to the tip
That last update would remove the directory. For everyone else it's even easier. When they hg update to your new changes their directory will just vanish (provided they have no uncommitted file in it).
hg remove dir
If you end up with empty directories and you want to get rid of them, an easy way is the purge extension. (add purge= under the [extensions] group in your .hrgc file to unlock).
You can then use
hg purge
to clean up the empty dirs... You must be careful with the purge command as it removes everything that is untracked in your repos. I strongly suggest you run a
hg purge -p
beforehand to see what the command will do ( -p will print a "test run" without doing anything.) Never forget the --help option! ;)
edit: I prefer using purge to hg update in succession as updating triggers rebuilds in my IDE if it is open (and it's a good bet it is when I do that). hg purge will probably be smoother. And you can use --all to include ignored files too (must be careful though).
To remove a directory, Just do
hg remove <dir>
hg commit -m "..."
This will remove the directory and all files under it.

Using hg revert in Mercurial

I'm using Mercurial. I made a clone of a repository. For debugging, I changed a few lines of code in a java file. I did not commit those changes though. I just want to revert them back to their original state, as found in the repository. I tried hg revert filename.java, which did revert it, but now when I do hg status, I see additional files added in my folder now like:
? filename.java.orig
Can I just delete those files, and why does Mercurial make them when I use revert?
You can also use the flag --no-backup and the .orig files will not be created
hg revert --no-backup filename.java
As of Mercurial 2.0, you can instead use the flag -C to supress the .orig files from being created
hg revert -C filename.java
Yes, you can delete them. It's a safety feature in case you reverted something you didn't mean to revert.
I find the purge extension handy. Usage:
hg purge
"This extension purges all files and directories not being tracked by
Mercurial"
...including the .orig files but excluding ignored files (unless you use --all).
As other's have pointed out, you can safely delete these files.
You can remove them by executing this command from the root of your repo:
rm `hg st -un | grep orig`
If you want to revert, and don't care at all about backing up the original files, the command you want is:
hg update -C
Those are copies of the files from before you reverted them. If you don't need those, you can delete them, either by hand or by using the Purge extension:
hg clean
These backup files can be created for merge and revert operations (cf. man page). You can add an ignore rule if you want, or simply delete them if you don't need them anymore.
These are rather common, resulting from various operations. A glance at one of the moderate sized repositories I work on finds 237 of them. I don't like deleting things that may end up being useful, and I have no reason to name legitimate files with the same suffix, so I add the following to .hgignore instead:
.\.orig$
I made this batch file myself.
IF "%1%" == "d" (
del /s *.orig
del /s *.rej
) ELSE (
del /s /p *.rej
del /s /p *.orig
)
Help:
Save this content as orig.bat
Run orig d to delete all rejects and orig files at once without confirmation
Run orig to delete files with confirmation [Safety mechanism]
Hope this is helpful.