How can I restrict git status to regular files in

2019-03-14 12:13发布

问题:

I would like to see the status of the current directory. Because there are lots of changes in sub-directories, which I do not want to see, the following command doesn't do the trick:

git status .

Is there any way of getting this kind of report, short of grepping the output of git status?

回答1:

Use git-status -- <pathspec>...

The synopsis of the git-status man page tells you that you can filter by paths:

git status [<options>...] [--] [<pathspec>...]

Therefore, all you have to do is get a list of paths corresponding to the regular (non-directory) files in the current directory, and pass that to git-status.

There is one gotcha: because git status reports about the whole repository if passed an empty <pathspec>... argument, you need to check whether the list is empty or not.

Shell script

Here is a small shell script that does what you want.

#!/bin/sh

# git-status-dot
#
# Show the status of non-directory files (if any) in the working directory
#
# To make a Git alias called 'status-dot' out of this script,
# put the latter on your search path, make it executable, and run
#
#   git config --global alias.status-dot '! git-status-dot'

# Because GIt aliases are run from the top-level directory of the repo,
# we need to change directory back to $GIT_PREFIX.
[ "$GIT_PREFIX" != "" ] && cd "$GIT_PREFIX"

# List Non-Directory Files in the Current Directory
lsnondirdot=$(ls -ap | grep -v /)

# If "lsnondirdot" is not empty, pass its value to "git status".
if [ -n "$lsnondirdot" ]
then
    git status -- $lsnondirdot
else
    printf "No non-directory files in the working directory\n"
fi

exit $?

For more details about why the GIT_PREFIX shenanigans are required, see git aliases operate in the wrong directory.

The script is available at Jubobs/git-aliases on GitHub.

Make a Git alias out of it

For convenience, you can create a Git alias that calls the script; make sure the script is on your path, though.

git config --global alias.statusdot '!sh git-status-dot.sh'

Toy example

Here is a toy example demonstrating how to use the resulting alias and what it does.

# initialize a repo
$ mkdir testgit
$ cd testgit
$ git init

# create two files
$ mkdir foo
$ touch foo/foo.txt
$ touch bar.txt

# good old git status reports that subdir/test1.txt is untracked... 
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    bar.txt
    foo/

nothing added to commit but untracked files present (use "git add" to track)
# ... whereas our new alias, git status-dot, only cares
# about regular files in the current directory
$ git status-dot
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    bar.txt

nothing added to commit but untracked files present (use "git add" to track)

# and if we delete README.md ...
$ rm README.md
# ... good old git status still bother us about /subdir ...
$ git status
Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    foo/

nothing added to commit but untracked files present (use "git add" to track)
# ... whereas git statusdot doesn't
$ git status-dot
No non-directory files in the working directory
$


回答2:

Maybe there's a more proper way to do this, but you can simply

find . -maxdepth 1 -type f -print0 | xargs -0 git status

Of course, this fails if there's no regular files on the current directory. In that case, you can use the extra ugly version

find . -maxdepth 1 -type f -print0 | xargs -0 git status nonexistentfile

And, no, I'm not going to address the case where you have a file named nonexistentfile.



回答3:

You can use:

git status | grep -v /

to filter out any paths that contain a slash (/) which means they are in subdirectories.

You will also lose the red/green coloring of the changed paths.

Update:

This solution does not display the files that are moved from or to the current directory because the source and destination of a move operation are displayed on the same line in the output. The files that were renamed in the current directory (without being moved between directories) are displayed though.



回答4:

I believe the answer is no...

Unless the files are untracked files, submodules, or ignored files. The full documentation for the status command mentions nothing about limiting the output to the current directory.

However, you might want to consider using the stash command to clean up your working tree. If you stash everything not in your current directory (which requires the --patch option to only stash selective parts), then status will only show what you didn't stash. However, if you use stash multiple times while working, then you should always have a clean working tree and you could avoid this problem to begin with. Each body of work will be packaged up in a separate stash waiting until you are ready to commit it.

Of course, that doesn't help much with your current situation (aside from using (stash --patch). Another alternative you might want to try is the interactive mode of the add command. Then you can go through all the changed files and selectively add the ones you want (stash --patch works the same way).

Or, you can use the grep solutions suggested in other answers.