How to automatically remove all .orig files in Mercurial working tree?
Asked Answered
A

12

58

During merges mercurial leaves .orig file for any unresolved file. But after manually resolving problems and marking a file correct it does not delete the .orig file. Can it be automatically removed by some command?

I work on a Mac so I can use something like:

find . -iname '*.orig' -exec rm '{}' ';'

and alias it or something, but I'd rather use something like hg cleanup...

UPDATE:

Since some time now, Purge extension is bundled with Mercurial and solves this problem nicely.

Abney answered 1/7, 2009 at 7:10 Comment(1)
I would have preferred an answer along the lines of "open ~/.hgrc, go to e.g. the "extensions" section and add the "no-orig" plug-in...wishful thinking?Didi
U
70

Personally, I use

$ rm **/*.orig

if I get tired of the .orig files. This works in Zsh and in Bash 4 after you run shopt -s globstar.

But if you use another shell or want a built-in solution, then maybe you'll like the purge extension (link updated 2016-08-25). That lets you remove all untracked files with

$ hg purge

You can remove all untracked and ignored files with

$ hg purge --all

An advantage of using hg purge is that this will also cleanup directories that become empty after removing the files. The rm command line will just leave the empty directories behind.

Unsuccessful answered 1/7, 2009 at 8:19 Comment(4)
rm is quite short :). But the purge removes all untracked files - and some file I use are not tracked on purpose - private project configuration, database configuration, etc...Abney
Why am I getting downvotes for this? Is it because this only works in shells like Zsh that understand **? I said personally since this is what I use myself, and then I gave a general, cross-platform answer in the form of the purge extension.Unsuccessful
@Martin It doesn't recurse into sub-directories is my guess.Winner
@Keyo: the rm command line does recurse, that's the purpose of the ** part. It wont remove directories that become empty after removing the .orig files. That's a slight advantage of using hg purge. It's rare that directories come and go in my projects, so I hadn't thought of this before.Unsuccessful
P
35

btw. find utility has an action -delete so you can type only:

find <path-to-files> -name '*.orig' -delete

Photogenic answered 12/11, 2012 at 11:18 Comment(0)
B
16

If you just want to delete the .orig files, and you happen to be on a Windows computer, the following seems to work well:

D:\workspace>hg purge -I **/*.orig --all

This will delete all untracked files that end in .orig, but won't delete other untracked files, as the other answers would.

You can test this before running it by putting the --print flag in as well.

Branca answered 14/11, 2012 at 21:35 Comment(2)
I agree this is the best option if you have purge installedAdios
the best option, at all. as some said "I have untracked files on purpose" so this wont remove them. additionally, you can use the flag '-p' before so you can print it instead of removing files. thanks!Ist
C
4

The following will remove .orig files in your entire working copy hierarchy and also works for paths containing spaces:

find . -name *.orig | while read -d $'\n' file; do rm -v "$file"; done;

I use an alias in my .bash_profile:

alias clearorig='echo "Removing .orig files..."; find . -name *.orig | \
while read -d $'\''\n'\'' file; do rm -v "$file"; done;'
Chianti answered 11/3, 2012 at 21:15 Comment(2)
How is that piping through several processes any better than find . -name '*.orig' -exec rm '{}' ';' or even simpler find . -name '*.orig' -delete, where all work is performed by find and rm directly or just by find on its own?Leper
@Mecki, pretty sure it's not, and that it's prone to errors when files contain weird characters...like newlines, for example.Branca
W
2

PowerShell one-liner (recursive):

Get-ChildItem <path> -Recurse -File -Include *.orig | Remove-Item

For example for the current folder and sub-folders:

Get-ChildItem . -Recurse -File -Include *.orig | Remove-Item
Wadley answered 4/5, 2020 at 7:55 Comment(0)
S
1

you should use the update hook

update: This is run after an update or merge of the working directory has finished

Sealskin answered 1/7, 2009 at 7:31 Comment(2)
can you be more more specific? Are you proposing removing all files on commit hook? :)Abney
you can execute find . -iname '.orig' -exec rm '{}' ';' *after a merge, see the doc for detailsSealskin
O
1

