Mercurial: Resync working directory with .hgignore file - mercurial

I just opened up a project that had the .hgignore file set up entirely wrong. I have fixed it to what it should be, and now I have to remove all the stuff that it was previously not ignoring and now should. Maybe its just early in the morning, but any way to do that other than manually?

(requires Mercurial >= 1.9)
$ hg forget "set:hgignore() and not ignored()"
see hg help filesets for more

Related

Mercurial: Unable to unshelve shelved changes

It seems like ShelveExtension only shelves your modified files leaving untracked or deleted.
I am new to Mercurial and coming from git so for me this is not expected.
Even bigger problem I am not able to hg unshelve with what I assume is an error message.
See below:
unshelving change 'main'
temporarily committing pending changes (restore with 'hg unshelve --abort')
rebasing shelved changes
abort: uncommitted changes
Is that an expected behavior and I am just missing something?
How could I unshelve my modified files without restoring/committing/etc.?
Is there an extension which behaves exactly like git stash?
Steps to reproduce:
Environment:
OS: Windows 8
Mercurial: Mercurial Distributed SCM (version 3.0.1).
Installed as cygwin /usr/bin/hg (Tortoisehg is not installed, Windows hg is installed but not used)
Extension: ShelveExtension.
Is that an expected behavior and I am just missing something?
Yes, this is normal behavior. You need to do hg addremove (or manually hg add and hg rm the individual files) if you want Mercurial to track file creation and deletion. Renaming should be done with hg mv. This is vaguely similar to git add, except that you do not need to do it for modified files.
When you unshelve, your working directory should be clean. At the very least, it should not have any missing files (prefixed with ! in hg st) nor any modified files (prefixed with M). You can always make a temporary commit and hg strip it later.
How could I unshelve my modified files without restoring/committing/etc.?
There's no sane way to do this in the general case. What if the shelf contains changes to a file which no longer exists? If the file deletion had been committed, you could generate a patch conflict, and that's what Mercurial does. But without a commit to conflict with, there's no obvious response to this situation.
Is there an extension which behaves exactly like git stash?
Not to my knowledge, but this is beyond the scope of StackOverflow.

Remove file from a commit in Mercurial

I have a commit onto which I have amended some files. Some of these files that were part of the amend I do not want in this commit. Is there a way in Mercurial to remove certain files from the commit without losing the changes I have made to them? Thank you.
Steps:
Made some changes
hg commit -m
Made some more changes (some of these file accidentally amended)
hg amend
Try out:
hg forget somefile.txt
hg commit --amend
If the file was new (i.e. you had used hg add).
If that file already existed try:
cp somefile.txt somefile.txt.bak
hg revert somefile.txt --rev .~1
hg commit --amend
Which is basically telling mercurial to revert the file (somefile.txt) back to the state it was one revision ago (--rev .~1).
Just make sure to back up the file you are reverting before entering the command so that you do not lose your changes. I was under the impression mercurial does this automatically for you, but after testing it quickly I'm not so sure.
hg uncommit somefile.txt does exactly this for me.
Like plain git reset, it removes the change from the commit but leaves the file contents unchanged, so now hg diff shows the change you just uncommitted.
The uncommit command claims to come from the uncommit extension, but may actually be coming from the evolve extension, I admit I'm not 100% sure!

How to Hg Shelve Added files uncommitted yet

I am using Mercurial Shelve extension to shelve changes from command line. It works nice except when the changes that i like to shelve contain new added files(a) in working directory. Basically, it shelves everything except the new added files. I checked this by looking at the .hg/shelve stored changes.
How to shelve new added files (a status)?
This response is overdue, but you can use the following command to shelve all files (track / untrack) :
hg shelve -A
or
hg shelve --addremove
About this command, documentation says :
mark new/missing files as added/removed before shelving
You must pay attention by using this feature because after unshelving, your old untracked files are track.
These file are already to be commited in the last commit if no files are specified in hg commit command. You should use hg forget if you want untracked them again.
I assume you are talking about currently untracked files? You need to add the first.
So just do hg add for your new files and then hg shelve will also shelve them.
Thank you Tom. I am using Mac, so it didn't really worked. What did work was another mercurial extension 'hgattic' about which you can read more in my blog
http://margotskapacs.com/2012/10/shelving-uncommitted-changes-in-mercurial/
(see section 'Bug – Added Files Unable Shelve')
If the command line isn't absolutely necessary:
then just type (on Linux)
thg shelve
This allows you to easily shelve added (but not yet committed) files.
As a mostly Git user, I find Atlassian SourceTree the easiest way to deal with the odd Mercurial repo that I have to work with. It has shelving built in. The price is right, too (free).
Disclaimer: I work for Atlassian

Mercurial, how to remove file from repository?

I push in our repository more big video files, my fault, I did not notice them and forgot to add the folder with the video to ignore file. Now my friends can not upgrade because a shortage of memory (abort: out of memory). How do I remove a video from the master repository? I tried to just delete the folder with the video in /home/hg/project/.hg/ But then do not start updating with an error. Help me pliz and sorry for my english/
See the Mercurial FAQ:
4.14. I committed a change containing nuclear launch codes, how do I delete it permanently?
4.15. I committed a large binary file/files, how do I delete them permanently?
There are some options described on the Editing History page as well.
You:
$ hg rm video.ogv
$ hg ci -m "removed video.ogv"
Other:
$ hg pull your-repository
$ hg update
The HG FAQ merely gives a few vague pointers. Here's how to do it:
Add to your .hgrc:
[extensions]
hgext.convert=
[convert]
hg.saverev=false
Create a filemap of what files you want to remove (myfilemap)
exclude "relative/path/to/file.mp4"
Use hg convert to make a new repo
hg convert --filemap myfilemap myrepo myrepo.new
Now you have the new repo without the excluded files.

Can Mercurial use .hgignore to forget files?

I forget to place the correct .hgignore into my project and am now confronted with many useless files in my repository. As these files are already under source control .hgignore will not pick em up.
Is there a way for hg to forget all files matched by .hgignore?
filesets awesomeness (requires 1.9):
hg forget "set:hgignore() and not ignored()"
You need to remove that file for it to be ignored.
hg remove -Af myfile
(remove from the revision while leaving a copy on your workspace: or hg forget)
But your Mercurial repository won't "forget" those same files in the previous revisions.
Removing a file does not affect its history.
It is important to understand that removing a file has only two effects.
It removes the current version of the file from the working directory.
It stops Mercurial from tracking changes to the file, from the time of the next commit.
Removing a file does not in any way alter the history of the file.
Another way, when you have a lot of extra files you need now to ignore is:
remove them (from the file system, not with an hg command, but with an OS 'rm' command)
hg addremove (warning, it will add currently non-committed files, but it will hg remove all the other files you just rm'ed)
See How to forget all removed files with Mercurial for more.
I don't think hg can do it out of box.
But it's pretty easy to roll your own. hgignore entries are regexp or glob, so you can just go through the entries and find the matching files/dirs and do "hg remove" on them.
For hgignore parsing/matching, if you use python you can just call the functions in hg's ignore.py.
Maybe someone can write an extension for this.
This is what I did for each of the directories mentioned in .hgignore
for /f "delims=" %i in ('dir bin /ad/s/b') do hg forget %i/
And for files
for /f "delims=" %i in ('dir *.user /s/b') do hg forget %i
DISCLAIMER:
I don't know if it will work on non-windows OS or not.
Idan K's solution is great. I added an alias to my global mercurial.ini because I can't remember the command.
[alias]
forgetignored = forget "set:hgignore() and not ignored()"