I have a fairly simple question I could not find a solution for. I want to ignore all Mac OS X Alias folders I have in my git project. How do I target those? I couldn't figure out their file extension. ".alias" and ".alias-file" doesn't seem to work.
Is there a way to do this? Other than ignoring each one specifically.
I don't know anything about git, but this script can find OSX aliases and list them for you, so you could probably pipe the list into git to ignore somehow...
#!/bin/bash
################################################################################
# ListAliases
# Given a directory as parameter, find and output names of all things under
# that directory that are aliases. Not an officially approved technique!
################################################################################
d=${1-$(pwd)}
find "$d" -exec sh -c 'xattr -pl com.apple.FinderInfo "{}" 2> /dev/null | grep -q alisMACS && echo "{}"' \;
Save it in a file called ListAliases, then make it executable like this:
chmod +x ListAliases
and run it like this
./ListAliases
or
./ListAliases /path/to/git/repository
Sample Output
/Users/mark/.Trash/installed.txt alias
/Users/mark/Desktop/installed.txt alias
/Users/mark/Desktop/installed.txt alias 2
It sounds like you're assuming that every file needs to have a file extension... that Mac alias files have a ".alias" extension. That's not the case. The Mac OS supports files both with and without extensions. When aliasing folders, there's no file extension involved. You would need to ignore the names of the folders that the aliases point to, which in turn would ignore the aliases themselves, since the aliases share the same name as the folders they point to.
What about aliases to folders?
With regard to folder alias' I tried this and it seemed to work:
*\ alias
In this case for all folder alias'
Just create a ".gitignore" file.
Write inside the patterns you want to ignore. (separated by new-line)
In your case that would be:
"
.alias*
"
Then, the "git status" command should not show you files OR directories matching the pattern.
Finish with a 'git add .gitignore' and "git commit -m "Added a gitignore file""
Update: Ok, the answer is very basic but I hadn't any clues.
Check this link : Ignore files that have already been committed to a Git repository
Related
I often use fzf to navigate the filesystem, especially the Alt-c key binding.
When invoked, fzf generates a list from the current working directory.
Is it possible to make fzf generate a list from a specified directory?
I have tried fzf <dir>, but it results in an error (unknown option). Also, I can't find any options like -C <dir> for specifying the start directory.
I had a more general issue which might be useful for you. The following is from a blog post I wrote about it:
Configuring FZF to search useful directories beyond the working directory
I use fzf both as a command line tool and from within Vim using the fzf.vim plugin. It makes finding (and opening) files intuitive, fast, and frees you from needing to remember their location or exact name. By default, fzf searches recursively within the current directory, which is often just what you want. If you need to search for a file in some directory beyond the current working directory you need to specify that path as an argument to fzf, after which it's business as usual (fzf will recursively search the specified directory).
The Problem
It always felt a shame to have to occasionally precisely specify a path in order to get a fuzzy search going... precisely specifying a path is the exact thing that fzf is supposed to unburden your from! My initial approach was to supply the home directory path and let fzf search everything, the home directory path can be specified in only a couple of characters so there's no real burden in that case.
The problem with doing this is that you end up searching a lot of directories which you know don't have the file you want. The main offenders were directories you end up with if you install say, anaconda3. The results would be swamped with thousands of internal files, with very long paths. The long paths tended to 'soak up' any letters I entered in the search, so it was difficult for fzf to filter them out.
The Solution
You can choose which searching tool fzf uses under the hood. The default is the standard linux find command, but you can also use fd, ripgrep or silver searcher. Apart from being a lot faster than the default find, these latter tools respect .ignore files. This means that fzf will skip any files or directories listed in a .ignore file. We can turn this feature to our advantage.
First, we install fd. If you run Ubuntu 19.04 (Disco Dingo) or newer, you can install the officially maintained package:
sudo apt install fd-find
If you use an older version of Ubuntu, you can download the latest .deb package from the release page and install it via:
# adapt version number and architecture
sudo dpkg -i fd_8.2.1_amd64.deb
Now we configure fzf to use fd by adding the following line in your .bashrc:
export FZF_DEFAULT_COMMAND="fdfind . $HOME"
If you're using an older version than Ubuntu 19.10, the above line needs to be modified like so:
export FZF_DEFAULT_COMMAND="fd . $HOME"
Now fzf will always search recursively from the home directory, and respect any .ignore files. So let's make one in the home directory:
touch ~/.ignore
I find that the list of directories that I might conceivably (~15) want to recursively search with fzf is shorter that the list of directories that I would never want searched. The total number of files in the directories I want searched is about 5000 or so - easily handled by fd.
In the .ignore file, I first list all my home directories, each followed by a '/':
# start by igoring every home directory
anaconda3/
arch/
cache/
code/
Desktop/
.
.
.
Then below those, put the directories that you want to be searched, each preceded by a '!' and followed by a '/':
# now un-ignore the ones I care about
!code/
!Desktop/
!documents/
!downloads/
.
.
.
The '!' will 'cancel out' the previous ignore commands.
And there we have it. We can invoke fzf wherever we are in the file system and start typing vague things about the file(s) we have in mind and fzf will search in a set of predefined directories and find it with ease. This completely removes the barrier of thinking where a file might be and how precisely it was named.
N.B. I have noticed that, for some reason, a couple of subdirectories were not showing up in the fzf search, and so I explicitly created some '!path/to/missed/directory/' lines in this section...
N.B. You may be wondering "What if I find myself in an unusual directory not on the list, and want to use fzf?". I had the same concern so I put a couple of aliases in my .bashrc that can toggle the above configuration on and off at will (be sure to use 'fdfind' for Ubuntu 19.10+, as disused above):
# restore fzf default options ('fzf clear')
alias fzfcl="export FZF_DEFAULT_COMMAND='fd .'"
# reinstate fzf custom options ('fzf-' as in 'cd -' as in 'back to where I was')
alias fzf-="export FZF_DEFAULT_COMMAND='fd . $HOME'"
If you're using Vim to create the .ignore file, an easy way to get a list of all the directories in your home directory is the following command:
:.!ls ~/
Append a '/' to all lines by putting the cursor on the first directory in the list and entering the following command:
:.,$ norm A/
Similar to above, insert the '!' before each one by putting the cursor on the first directory in the list and entering the following command:
:.,$ norm I!
Assuming you're using bash or similar, this is built into the default completion options which get installed with fzf: https://github.com/junegunn/fzf#fuzzy-completion-for-bash-and-zsh
tldr; enter start file or directory, append ** and hit Tab. So if you'd enter cd /foo/** then tab opens fzf with /foo as start directory.
edit at the time of writing the commands for which this works are hardcoded in fzf's bash helpers, which is why this works for cat and cd but not for tac or nano. This is the complete list:
awk cat diff diff3
emacs emacsclient ex file ftp g++ gcc gvim head hg java
javac ld less more mvim nvim patch perl python ruby
sed sftp sort source tail tee uniq vi view vim wc xdg-open
basename bunzip2 bzip2 chmod chown curl cp dirname du
find git grep gunzip gzip hg jar
ln ls mv open rm rsync scp
svn tar unzip zip
To add other commands use this in e.g. your .bashrc, after the place where fzf gets sourced (something like [ -f ~/.fzf.bash ] && source ~/.fzf.bash):
__fzf_defc "tac" _fzf_path_completion "-o default -o bashdefault"
Alternatively: open an issue to ask for the commands you want to be added to fzf by default, things like tac and nano are super common anyway.
You can do something like:
find <dir> | fzf
fd . <dir> | fzf
Source.
When I copy something, I always forget the -R, then I have go all the way back to add it right after cp.
I want to add this to bash config files.
alias cp="cp -R"
I have not seen anything bad happen. Is it safe to do this?
The only thing I can think of that would cause unexpected behavior with the -R flag is that it doesn't work with wildcards.
What I mean is... for example you want to copy all mp3 Files in a directory and every subdirectory with: cp -R /path/*.mp3. Although -R is given it will not copy mp3s in the subdirectories of path - if there are any.
I wouldn't use aliases for changing the behaviour of normal commands. When you are in a different shell / another computer, the alias will be missing. When a friend wants to help you, he will not know what you did.
Once I had an alias rm="rm -i" and I performed rm *, while I just had changed shell with a su.
And sometimes you want to use cp without the -R option, will you remember to use /bin/cp in these cases (copy all files in the current dir to another location, but do not cp the subdirs)?
I have following directory structure :
/home/dir1/abc.jpg
/home/dir1/abc.pdf
/home/dir1/dir2/abc.jpg
/home/dir1/dir2/abc1.jpg
/home/dir1/dir2/dir3/abc.jpg
and I want to copy jpg files from them to a new folder which will have same directory structure, for eg.:
/home/newdir1/abc.jpg
/home/newdir1/dir2/abc.jpg
/home/newdir1/dir2/abc1.jpg
/home/newdir1/dir2/dir3/abc.jpg
How to achieve it using rsync or any other software ?
Please help, Many Thanks !!
From the looks of what you've included in your question, there are a couple of things you might try.
You've specified that you want to "move" files. That means you either use the mv command, or use rsync's --remove-source-files option. For example:
mv /source1/* /source2/* /path/to/targetdir/
or
rsync -a /source1/ /source2/ /path/to/targetdir/
You've no doubt already read the part of rsync's man page that explains the difference between source dirs with and without their trailing slash. If not, read up, because it's important.
If your "thousands of source files [with] similar names" need to be matched from within your source directories, leaving some other files behind, you need to determine whether your "similar names" can be differentiated using pathname expansion or if you should use a regular expression. If the former, then adding the pathname expansion to your sources with either mv or rsync should be sufficient. If you need to use a regex, then find may be a better option:
find /source1/ /source2/ -regex ".*/file[A-F][0-9][0-9].txt" -exec mv "{}" /targetdir/ \;
If these don't solve the problem, then you'll need to supply more detail in your question.
I would try a little shell script like this:
#!/bin/sh
cd /home/dir1
JPEGS=`find . -name "*.jpg"`
tar cf - $JPEGS | (cd /home/newdir1 ; tar xf -)
This first gets the list of all your jpg files with their relative paths, then writes a tar file of them to a pipe into a subshell which changes to the new directory, and then extracts the tar from its stdin.
The layout of the two directories in question is:
folder1
-file1
-file2
folder2
-file1
-file2
The files in the directories are named the same. I tried to use rm to programmatically remove files in folder 2:
for f in /Users/michelegiarratana/1/*; do rm /Users/michelegiarratana/2/$f
but this isn't working. Is $f the full path? How do I get the name?
Thanks
As savanto said in his comment -- yes, you are correct, $f here is the full file path. To fix this, you should use the basename builtin, which extracts just the file name. In your example:
for f in /Users/michelegiarratana/1/*; do rm /Users/michelegiarratana/2/$(basename $f); done
Additionally -- your question applies more broadly to bash shells than just the OS X terminal, in the future, you should try looking for answers in the bash tag, as many of them will be useful to you.
I wanted to rename a folder from "Frameworks" to "frameworks", but git would not let me add the new lowercase name. I guess it treats filenames case insensitive, does it?
A git add frameworks/ -f didn't help
You can try:
"git mv -f foo.txt Foo.txt" (note: this is no longer needed since git 2.0.1)
to set ignorecase to false in the config file.
But the issue of case (on Windows for instance) is described in the msysgit issue 228 (again: this should now -- June 2014 -- work with git 2.0.1)
there is always an option to set ignorecase to false in the config file that will force Unix like Git semantics on top of NTFS.
Git supports this behavior but it is not the default - from NTFS point of view a.txt
and A.txt are the same thing - so Git tries to preserve that as most users would expect
As a better workaround, you can
git mv foo.txt foo.txt.tmp && git mv foo.txt.tmp Foo.txt
, which also changes the case of the file as stored on disk.
This blog post illustrates the same issue on MacOs during a rebase:
The default on Mac OS X file systems is that they are case-insensitive. FFFFFF.gif is the same as ffffff.gif.
If you delete the file in question, just from the file system, not from the Git index, mind you, you can merge the branch in question, and have it restore the file as if nothing happened.
The steps are pretty simple:
$ rm file/in/question.gif
$ git merge trunk
Anyhow, remember what git mv stands for:
mv oldname newname
git add newname
git rm oldname
, so if newname and oldname clash, you need to make them different (even if it is only for a short period of time), hence the git mv foo.txt foo.txt.tmp && git mv foo.txt.tmp Foo.txt
If you happen to host on Github, you can use the rename function on their website. Had to change the casing for 5 files and found it worked really well.
I was having a similar problem and couldn't get a new folder name (different case) to change on remote repos. I found that the easiest solution was just to move the file out of the repo and commit. Triggering a delete action. Then re-add and when I added, it came in with the proper case.