I have posted this answer before. But this is the correct place to this answer.

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

  1. Run orig d to delete all rejects and orig files at once without confirmation
  2. Run orig to delete files with confirmation [Safety mechanism]

Hope this is helpful.

Observance answered 23/11, 2012 at 12:40 Comment(0)
P
1

I personally use the following from the root of the repo:

hg purge -p -I **/*.orig | xargs rm -f

It's a little better than using just 'hg purge' or 'hg purge --all' because you can filter out the specific file types you want to include.

For an explaination:

  • The -p argument prints the list of files to be purged
  • The -I argument whitelist filters the files to include
  • The resulting list is piped to xargs and executed using the rm -f command
Phillie answered 11/7, 2013 at 12:48 Comment(2)
Correct me if I'm wrong here, but won't this have all the usual issues that you have when you send output to xargs without using the -0 flags? From the man page: "-0 Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken literally). Disables the end of file string, which is treated like any other argument. Useful when input items might contain white space, quote marks, or backslashes. The GNU find -print0 option produces input suitable for this mode."Branca
@mlissner, you are correct. In my case, we typically didn't put spaces or newlines in filenames, so for the general case this solution above wouldn't work.Phillie
G
1

I'm working in Powershell and didn't see the answer here:

# NOTE: be in the root of your repository
# fetch all .orig files recursively
$orig = (dir *.orig -recurse) ;

# remove each .orig file
foreach ($item in $orig) { del $($item.FullName) ; }

# afterwards I make sure to remove the references to the .orig files in the repo
# then commit & push
hg addremove ; 
hg commit -m "remove .orig" ;
hg push ;
Gracioso answered 9/7, 2015 at 21:50 Comment(0)
H
0

This is not an automatic way of removing extra files, but it's simple enough to run manually.

The hg st can show unknown or not tracked files. You can use this output as an argument to the system rm command. Here's an actual example I just performed:

$ # SHOW ONLY THE CRUFT
$ hg status --unknown
? config/settings.rb.orig
? lib/helpers.rb.orig
? routes/main.rb.orig

$ # THE CRUFT WITHOUT THE "?" PREFIX
$ hg status --unknown --no-status
config/settings.rb.orig
lib/helpers.rb.orig
routes/main.rb.orig

$ # SAFELY REMOVE ALL CRUFT
$ rm -- `hg st -un`

If you have empty directories left behind, the -r and -d flags for rm might help.

As a bonus, hg status --ignored could be used to cleanup all those ignored temp files as well as swap files from your editor (e.g., Vim).

Hose answered 29/9, 2014 at 0:12 Comment(0)
T
0

A command that I use on Linux for cleaning up, saves the need to do a fresh search with find.

These need to be run from the root directory of the Mercurial project

hg status | grep ".orig" | cut -d ' ' -f 2- | xargs rm -f

Or if you want to clear all unknown files.

hg status | cut -d ' ' -f 2- | xargs rm -f

Tetravalent answered 1/12, 2015 at 22:2 Comment(0)
D
-1

I don't like the chosen answer. It doesn't removed everything within all levels of the project. I use this:

for f in `find . | grep .orig$`; do rm "$f"; done

Works on both Mac and *nix

Detta answered 19/1, 2012 at 20:2 Comment(4)
This is not a good answer: file names with spaces will break the rm invocation. Please let me know if you fix the answer so that I can remove the down vote.Unsuccessful
You need to add double quotes "" around the variable $f. This is a common problem in a lot of scripts that operate on files and directories, including Apple documentation (which I notified them to update years ago and still has incompatible script examples) :PPhillie
@CollinKlopfenstein: Imagine you have files named foo.txt and bar baz.txt. The find call will return foo.txt\nbar baz.txt\n and the for loop will split this into three files: foo.txt, bar, and baz.txt. Only the first name is correct. This is why you need find -print0 or should let find execute rm.Unsuccessful
How is that piping through several processes any better than find . -name '*.orig' -exec rm '{}' ';' or even simpler find . -name '*.orig' -delete, where all work is performed by find and rm directly or just by find on its own?Leper

© 2022 - 2024 — McMap. All rights reserved.