Bash Tab Completion Suggests Hidden SVN Files - bash

When using tab completion, I keep getting suggestions for .svn files, so, using ls, my output looks like this:
[spaceplace]$ ls src/
main/ .svn/
[spaceplace]$ ls src/
main/ .svn/
[spaceplace]$ ls src/
main/ .svn/
[spaceplace]$ ls src/main/
java/ resources/ .svn/
[spaceplace]$ ls src/main/
java/ resources/ .svn/
The .svn files don't show up when I just use ls, so I don't know why they show up when I use tab complete. The issue only seems to exist with the .svn files and no other hidden files, which seems weird. How can I get these files to not show up when I am using tab complete?

I found out a way to do it; in my .bashrc I added the line bind 'set match-hidden-files off'. Now all the files beginning with "." don't show up unless you explicitly specify it.

Bash allows to specify which files or directories to ignore in tab completion based on extensions, e.g. to ignore all files or directories named *.svn
$ export FIGNORE=$FIGNORE:.svn
Depending on how your files are usually named this shouldn't clash too much (at least it worked well for me).

The tab completion does not exclude hidden files. It is acting as intended. If you do a ls -a it will show the hidden files.
It is worth noting that any files/folders that start with a . are hidden files. Command line assumes that you will need access to these files which is why it is suggesting them in the auto complete.

Related

Copy whole directory but exclude all folders and subfolders with certain name

I'm not allowed to use rsync on the cluster I'm working on so I need to use cp. I want to copy a large directory including all files and subfolders etc. but without any folders that have the name "outdir".
I tried cp -r -v ./!(outdir) ../target-directory/
but it still copies all folders and contents in deeper directories with the name outdir. It only included the outdir folders in the highest directory.
I also tried cp -r ./*/!(outdir) ../target-directory/ but that one copied all files into the folder without keeping any hirarchy or folders etc.
I also tried certain find commands but it didn't work, but maybe I was just doing something stupid. I'm a beginner with bash so if you could explain your answer and what the flags etc. do that would really be helpfull, I've been trying forever now, on what I think shouldn't be that hard to do.
Instead of cp, you can use tar with option --exclude to control what you want copied or not.
The full command is:
tar --exclude="outdir" -cvpf - . | (cd TARGET_DIRECTORY; tar -xpf -)
So any path that contains the "outdir" pattern will be excluded.
Without the --exclude option, it will copy the entire structure of your current directory under TARGET_DIRECTORY.
You can replace the . in the first tar by your desired source directory.

Hide `.DS_Store` when navigating the terminal with tab auto-complete

Typically when moving thru my terminal (Bash environment) I use tab to display my directory contents. .DS_Store is a lot of noise to see in every directory. I'm okay with the existence of .DS_Store, but I don't want it ever see it in my auto-tab-complete results.
An example is when you hit <Tab> after typing in cd ~/dev/project-a/
$ cd ~/dev/project-a/
.DS_Store .git/ Makefile
.editorconfig .gitignore src/
Is there a clean solution to hiding .DS_Store from the results, without switching shell environments?
To ignore directory .DS_Store I suggest to add this to your ~/.bashrc:
FIGNORE=DS_Store
Disadvantage: This ignores everything that ends with .DS_Store.

zip all files and folders recursively in bash

I am working on a project, where compilation of the project involves, zipping up various files and folders and subfolders (html/css/js) selectively. Working on the windows platform, and I could continue to just use the CTRL+A and then SHIFT-click to unselect, but it does get a little tedious. I am working with cygwin, so I was wondering if it is possible to issue a command to zip selected files/folders recursively whilst excluding others, in one command? I already have zip command installed, but I seem to be zipping up the current zip file too and the .svn file too.
I would like this to be incorporated into a shell script if possible, so the simpler the better.
After reading the man pages, I think the solution that I was looking for is as follws:
needs to recurse directories (-r),
needs to exclude certail files/directories (-x)
It works in the current directory, but the . can be replaced with the path of any directory
zip -x directories_to_exclude -r codebase_latest.zip .
I have incorporated this into a short shell script that deletes files, tidy up some code, and then zips up all of the files as needed.
You should read man page of zip command:
-R
--recurse-patterns
Travel the directory structure recursively starting at the current directory; for example:
zip -R foo "*.c"
In this case, all the files matching *.c in the tree starting at the current directory are stored into a zip archive named foo.zip. Note that *.c will match
file.c, a/file.c and a/b/.c. More than one pattern can be listed as separate arguments. Note for PKZIP users: the equivalent command is
pkzip -rP foo *.c
Patterns are relative file paths as they appear in the archive, or will after zipping, and can have optional wildcards in them. For example, given the cur‐
rent directory is foo and under it are directories foo1 and foo2 and in foo1 is the file bar.c,
zip -R foo/*
will zip up foo, foo/foo1, foo/foo1/bar.c, and foo/foo2.
zip -R */bar.c
will zip up foo/foo1/bar.c. See the note for -r on escaping wildcards.
You can also have a look HERE

