Skip to content

Commit b0b4034

Browse files
committed
Adding git ignore command
The 'git ignore' command modifies a .gitignore file in your path easily. By default, it adds lines to the .gitignore found in the root of your repository. It can, however, add lines to a gitignore anywhere inbetween the file(s) passed in and the root of the repository. The lines added to the gitignore can be based on filename, extension, directory, or recursive glob. Also, you can easily open the gitignore file using your $EDITOR with 'git ignore --edit'. This can make things much easier when ignore files in subdirectories. No longer will you have to run: echo "path/to/the/file.txt" >../../../../../../.gitignore instead: git ignore file.txt Signed-off-by: Thurston Stone <[email protected]>
1 parent 8dca754 commit b0b4034

File tree

5 files changed

+520
-0
lines changed

5 files changed

+520
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
/git-http-backend
7777
/git-http-fetch
7878
/git-http-push
79+
/git-ignore
7980
/git-imap-send
8081
/git-index-pack
8182
/git-init

Documentation/git-ignore.txt

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
git-ignore(1)
2+
=============
3+
4+
NAME
5+
----
6+
git-ignore - Easily add entries to your .gitignore file
7+
8+
9+
SYNOPSIS
10+
--------
11+
[verse]
12+
'git ignore' [--dry-run | -n] [--ext | -e] [--all-ext | -E] [--dir | -d]
13+
[--all-file | -a] [--parent-level | -p <parent_level>] pathspec [...]
14+
'git ignore' --edit [--parent-level | -p <parent_level>]
15+
16+
17+
DESCRIPTION
18+
-----------
19+
The command modifies a .gitignore file in your path easily. By default,
20+
it adds lines to the .gitignore found in the root of your repository. It
21+
can, however, add lines to a gitignore anywhere inbetween the file(s)
22+
passed in and the root directory. The lines added can be based on
23+
filename, extension, directory, or recursive glob.
24+
25+
Also, you can easily open the gitignore file using the $EDITOR environment
26+
variable.
27+
28+
29+
OPTIONS
30+
-------
31+
<pathspec>...::
32+
Files to add to a gitignore. Fileglobs (e.g. `*.c`) can
33+
be given to add all matching files. Also a
34+
directory name can be given to add it to the gitignore
35+
as well.
36+
37+
--edit::
38+
Open the appropriate gitignore file in your default editor (using the
39+
$EDITOR variable). This option can be combined with `--parent-level` based
40+
on your current working directory.
41+
42+
-n::
43+
--dry-run::
44+
Don't actually edit the gitignore(s), just show what changes
45+
would have taken place.
46+
47+
-e::
48+
--ext::
49+
Add the relative filepath based on extension. If pathspec
50+
references path/to/file.log, the added gitignore line would
51+
be path/to/*.log.
52+
53+
-E::
54+
--all-ext::
55+
Add a global exclusion of the given extension. If pathspec
56+
references path/to/file.log, the added gitignore line would
57+
be **/*.log.
58+
59+
-d::
60+
--dir::
61+
Add the contents of the parent directory. If pathspec references
62+
path/to/file.log, the added gitignore line would be path/to/*.
63+
64+
-a::
65+
--all-file::
66+
Add a global exclusion of the given filename. If pathspec references
67+
path/to/file.log, the added gitignore line would be **/file.log.
68+
69+
-p::
70+
--parent-level <parent_level>::
71+
Modifications will go to a gitignore located <parent_level>
72+
directories above each of the files passed in. If the number
73+
of parent levels causes the directory to fall outside of the
74+
root of the git repository, a warning is printed and the root
75+
of the repository is used instead. Using a parent-level of 0
76+
will use the gitignore in the directory of each file passed in.
77+
78+
+
79+
Note that the parent level is calculated for each file passed in. If multiple
80+
files are passed in that have different parents at a given parent level, then
81+
they will cause separate gitignore files to be written.
82+
83+
84+
EXAMPLES
85+
--------
86+
87+
* Adds all `*.log` files under `tmp` directory
88+
and its subdirectories to the gitignore file found at the
89+
root of the repository:
90+
+
91+
------------
92+
$ pwd
93+
/user/test/git_repo/src
94+
$ git ignore -e tmp/file.log
95+
------------
96+
+
97+
Results in `tmp/*.log` added to /user/test/git_repo/.gitignore
98+
99+
100+
* Add the files under the `var/uploaded` directory to the gitignore above
101+
102+
+
103+
------------
104+
$ pwd
105+
/user/test/git_repo/
106+
$ git ignore -d --parent-level=1 www/var/uploaded/\*
107+
------------
108+
Results in `var/uploaded/*` added to /user/test/git_repo/www/.gitignore
109+
110+
SEE ALSO
111+
--------
112+
linkgit:gitignore[5]
113+
114+
GIT
115+
---
116+
Part of the linkgit:git[1] suite

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,7 @@ TEST_PROGRAMS_NEED_X =
606606
unexport CDPATH
607607

