2011年6月4日 星期六

Ignore tracked file in Mercurial without removing it

hgignore only ignore files that have not been tracked before, if you add some files to the repository at previous commits, then you changed your mind, don't want to track those files, list them in .hgignore won't stop Mercurial from tracking them, you need to use `hg rm -Af FILENAME` to remove files from the repository ( files will still exist in the directory ), after commit, Mercurial will really stop tracking those files.

Step by step:
  1. list files in .hgignore ( eg. echo "glob:FILENAME" >> .hgignore )
  2. hg rm -Af FILENAME
  3. hg ci -m "Stop track FILENAME"

My test:
[lefthaha@HOST work]$ mkdir test
[lefthaha@HOST work]$ cd test/
[lefthaha@HOST test]$ hg init
[lefthaha@HOST test]$ touch abc.txt
[lefthaha@HOST test]$ hg ci -Am 'abc.txt'
adding abc.txt
abc.txt
committed changeset 0:1949cce3893d

[lefthaha@HOST test]$ hg st
[lefthaha@HOST test]$ hg head
changeset: 0:1949cce3893d
tag: tip
user: left < lefthaha >
date: Sat Jun 04 17:18:02 2011 +0800
files: abc.txt
description: abc.txt

[lefthaha@HOST test]$ echo "glob:abc.txt" > .hgignore
[lefthaha@HOST test]$ echo ".hgignore" >> .hgignore
[lefthaha@HOST test]$ echo "cde" >> abc.txt

[lefthaha@HOST test]$ hg st
M abc.txt
[lefthaha@HOST test]$ hg ci -m "modify abc.txt"
abc.txt
committed changeset 1:76446b6f8d7f
[lefthaha@HOST test]$ ls
abc.txt
[lefthaha@HOST test]$ hg rm -Af abc.txt
removing abc.txt
[lefthaha@HOST test]$ hg st
R abc.txt
[lefthaha@HOST test]$ ls
abc.txt
[lefthaha@HOST test]$ hg ci -m "hg rm abc.txt"
committed changeset 2:b07e13f2dd28

[lefthaha@HOST test]$ echo "ijk" >> abc.txt
[lefthaha@HOST test]$ hg st
[lefthaha@HOST test]$ echo "ijk" >> abc.txt
[lefthaha@HOST test]$ hg st
[lefthaha@HOST test]$ cat abc.txt
cde
fgh
ijk
ijk
[lefthaha@HOST test]$ hg ci
nothing changed

[lefthaha@HOST test]$ cd ..

# clone the repository
[lefthaha@HOST work]$ hg clone test/ test2
updating to branch default
resolving manifests
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
[lefthaha@HOST work]$ cd test2/
[lefthaha@HOST test2]$ ls
[lefthaha@HOST test2]$ hg st
[lefthaha@HOST test2]$ hg head
changeset: 2:b07e13f2dd28
tag: tip
user: left < lefthaha >
date: Sat Jun 04 17:20:12 2011 +0800
files: abc.txt
description:
hg rm abc.txt

[lefthaha@HOST test2]$ hg log
changeset: 2:b07e13f2dd28
tag: tip
user: left < lefthaha >
date: Sat Jun 04 17:20:12 2011 +0800
files: abc.txt
description:
hg rm abc.txt

changeset: 1:76446b6f8d7f
user: left < lefthaha >
date: Sat Jun 04 17:19:34 2011 +0800
files: abc.txt
description:
modify abc.txt

changeset: 0:1949cce3893d
user: left < lefthaha >
date: Sat Jun 04 17:18:02 2011 +0800 1 123
files: abc.txt
description:
abc.txt

[lefthaha@HOST test2]$ hg update -r 1
resolving manifests
getting abc.txt
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
[lefthaha@HOST test2]$ ls
abc.txt



There is another trick on Mercurial wiki to ignore multiple files in one line command, not tried yet.

Tips and Tricks - 34. Remove files that are matched by .hgignore but were added in error


Reference:
superuser - Can you remove a file from Mercurial without removing it from the filesystem like Git?
hg(1)
hgignore(5)