Linux command to delete all files except .git folder? - linux

I want to delete all of the current directory's content except for the .git/ folder before I copy the new files into the branch.
What's the linux command for that?

Resetting the index is cheap, so
git rm -rf .
git clean -fxd
Then you can reset the index (with git reset) or go straight on to checking out a new branch.

With find and prune option.
find . -path ./.git -prune -o -exec rm -rf {} \; 2> /dev/null
Edit: For two directories .git and dist
find . -path ./.git -prune -o \( \! -path ./dist \) -exec rm -rf {} \; 2> /dev/null

As Crayon mentioned in the comments, the easy solution would be to just move .git out of the directory, delete everything, and then move it back in. But if you want to do it the fancy way, find has got your back:
find -not -path "./.git/*" -not -name ".git" | grep git
find -not -path "./.git/*" -not -name ".git" -delete
The first line I put in there because with find, I always want to double-check to make sure it's finding what I think it is, before running the -delete.
Edit: Added -not -name ".git", which keeps it from trying to delete the .git directory, and suppresses the errors. Depending on the order find tries to delete things, it may fail on non-empty directories.

One way is to use rm -rf *, which will delete all files from the folder except the dotfiles and dotfolders like .git. You can then delete the dotfiles and dotfolders one by one, so that you don't miss out on important dotfiles like .gitignore, .gitattributes later.
Another approach would be to move your .git folder out of the directory and then going back and deleting all the contents of the folder and moving the .git folder back.
mv .git/ ../
cd ..
rm -rf folder/*
mv .git/ folder/
cd folder

for i in `ls | grep -v ".git"` ; do rm -rf $i; done; rm .gitignore;
the additional rm at the end will remove the special .gitignore. Take that off if you do need the file.

as CB Bailey mention:
I want to remove the history of tracker files too.
git rm -rf .
git clean -fxd
git update-ref -d refs/heads/master #or main or ...

should find all the files and directories that with the name .git
find . -name .git
should find all the file and directories not named .git
find . -not -name .git
delete all the files that you find
find . -not -name .git -exec rm -vf {} \;
be sure that the find is doing what you want
if you want to delete directories change the rm command to rm -rvf
I include the v option to see the files that are deleted.
if you want to make sure about the files before you delete them
pipe the find command to a file and review the results

Related

How to "rm -rf" with excluding files and folders with the "find -o" command

I'm trying to use the find command, but still can't figure out how to pipe the find ... to rm -rf
Here is the directory tree for testing:
/path/to/directory
/path/to/directory/file1_or_dir1_to_exclude
/path/to/directory/file2_or_dir2_to_exclude
/path/to/directory/.hidden_file1_or_dir1_to_exclude
/path/to/directory/.hidden_file2_or_dir2_to_exclude
/path/to/directory/many_other_files
/path/to/directory/many_other_directories
Here is the command for removing the whole directory:
rm -rf /path/to/directory
But how to rm -rf while excluding files and folders?
Here is the man help for reference:
man find
-prune True; if the file is a directory, do not descend into it. If
-depth is given, then -prune has no effect. Because -delete im‐
plies -depth, you cannot usefully use -prune and -delete to‐
gether.
For example, to skip the directory `src/emacs' and all files
and directories under it, and print the names of the other files
found, do something like this:
find . -path ./src/emacs -prune -o -print
What's the -o in this find command? Does it mean "or"? I can't find the meaning of -o in the man page.
mkdir -p /path/to/directory
mkdir -p /path/to/directory/file1_or_dir1_to_exclude
mkdir -p /path/to/directory/file2_or_dir2_to_exclude
mkdir -p /path/to/directory/.hidden_file1_or_dir1_to_exclude
mkdir -p /path/to/directory/.hidden_file2_or_dir2_to_exclude
mkdir -p /path/to/directory/many_other_files
mkdir -p /path/to/directory/many_other_directories
I have tried to use this find command to exclude the .hidden_file1_or_dir1_to_exclude and then pipe it to rm, but this command does not work as expected.
cd /path/to/directory
find . -path ./.hidden_file1_or_dir1_to_exclude -prune -o -print | xargs -0 -I {} rm -rf {}
The meaning of rm -rf is to recursively remove everything in a directory tree.
The way to avoid recursively removing everything inside a directory is to get find to enumerate exactly the files you want to remove, and nothing else (and then of course you don't need rm at all; find knows how to remove files, too).
find . -depth -path './.hidden_file1_or_dir1_to_exclude/*' -o -delete
Using -delete turns on the -depth option, which disables the availability of -prune; but just say "delete if not in this tree" instead. And indeed, as you seem to have discovered already, -o stands for "or".
The reason -delete enables -depth should be obvious; you can't traverse the files inside a directory after you have deleted it.
As an aside, you need to use -print0 if you use xargs -0. (This facility is a GNU extension, and generally not available on POSIX.)
You need to separate files from directories to exclude:
find . -mindepth 1\
\( -path ./dir_to_exclude -o\
-path ./.hidden_dir_to_exclude \) -type d -prune\
-o\
! \( -path ./file_to_exclude -o\
-path ./.hidden_file_to_exclude \)\
-exec echo rm -rf {} \;
You can remove the echo once tested.

how to tell find command to only remove contents of a directory

I am using find to get both files and dirs inside $dest_dir and remove them:
dest_dir="$HOME/pics"
# dest_dir content:
# dir1
# dir2
# pic1
# pic2
find $dest_dir -maxdepth 1 -exec rm -rf {} \;
Expectation: remove dest_dir contents only (i. e. dir1, dir2, pic1, pic2) and not dest_dir itself
Actual result: the command removes the dest_dir too
I also tried -delete instead of the -exec rm -rf {} \; section, but it can't remove non-empty directories.
If you pass a directory name to rm -rf it will delete it, by definition. If you don't want to recurse into subdirectories, why are you using find at all?
rm "$dest_dir"/*
On the other hand, if you want to rm -rf everything inside the directory ... Do that instead.
rm -rf "$dest_dir"/*
On the third hand, if you do want to remove files, but not directories, from an arbitrarily deep directory tree, try
find "$dest_dir" -type f -delete
or somewhat more obscurely with -execdir and find just the directories and pass in a command like sh -c 'rm {}/*', but in this scenario this is just clumsy and complex.
You can use this find command:
find "$dest_dir" -maxdepth 1 -mindepth 1 -exec rm -rf {} +
Option -mindepth 1 will find all entries inside "$dest_dir" at least one level down and will skip "$dest_dir" itself.

Prevent deletion of .git folder using terminal

I want to delete all the folders and files from my local repo folder, but not the .git folder and any other folder/file proceeding with a '.'.
How exactly do I do that?
I'm running Ubuntu 14.04
Normally, the following works:
git rm -r *
That leaves the .gitignore file and any other . files unaffected. By default, in bash (and probably other shells) * does not match directories or files starting with a ..
Similarly,
rm * -r -i
will only remove files and directories not starting with a . with. (remove the -i for non-interactive mode)
The .git folder isn't itself version controlled, and Git will not remove it.
Just run git rm -r . and you'll remove all files in the repository without removing the .git directory.
try this:
find . -type f -not -name ".*" -exec rm -f {} \;
That will delete all files that aren't preceded with at "."
Please let me know if you have any questions!

How do I remove all traces of SVN from my directory?

I want it to be cleared of SVN, recursively, but of course keep my files.
You mean killing all the .svn directories? This should do it:
find -name '.svn' -type d -exec rm -rf {} ';'
EDIT: Updated from comments. Doh!
use find and look for the .svn directories
find . -name "FILE-TO-FIND"-exec rm -rf {} \;
You can fetch a new copy from the svn repository using the svn export command instead of svn checkout. The resulting tree will have no SVN bits in it.

How to remove all .svn directories from my application directories

One of the missions of an export tool I have in my application, is to clean all .svn directories from my application directory tree. I am looking for a recursive command in the Linux shell that will traverse the entire tree and delete the .svn files.
I am not using export, as this script will be used for some other file/directory names which are not related to SVN. I tried something like:
find . -name .svn | rm -fr
It didn't work...
Try this:
find . -name .svn -exec rm -rf '{}' \;
Before running a command like that, I often like to run this first:
find . -name .svn -exec ls '{}' \;
What you wrote sends a list of newline separated file names (and paths) to rm, but rm doesn't know what to do with that input. It's only expecting command line parameters.
xargs takes input, usually separated by newlines, and places them on the command line, so adding xargs makes what you had work:
find . -name .svn | xargs rm -fr
xargs is intelligent enough that it will only pass as many arguments to rm as it can accept. Thus, if you had a million files, it might run rm 1,000,000/65,000 times (if your shell could accept 65,002 arguments on the command line {65k files + 1 for rm + 1 for -fr}).
As persons have adeptly pointed out, the following also work:
find . -name .svn -exec rm -rf {} \;
find . -depth -name .svn -exec rm -fr {} \;
find . -type d -name .svn -print0|xargs -0 rm -rf
The first two -exec forms both call rm for each folder being deleted, so if you had 1,000,000 folders, rm would be invoked 1,000,000 times. This is certainly less than ideal. Newer implementations of rm allow you to conclude the command with a + indicating that rm will accept as many arguments as possible:
find . -name .svn -exec rm -rf {} +
The last find/xargs version uses print0, which makes find generate output that uses \0 as a terminator rather than a newline. Since POSIX systems allow any character but \0 in the filename, this is truly the safest way to make sure that the arguments are correctly passed to rm or the application being executed.
In addition, there's a -execdir that will execute rm from the directory in which the file was found, rather than at the base directory and a -depth that will start depth first.
No need for pipes, xargs, exec, or anything:
find . -name .svn -delete
Edit: Just kidding, evidently -delete calls unlinkat() under the hood, so it behaves like unlink or rmdir and will refuse to operate on directories containing files.
There are already many answers provided for deleting the .svn-directory. But I want to add, that you can avoid these directories from the beginning, if you do an export instead of a checkout:
svn export <url>
If you don't like to see a lot of
find: `./.svn': No such file or directory
warnings, then use the -depth switch:
find . -depth -name .svn -exec rm -fr {} \;
In Windows, you can use the following registry script to add "Delete SVN Folders" to your right click context menu. Run it on any directory containing those pesky files.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
#="Delete SVN Folders"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]
#="cmd.exe /c \"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""
You almost had it. If you want to pass the output of a command as parameters to another one, you'll need to use xargs. Adding -print0 makes sure the script can handle paths with whitespace:
find . -type d -name .svn -print0|xargs -0 rm -rf
find . -name .svn |xargs rm -rf
As an important issue, when you want to utilize shell to delete .svn folders You need -depth argument to prevent find command entering the directory that was just deleted and showing error messages like e.g.
"find: ./.svn: No such file or directory"
As a result, You can use find command like below:
cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;
Try this:
find . -name .svn -exec rm -v {} \;
Read more about the find command at developerWorks.
Alternatively, if you want to export a copy without modifying the working copy, you can use rsync:
rsync -a --exclude .svn path/to/working/copy path/to/export

Resources