608608
SCRIPT_SH += git-bisect.sh
609+
SCRIPT_SH += git-ignore.sh
609610
SCRIPT_SH += git-difftool--helper.sh
610611
SCRIPT_SH += git-filter-branch.sh
611612
SCRIPT_SH += git-merge-octopus.sh

git-ignore.sh

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2016, Thurston Stone
4+
#
5+
# unit test: t7900
6+
7+
test -z "$DDDEBUG" || set -x
8+
9+
_verbose=0
10+
11+
SUBDIRECTORY_OK=Yes
12+
OPTIONS_KEEPDASHDASH=
13+
OPTIONS_STUCKLONG=t
14+
# Would be nice to have examples, but rev-parse sees '*' as a symbol to hide everything afterwards
15+
#e,ext add relative path for any file of that type (ex. path/to/*.ext)
16+
#E,all-ext all files of that extention anywhere (ex. **/*.ext)
17+
#d,dir all files under the parent directory (ex. directory/*)
18+
#a,all-file all files of that file name (ex. **/filename.ext)
19+
OPTIONS_SPEC="git ignore [options] [file|glob ...]
20+
--
21+
Miscelleneous
22+
edit open the pertinent gitignore with your default text editor (Requires \$EDITOR to be set)
23+
v,verbose show verbose output
24+
n,dry-run do not actually edit any .gitignore files
25+
Determine what files to add to the gitignore(s):
26+
e,ext add relative path for any file of that type
27+
E,all-ext all files of that extention anywhere
28+
d,dir all files under the parent directory
29+
a,all-file all files of that file name
30+
Determine what gitignore(s) to use:
31+
p,parent-level= number of parent directories containing the gitignore to edit. Set to 0 to put it in the local directory"
32+
33+
. git-sh-setup
34+
. git-sh-i18n
35+
36+
write_output () {
37+
if test $_verbose -eq 1
38+
then
39+
say $1
40+
fi
41+
}
42+
43+
get_git_ignore () {
44+
directory=$1
45+
46+
# if we don't yet have the repo root directory, get it
47+
if test -z "$repo_root"
48+
then
49+
#First, determine the root of the repository
50+
repo_root="$(git rev-parse --show-toplevel)/"
51+
write_output "repo_root=$repo_root"
52+
fi
53+
54+
# get the path relative to the repo root
55+
rel_directory="${directory#$repo_root}"
56+
# if the relative path is the same as it was, try converting it to aa *nix
57+
# style path
58+
if test "$rel_directory" = "$directory"
59+
then
60+
# repo root 2 (cygwin-ified path) didn't work
61+
# try the other one
62+
write_output "changing repo_root from $repo_root"
63+
#On windows, this turns to C:\... instead of /c/... from some other commands
64+
repo_root=$(printf "$repo_root" | awk -F":" '{ if ($2) print "/" tolower($1) $2; else print $1 }')
65+
write_output " to $repo_root"
66+
rel_directory="${directory#$repo_root}"
67+
fi
68+
# default gitignore
69+
gitignore="${repo_root}.gitignore"
70+
71+
# ------------------------------------------------
72+
# Determine the correct git ignore and the path of
73+
# the file relative to it
74+
# ------------------------------------------------
75+
if test $_parent_level -ge 0
76+
then
77+
parent=${directory}
78+
write_output "parent=${parent}"
79+
80+
if test $_parent_level -ne 0
81+
then
82+
i=1
83+
while test "$i" -le $_parent_level
84+
do
85+
parent="$(dirname "$parent")/"
86+
write_output "parent=${parent}"
87+
i=$(($i + 1))
88+
done
89+
fi
90+
root_len=$(printf "${repo_root}" | wc -m)
91+
parent_len=$(printf "${parent}" | wc -m)
92+
if test $root_len -ge $parent_len
93+
then
94+
write_output "root_len(${root_len}) >= parent_len(${parent_len})...
95+
uh-oh"
96+
gettextln "WARNING: Parent directory is outside of the repository"
97+
parent="${repo_root}"
98+
else
99+
write_output "root_len(${root_len}) < parent_len(${parent_len})...
100+
good"
101+
fi
102+
rel_directory="${directory#$parent}"
103+
gitignore="${parent}.gitignore"
104+
fi
105+
106+
write_output "rel_directory=${rel_directory}"
107+
write_output "gitignore=${gitignore}"
108+
109+
}
110+
111+
add_ignore () {
112+
# get the absolute path of the file
113+
file="$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
114+
write_output "file=$file"
115+
116+
directory="$(dirname "$file")/"
117+
write_output "directory=$directory"
118+
get_git_ignore "$directory"
119+
120+
filename=$(basename "$file")
121+
write_output "filename=$filename"
122+
extension="${filename##*.}"
123+
write_output "extension=$extension"
124+
# defaault line
125+
line="${rel_directory}${filename}"
126+
127+
# ------------------------------------------------
128+
# Determine the correct line to add to the gitignore
129+
# based on user inputs
130+
# ------------------------------------------------
131+
if test $_ext -eq 1
132+
then
133+
line="${rel_directory}*.$extension"
134+
fi
135+
if test $_directory -eq 1
136+
then
137+
line="${rel_directory}*"
138+
fi
139+
if test $_file_anywhere -eq 1
140+
then
141+
line="**/$filename"
142+
fi
143+
if test $_ext_anywhere -eq 1
144+
then
145+
line="**/*.$extension"
146+
fi
147+
write_output "line=${line}"
148+
dryrun=""
149+
if test $_dry_run -eq 1
150+
then
151+
dryrun="$(gettext "DRY-RUN!")"
152+
fi
153+
say "$dryrun $(eval_gettext "Adding \$line to \$gitignore")"
154+
if test $_dry_run -eq 0
155+
then
156+
echo "$line" >>"$gitignore"
157+
fi
158+
}
159+
160+
_ext=0
161+
_directory=0
162+
_file_anywhere=0
163+
_ext_anywhere=0
164+
_parent_level=-1
165+
_edit=0
166+
_dry_run=0
167+
168+
while test $# != 0
169+
do
170+
case "$1" in
171+
--ext)
172+
_ext=1
173+
;;
174+
--all-ext)
175+
_ext_anywhere=1
176+
;;
177+
--dir)
178+
_directory=1
179+
;;
180+
--all-file)
181+
_file_anywhere=1
182+
;;
183+
--parent-level=*)
184+
_parent_level="${1#--parent-level=}"
185+
if ! echo $_parent_level | grep -q '^[0-9]\+$'
186+
then
187+
gettextln "ILLEGAL PARAMETER: -p|--parent-level requires a numerical argument"
188+
usage
189+
fi
190+
;;
191+
--dry-run)
192+
_dry_run=1
193+
;;
194+
--edit)
195+
if test -z $EDITOR
196+
then
197+
gettextln "ERROR: Shell variable \$EDITOR must be set"
198+
usage
199+
fi
200+
_edit=1
201+
;;
202+
--verbose)
203+
_verbose=1
204+
;;
205+
--)
206+
only_files_left=1
207+
;;
208+
*)
209+
if test $only_files_left -eq 1
210+
then
211+
add_ignore "$1"
212+
fi
213+
;;
214+
esac
215+
shift
216+
done
217+
if test $_edit -eq 1
218+
then
219+
get_git_ignore "$(pwd)/"
220+
git_editor "$gitignore"
221+
fi
222+
exit 0

0 commit comments

Comments
 (0)