How can I run "git status" and just get the filenames as opposed to the long relative path?
10 Answers
The output of git status --porcelain
, designed to be easy to parse in a script, outputs the full paths rather than relative paths regardless of where your current directory is within the tree.
Each line output by git status --porcelain
has two leading characters indicating the status of the file (e.g. whether it's untracked, modified, new, deleted, etc.) followed by a space, so if you just want the full paths of everything that would be mentioned in the output of git status
you can do:
git status --porcelain | sed s/^...//

- 446,582
- 72
- 411
- 327
-
12Same as git status -s but without coloring. – earlonrails Feb 06 '13 at 18:51
-
1I found I was looking for a slightly different question, but this still includes the status marker (which I don't believe there is an option to remove). @sehe's answer is better if you purely want the filename and nothing else. – Isaac Aggrey Aug 07 '13 at 22:05
-
1@IsaacAggrey: except that with sehe's answer you have to run multiple commands, and even those commands will miss untracked files that would appear in the output of git status, so it's not an accurate answer to the question. It's easy to strip off the status characters from the start of the output produced by what I suggested - I've edited my answer to show how. – Mark Longair Aug 23 '13 at 08:59
-
1@earlonrails its only the same if you're at the root, run the same commands from a subdirectory of the repo and you'll see one uses relative paths to the working directory, the other full paths in the repo's root – jxramos Mar 28 '18 at 23:55
-
2@jxramos You can still use cut just change the flag for git status command, `git status --porcelain | cut -c4-`. IMO `cut` is better than using `sed` because more systems will have `cut` already installed. – earlonrails Apr 02 '18 at 18:41
-
1Does not produce pathnames relative to current directory like [`git status | cut` answer](https://stackoverflow.com/a/14736749/4035845) – anthumchris Mar 14 '19 at 21:18
I think cut
is good for this.
git status -s | cut -c4-

- 57,944
- 17
- 167
- 143

- 4,966
- 3
- 32
- 47
-
2and here I was using sed to strip the status codes. never used the -c flag for cut before. nice! add this to your .gitconfig for a good daystarter: `de=!$EDITOR $( git status --porcelain | cut -c4- ) & # open all changed files in EDITOR` – John Hart Aug 02 '13 at 22:09
-
16For someone who are not familiar with `cut` command, `cut -c 4-` means, take characters from fourth character. – Sanghyun Lee Feb 20 '14 at 07:15
-
1
Aha, I think I just understood the question: you want basenames? Tack on | while read a; do basename "$a"; done
to any of the following:
how about
git diff --name-only
for changes relative to index
git diff --name-only --staged
for ... well staged chages :)
git diff --name-only HEAD
got both

- 374,641
- 47
- 450
- 633
-
I see, if you want just _basenames_ tack this on at the end of any: ` | while read fname; do basename "$fname"; done` – sehe Mar 16 '11 at 14:27
-
1Does not produce pathnames relative to current directory like [git status | cut answer](https://stackoverflow.com/a/14736749/4035845) – anthumchris Mar 14 '19 at 21:13
-
Even though it certainly only outputs relative to the root of the git repository, this is a much more to the point solution than `git status --porcelain`, since you don't need to process/clean up its output. – Miguel Ruiz Nov 03 '21 at 17:34
-
Works just great: `vi \`git dno\`` I believe the dno shortcut for git diff came in my gitconfig by default. – k00ka Feb 09 '22 at 17:43
A much simpler solution that is built-in to git
using ls-files
.
From the docs:
OPTIONS
-c --cached Show cached files in the output (default)
-d --deleted Show deleted files in the output
-m --modified Show modified files in the output
-o --others Show other (i.e. untracked) files in the output
-i --ignored Show only ignored files in the output. When showing files in the index, print only those matched by an exclude pattern. When showing "other" files, show only those matched by an exclude pattern. Standard ignore rules are not automatically activated, therefore at least one of the --exclude* options is required.
-s --stage Show staged contents' mode bits, object name and stage number in the output.
-u --unmerged Show unmerged files in the output (forces --stage)
Example showing flags can be combined as well:
git ls-files -dmo

- 360
- 3
- 11
-
Very nice. I used `git ls-files -m | grep pom.xml` after running `mvn org.codehaus.mojo:versions-maven-plugin:2.7:set` in my jenkins job. That way i don't have to know what all modules are in the project and worry about missing adding/committing them. – ranma2913 Jul 13 '22 at 15:24
Get the name of modified files
git status --porcelain|awk '{if($1=="M") {print "basename " $2}}'|sh
I use similar script to copy my modified files to a remote server, as below:
git status --porcelain|awk '{if($1=="M") {print "scp " $2 " account_name@server_ip:~/my_codebase/$(dirname " $2 ")/;"} }'|sh

- 61
- 5
-
2There's an easier way to search using awk: `git status --porcelain | awk '/^ M/{ print $2 }'` – Kyle Gibson Dec 31 '12 at 05:17
git status outputs relative paths so if you cd to the same directory as the file (under your working directory's root) before running git status it will only output the basenames of added/staged files.
cd /long/path/to/my/repo/root/dir
"stuff" > ./newfile.txt
> git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: /long/path/to/my/repo/root/dir/plus/some/more/levels/of/directory/structure/inside/it/changed_file.txt
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# long/path/to/my/repo/root/dir/plus/some/even/more/levels/of/directory/structure/inside/it/but_another_new_file.txt
# newfile.txt
no changes added to commit (use "git add" and/or "git commit -a")
ie, 'newfile.txt' is listed without the full path because you're in the same path as it.

- 452
- 4
- 10
git status
will always walk down (edit and up) the tree and display relative paths. If you only want the file in the directory you are in, See this related answer

- 1
- 1

- 11,780
- 9
- 47
- 67
In addition to the accepted answer, another way of doing it is with awk
git status --porcelain | awk '{ print $2 }'
The $2
selects second the column of each line.

- 21
- 1
If you're looking for only the filenames without the path mumbo-jumbo the following should work:
git status --porcelain | cut -c 3- | xargs basename -a
This script gets the shortened format of git status, cuts each line's 3rd column to the end and feeds it to the basename
command which outputs only the filename from the full path.

- 3,614
- 1
- 22
- 35
If you are using git ls-files
, as suggested here by Peter Benjamin, know that, with Git 2.40 (Q1 2023), its options have been clarified.
See commit e750951, commit 4173b80, commit 2b02d2d, commit 2a34b31 (13 Jan 2023) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit 3eda830, 03 Feb 2023)
ls-files
: clarify descriptions of file selection optionsSigned-off-by: Elijah Newren
The previous descriptions of the file selection options were very easy to misunderstand.
For example:
- "Show cached files in the output" This could be interpreted as meaning "show files which have been modified and git-add'ed, i.e.
files which have cached changes relative to HEAD".- "Show deleted files" This could be interpreted as meaning "for each
git rm $FILE
(man) we ran, show me$FILE
"- "Show modified files" This could be interpreted as meaning "show files which have been modified and git-add'ed" or as "show me files that differ from HEAD" or as "show me undeleted files different from HEAD" (given that
--deleted
is a separate option), none of which are correct.Further, it's not very clear when some options only modify and/or override other options, as was the case with
--ignored
,--directory
, and--unmerged
(I've seen folks confused by each of them on the mailing list, sometimes even fellow Git developers.)Tweak these definitions, and the one for
--killed
, to try to make them all a bit more clear.
Finally, also clarify early on that duplicate reports for paths are often expected (both when (a) there are multiple entries for the file in the index -- i.e.
when there are conflicts, and also (b) when the user specifies options that might pick the same file multiple times, such asgit
ls-files--cached
--deleted --modified``(man) when there is a file with an unstaged deletion).
git ls-files
now includes in its man page:
--cached
:Show all files cached in Git's index, i.e. all tracked files. (This is the default if no
-c
/-s
/-d
/-o
/-u
/-k
/-m
/--resolve-undo
options are specified.)
git ls-files
now includes in its man page:
--deleted
:Show files with an unstaged deletion
git ls-files
now includes in its man page:
--modified
:Show files with an unstaged modification (note that an unstaged deletion also counts as an unstaged modification)
git ls-files
now includes in its man page:
--ignored
Show only ignored files in the output.
Must be used with either an explicit '-c
' or '-o
'.
- When showing files in the index (i.e. when used with '
-c
'), print only those files matching an exclude pattern.- When showing "other" files (i.e. when used with '
-o
'), show only those matched by an exclude pattern.Standard ignore rules are not automatically activated, therefore at least one of the
--exclude*
options is required.
git ls-files
now includes in its man page:
--unmerged
:Show information about unmerged files in the output, but do not show any other tracked files (forces
--stage
, overrides--cached
).
git ls-files
now includes in its man page:
--killed
Show untracked files on the filesystem that need to be removed due to file/directory conflicts for tracked files to be able to be written to the filesystem.

- 1,262,500
- 529
- 4,410
- 5,250