sync/copy folders from source dir only if folders exist in target dir

I'm trying to write a bash script in ubuntu to do a copy of some files.. I'm working on a small Android project, where i'm translating the apps each week. I'm VERY new to bash scripting, so please bear with me ;)
I want my script to check the target directory and see if my source directory contains the same folders. If it does, it should copy (and overwrite if needed) my source folders to the target dir, preserving the structure. But also adding whatever extra files and folders i might have within those source folders.
Let's say i have folder1, folder2, folder3 in my source dir, but only folder1 and folder2 in the target dir. Then i only need folder1 and folder2 from the source dir copied to the target dir.
The content of the target dir changes often, that's why i need the check before it copies the folders/files over.
Btw, the folders in both source and target dir are named like: folder1.apk - it has an extension so it looks like a file..
Hope i provided enough info ;)
EDIT:
I ended up doing this:
for dir in `find * -maxdepth 0 -type d`; do
cp -r -f /source/$dir /destination
done
Don't know if it's the best way, but seems to do the job ;)
You would probably take a look at rsync tool, which has lot of options and easy to use (no need to use own scripts). For example, one of the options that will be useful in your case:
--existing skip creating new files on receiver
So, the following should do the job:
rsync -vur --existing ~/project/source /mnt/target/
And one of the possible benefits that you can sync files the same way through network if you will need to or even use it as a daemon to automatically sync files.

Ignoring directories in Git repositories on Windows

