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

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.

Related

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

Resolving conflicts: how to accept "their" changes automatically?

When merging conflicting changes using hg merge, Mercurial inserts a set of markers into the files to be merged in my working copy like this:
<<<<<<< local
version = 0.2
=======
version = 0.1
>>>>>>> other
Then I manually edit all files marked as U from a list produced by hg resolve --all -l and then I tell mercurial I have resolved them by hg resolve -m file1 file2 file3 ...
In many situations I would like however accept either my-only or their-only changes on some conflicting files. I am thinking to create two simple sed/awk/whatever scripts named accept-theirs.sh and accept-my.sh or is there any "proper" way to do it?
Use
hg resolve -t internal:other --all
to accept theirs and
hg resolve -t internal:local --all
to accept yours
Try this:
hg merge --tool internal:other
See also hg help merge-tools for more information.

Generating patches in Mercurial

I've looked for that in the manual, but I can't generate a patch for the last commit.
I tried
hg qnew patch_name
but it does only file with
# HG changeset patch
# Parent a6a8e225d16ff5970a8926ee8d24272a1c099f9c
I also tried
hg export tip
but it doesn't do anything. I committed the changes exactly.
How to generate a patch file with the last commit in?
The command to do this is export:
$ hg export -o FILE -r REV
It doesn't require redirection and will thus work correctly on any platform/shell.
Your hg export tip is the best way to do it, and the hg diff and hg log based answers are just lesser versions of the same. What exactly do you see/get when you type hg export tip? What does the output of hg log -p -r tip show?
The changeset tip is just means "the changeset that most recently arrived in my repository" which isn't as useful a concept as you might think, since hg pull and hg tag all create changesets too. If you really want the last thing you committed you'll need a more precise revspec.
Like so:
hg diff -r tip > tip.patch
You can use this command:
hg log -r tip -p > tip.patch
this will generate a patch for just that revision.
If you want to convert the latest commit to a patch file, use
hg qimport -r tip
This will replace the topmost regular commit with an applied MQ patch file.
To generate patches using "mq extensions" in mercurial, you can follow the below given steps. This will create a patch using mercurial:
1) Enabling mq extensions: Add the following lines to your hgrc file and save it.
[extensions]
mq =
2) Creating a patch using mq extensions: To create a patch using mq extensions you can do the following.
hg qnew -e -m "comment you want to enter" bug_name.patch
In the above command, -e flag is for editing the patch and -m flag is for adding a message to the patch.
3) Updating the patch: For updating the patch, you can use the following command when a patch is already applied.
hg qrefresh

How can I make a special file filter for mercurial revert command?

I need to revert all files in a working directory that match the name "test" anywhere inside the filename.
Is it possible to revert all this 3 files by using hg revert -I syntax:
/includes/atest.txt
/test.txt
/test/test/test.txt
It should work (I cannot test it right now) with the following syntax, according to issue 1697:
Windows:
hg revert "glob:*test.*"
# or
hg revert -I "*test.*" --all
Unix:
hg revert 'glob:*test.*'
hg revert -I '*test.*'
(Note the simple quotes for Unix)
As noted by Blaise in the comments
On macOS/Unix, you need to use ** if you want to match files in any directory, e.g.
hg revert -I '**/*test.*'
To expand on the given answer above
You can include all files in subdirectories in your revert by using the following syntax:
Windows:
hg revert "glob:**\*test.*"
And I assume Unix would be:
hg revert 'glob:**/*test.*'

Undo a remove action in Mercurial

Suppose that I have made some changes in the working directory and accidentally marked several files (that include some of the modified ones) for removal. How do I unmark the files for removal without losing the changes I have made?
Just hg add the files.
I don't know why you're getting some many answers that modify the working directory. If you've accidentally marked some files for removal you can undo it with add.
ry4an#four:~/hgtest$ hg status --all
M another_file
C a_file
ry4an#four:~/hgtest$ hg remove --after --force *
ry4an#four:~/hgtest$ hg status --all
R a_file
R another_file
ry4an#four:~/hgtest$ hg add *
ry4an#four:~/hgtest$ hg status --all
M another_file
C a_file
That said, don't use --force with hg remove or ever really. Also try to get in the habit of using hg forget instead of hg remove --after,
there are two options using hg revert :
hg revert -a
which will go back to the previous revision and put all your changes in new files with .orig appended to the names
hg revert [names of files to unremove] to just revert those files
i'd probably go with the latter
hg revert
I'm pretty sure Mercurial even makes backups of your changes by default.
If the file exists, (likely if you've marked it for removal with hg forget or if you've modified it then hg removed it), do hg add [file] to add it back with any changes made after the last commit and before forgetting the file.
If the file does not exist (likely if the file was unmodified and you've marked the file for removal using hg remove), do hg revert [file] to revert it back to its state in the parent of the working directory.
I had the exact same problem. hg add is the inverse to hg forget (just as the opposite is true). However, attempting to re-add the directory itself did not work. Instead, I had to use hg add on each file:
hg st | egrep "^R" | sed -e "s/R //" | xargs hg add
Hope that helps. Note that in my case, there was nothing I legitimately wanted to remove. If you have files you definitely want to remove, adjust the grep accordingly.
Following your comment to jk, I checked hg forget. It seems to be just a shortcut for hg remove -Af, meaning that this is the real opposite of hg add.
Following that, if you've used hg remove -Af, then you should be able to revert that using hg add (I just tried it and seems to work).
The markers are stored in .hg/dirstate file. All you need to do i to get a one from before issuing hg remove -Af. It may look like this (not tested):
hg clone bad-repo orig-repo
cp orig-repo/.hg/dirstate bad-repo/.hg/dirstate
cd bad-repo
hg status
The last command should show the status from before removing files.
I removed a bunch of unmodified files:
hg remove *
This is what I had to do to get them back:
hg revert --all
Nothing else worked. Not hg add not hg add * nor hg revert *