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.
Related
I have a pretty large folder (with many sub folders) on a mercurial repository. I was a bit too fast with my first commit so I added a lot of files that i now realize shouldn't be on version control. I've updated my .hgignore file accordingly but all the old files are still version controlled. Is there a command that I can write in the root directory that forgets all files that are in a folder of a specific name. These folder names exist in a lot of places and i want them all forgotten with one command since it would take a long time to go through them all manually and forget the folders/files
I guess it would maybe look something like this:
hg ignore ../folderName/
Yes... use a pattern to match them like
hg forget FOLDERNAME**
hg commit -m "Forget FOLDERNAME"
hg help forget
hg forget [OPTION]... FILE...
(...)
options ([+] can be repeated):
-I --include PATTERN [+] include names matching the given patterns
or use a one-line script:
for i in $(hg ma | grep FOLDERNAME); do hg forget $i; done
You can read hg help filesets and use one of it's samples
Forget files that are in .hgignore but are already tracked:
hg forget "set:hgignore() and not ignored()"
Say I type hg add in Mercurial, and there a bunch of untracked files in my working directory that are not ignored. What is the easiest way to un-add all those files without explicitly typing the name of each file?
Can I just un-add them all with one command?
Preface
You must always ask questions, which contain as much information as possible. Because now your question, depending from some conditions, may have totally different answers.
Case One - no local modifications in already versioned files, only added (and not committed) files
hg revert will return your working directory to the state after the last commit, undoing all changes it it.
Case One - local edits, which you want to save and occasionally added files
Read about filesets in Mercurial.
Use fileset in the hg forget command, something like hg forget "set:added()".
Use hg revert or hg forget on the files (both do the same for a file you ran hg add on). To avoid typing out the filenames, you can use a fileset like this:
$ hg revert "set:added()"
This will revert the file back to how it looked in the working copy parent revision, i.e., it will become unknown again.
hg revert -r .^ path-to-file will revert the commit from the commit-set.
then commit and submit (if using jelly fish) and you'll see the files removed from the changeset. I don't know why .^ works yet, but somebody will probably know.
You could always just re-clone your repository and then replace (delete existing and then copy new) the .hg directory in your working folder with the one from the fresh clone... (assuming you have no pending commits..)
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.
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.
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()"