How can I ignore directories or folders in Git using msysgit on Windows?
Create a file named .gitignore in your project's directory. Ignore directories by entering the directory name into the file (with a slash appended):
dir_to_ignore/
More information is here.
By default, Windows Explorer will display .gitignore when in fact the file name is .gitignore.txt.
Git will not use .gitignore.txt
And you can't rename the file to .gitignore, because Windows Explorer thinks it's a file of type gitignore without a name.
Non command line solution:
You can rename a file to ".gitignore.", and it will create ".gitignore"
It seems that for ignoring files and directories there are two main ways:
.gitignore
Placing .gitignore file into the root of your repository besides the .git folder (in Windows, make sure you see the true file extension and then make .gitignore. (with the point at the end to make an empty file extension))
Making the global configuration ~/.gitignore_global and running git config --global core.excludesfile ~/.gitignore_global to add this to your Git configuration
Note: files tracked before can be untracked by running git rm --cached filename
Repository exclude - For local files that do not need to be shared, you just add the file pattern or directory to the file .git/info/exclude. Theses rules are not committed, so they are not seen by other users. More information is here.
To make exceptions in the list of ignored files, see this question.
To ignore an entire directory place a .gitignore of “*” there.
For example,
Example System
/root/
.gitignore
/dirA/
someFile1.txt
someFile2.txt
/dirB/
.gitignore
someFile3.txt
someFile4.txt
Goal
ignore the contents of dirB/
Top Level (/root/.gitignore)
You could just “dirB/“ here
Ignored Directory (/root/dirB/.gitignore)
Or you could “*” here
Git watches for gitignore at every step of the file system. So here I choose dirB/.gitignore as “*” to ignore dirB/, including all files and subdirs within.
Done ☺️
To instruct Git to ignore certain files or folders, you have to create .gitignore file.
But in Windows Explorer you have to provide a name for the file. You just cannot create file with just an extension. The trick is that create a empty text file and go to command prompt and change the name of the file to .gitignore:
ren "New Text Document.txt" .gitignore
Now open the file with your favorite text editor and add the file/folder names you wish you ignore. You can also use wildcards like this: *.txt.
I had some issues creating a file in Windows Explorer with a . at the beginning.
A workaround was to go into the commandshell and create a new file using "edit".
If you want to maintain a folder and not the files inside it, just put a ".gitignore" file in the folder with "*" as the content. This file will make Git ignore all content from the repository. But .gitignore will be included in your repository.
$ git add path/to/folder/.gitignore
If you add an empty folder, you receive this message (.gitignore is a hidden file)
The following paths are ignored by one of your .gitignore files:
path/to/folder/.gitignore
Use -f if you really want to add them.
fatal: no files added
So, use "-f" to force add:
$ git add path/to/folder/.gitignore -f
You can create the ".gitignore" file with the contents:
*
!.gitignore
It works for me.
In Windows there's an extra catch with slashes. Excluding a single directory in .gitignore with
dir_to_exclude/
will possibly work, but excluding all directories with
/
causes problems when you have file names with spaces (like my file.txt) in your directory: Git Bash escapes these spaces with a backslash (like my\ file.txt) and Git for Windows doesn't distinguish between / and \.
To exclude all directories, better use:
**/
Two consecutive asterisks signify directory contents.
Just in case you need to exclude sub folders you can use the ** wildcard to exclude any level of sub directory.
**/build/output/Debug/
Also in your \.git\info projects directory there is an exclude file that is effectively the same thing as .gitignore (I think). You can add files and directories to ignore in that.
When everything else fails try editing the file
/.git/info/exclude
and adding the directories you want to the end of the file, like this:
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
assets/
compiled/
I added the folders "assets" and "compiled" to the list of files and directories to ignore.
I've had some problems getting Git to pick up the .gitignore file on Windows. The $GIT_DIR/info/exclude file always seems to work though.
The downside of this approach, however, is that the files in the $GIT_DIR directory are not included in the check-in, and therefore not shared.
p.s. $GIT_DIR is usually the hidden folder named .git
On Unix:
touch .gitignore
On Windows:
echo > .gitignore
These commands executed in a terminal will create a .gitignore file in the current location.
Then just add information to this .gitignore file (using Notepad++ for example) which files or folders should be ignored. Save your changes. That's it :)
More information: .gitignore
I assume the problem is that your working tree is like:
a-cache/foo
a-cache/index.html
b-cache/bar
b-cache/foo
b-cache/index.html
.gitignore
... with the .gitignore you describe. This will give you git status output like:
$ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# .gitignore
# a-cache/
# b-cache/
... if the index.html files have not yet been added to the repository. (Git sees that there are unignored files in the cache directories, but it only reports the directories.) To fix this, make sure that you have added and committed the index.html files:
git add *cache/index.html
git commit -m "Adding index.html files to the cache directories"
... and your git status will then look like:
$ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# .gitignore
nothing added to commit but untracked files present (use "git add" to track)
(Obviously you do want to commit .gitignore as well. I was just being lazy with this test case.)
On Windows and Mac, if you want to ignore a folder named Flower_Data_Folder in the current directory, you can do:
echo Flower_Data_Folder >> .gitignore
If it's a file named data.txt:
echo data.txt >> .gitignore
If it's a path like "Data/passwords.txt"
echo "Data/passwords.txt" >> .gitignore.
I had similar issues. I work on a Windows tool chain with a shared repository with Linux guys, and they happily create files with the same (except for case) names in a given folder.
The effect is that I can clone the repository and immediately have dozens of 'modified' files that, if I checked in, would create havoc.
I have Windows set to case sensitive and Git to not ignore case, but it still fails (in the Win32 API calls apparently).
If I gitignore the files then I have to remember to not track the .gitignore file.
But I found a good answer here:
http://archive.robwilkerson.org/2010/03/02/git-tip-ignore-changes-to-tracked-files/index.html
Just create .gitignore file in your project folder Then add the name of the folder in it for ex:
frontend/node_modules
This might be extremely obvious for some, but I did understand this from the other answers.
Making a .gitignore file in a directory does nothing by itself. You have to open the .gitignore as a text file and write the files/directories you want it to ignore, each on its own line.
so cd to the Git repository directory
touch .gitignore
nano .gitignore
and then write the names of the files and or directories that you want to be ignored and their extensions if relevant.
Also, .gitignore is a hidden file on some OS (Macs for example) so you need ls -a to see it, not just ls.
Temporarily ignore a directory/file that was already in git:
I have a lot of projects in a multi-project gradle project and they can take a long time to delete them, and they're all pretty much the same but different. From time to time I want to remove those from the gradle build by deleting them altogether. git can get them back after all. However I don't want them showing up in git status either. So I use the following simple procedure;
delete files and folders I don't want.
verify build still works
tell git to ignore the deleted files for a bit (we can get them back)
git ls-files --deleted -z | git update-index --assume-unchanged -z
--stdin
go about life without the dirs until you want them back. Then run the same command as before but switch out assume-unchanged for no-assume-unchanged
git ls-files --deleted -z | git update-index --no-assume-unchanged -z
--stdin

Resources