Linux command to delete all files except .git folder?
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.
Delete all files and folders recursively but excluding one folder
You can try with find
:
find my-root-folder -mindepth 1 -not -path "*/.git*" -delete
Roughly translated, this means: find
inside my-root-folder
everything at least one level deep
(so, exclude the folder itself) that does not
match the predicate path contains "/.git"
and delete
it.
Note that the argument ".git"
is actually a regular expression, so be careful when adapting to other situations. find
is a very powerful and useful tool, so be sure to check out its documentation!
remove everything exept for .git directory and .gitignore on linux
You could run this:
find -mindepth 1 -depth -print0 | grep -vEzZ '(\.git(/|$)|/\.gitignore$)' | xargs -0 rm -rvf
But simulate first what it would do:
find -mindepth 1 -depth -print0 | grep -vEzZ '(\.git(/|$)|/\.gitignore$)' | xargs -0 echo rm -rvf
Explanation:
-mindepth 1
: it will exclude current directory
-depth
: it will list files before folders
print0
: it will separate each records with a null character, handy if you file name contains spaces
Remove all except certain folders from git history
You are correct: a tree filter or an index filter would be the way to do this with git filter-branch
.
The tree filter is easier, but much slower (easily 10 to 100 times slower). The way a tree filter works is that your supplied command is run in a temporary directory that contains all, and only, the files that were present in the original (now being copied) commit. Any files your command leaves behind, remain in the copied commit. Any files your command creates in the temporary directory, are also in the copied commit. (You may create or remove directories within the temporary directory with no effect either way, since Git stores only the files.) Hence, to remove everything except A and B, write a command that removes every file that is in something other than either A or B:
find . -name A -prune -o -name B -prune -o -print0 | xargs -0 rm
for instance.
The index filter is harder, but faster because Git does not have to copy all the files out to a file tree and then re-scan the file tree to build a new index, in order to copy the original commit. Instead, it provides only an index, which you can then manipulate with commands like git rm -rf --cached --ignore-unmatch
for instance, or git update-index
for the most general case. But, now the only tools you have are those in Git that manipulate the index. There is no fancy Unix find
command.
You do, of course, have git ls-files
, which reads out the current contents of the index. Hence you can write a program in whatever language you like (I would use Python first here, probably, others might start with Perl) that in essence does:
for (all files in the index)
if (file name starts with 'A/' or 'B/')
do nothing
else
add to removal list
invoke "git rm --cached" on paths in removal list
If you are willing to trust that no file name has an embedded newline, the above can be done in regular shell as:
git ls-files | IFS=$'\n' while read path; do
case "$path" in A/*|B/*) continue;; esac
git rm --cached "$path"
done
which is not terribly efficient (one git rm --cached
per path!) but should work "out of the box" as an --index-filter
.
(Untested, but probably works and should be significantly more efficient: pipe git ls-files
output through grep -v
to remove desired files, and pipe grep
output into git update-index --force-remove --stdin
. This still assumes no newlines in path names.)
Remove all git files from a directory?
The .git folder is only stored in the root directory of the repo, not all the sub-directories like subversion. You should be able to just delete that one folder, unless you are using Submodules...then they will have one too.
How do you delete all hidden and non-hidden files except one?
This will delete everything in the current directory that you have permission to remove, recursively, preserving the file named by -path
, and its parent path.
# remove all files bar one
find . -mindepth 1 -not -type d -not -path ./file/to/keep -exec rm -rf {} +
# then remove all empty directories
find . -mindepth 1 -type d -exec rmdir -p {} + 2>/dev/null
rmdir
will get fed a lot of directories it's already removed (causing error messages). rmdir -p
is POSIX. This would not work without -p
.
You can keep more files with additional -path
arguments, and/or glob patterns. The paths must match the starting point, i.e. ./
.
Shell - Remove everything except a single folder
This is that simple as :
shopt -s extglob dotglob
rm -rf !(.git)
See http://mywiki.wooledge.org/glob
Related Topics
Delete All Files Except the Newest 3 in Bash Script
How to Rebuild Rootfs in Buildroot
How to Make Binary Distribution of Qt Application for Linux
How to Compile Glibc 32Bit on an X86_64 MAChine
What Is Terminal Escape Sequence for Ctrl + Arrow (Left, Right,...) in Term=Linux
Get Time in Milliseconds Without an Installing an Extra Package
How to Install Xvfb (X Virtual Framebuffer) on Redhat 6.5
Can't Read Variable That Was Stored from Within a While Loop, When Out of the While Loop
Sort Logs by Date Field in Bash
How to Handle the Linux Socket Revents Pollerr, Pollhup and Pollnval
Sub-Shell Differences Between Bash and Ksh
Linux Kernel - Add System Call Dynamically Through Module
Docker Behind Proxy That Changes Ssl Certificate
How Do Locales Work in Linux/Posix and What Transformations Are Applied