问题
I need to take a bunch of files that have changed and scp
them to different boxes for testing. I'm having trouble figuring out how to make git status
give me a listing like ls -1
so I can script the actions with minimal effort.
I have an existing script that does what I need using ls -1
. I'm not a gifted scripter, so I don't want to modify the script. Instead, I would like the tool to modify its output.
Obviously, git status -1
did not work. The format in How can I get 'git status' to always use short format is not compatible with my script. And git status --column
produced the same result as below.
How do I have git status
list modified files, one to a line, with only the modified file on the line?
$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 2 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: cryptest.vcproj
modified: dlltest.vcproj
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: adler32.cpp
modified: algebra.cpp
modified: algparam.cpp
modified: asn.cpp
modified: asn.h
modified: authenc.cpp
modified: authenc.h
modified: basecode.cpp
modified: cast.cpp
modified: ccm.cpp
modified: cmac.cpp
modified: config.h
modified: cryptdll.vcproj
modified: cryptlib.cpp
modified: cryptlib.h
modified: cryptlib.vcproj
modified: datatest.cpp
modified: dlltest.cpp
modified: eax.cpp
modified: ec2n.cpp
modified: eccrypto.cpp
modified: ecp.cpp
modified: emsa2.cpp
modified: eprecomp.cpp
modified: esign.cpp
modified: files.cpp
modified: filters.cpp
modified: filters.h
modified: fips140.cpp
modified: fipsalgt.cpp
modified: fltrimpl.h
modified: gf2_32.cpp
modified: gf2n.cpp
modified: gf2n.h
modified: gfpcrypt.cpp
modified: gfpcrypt.h
modified: hkdf.h
modified: hmac.cpp
modified: hrtimer.cpp
modified: ida.cpp
modified: idea.cpp
modified: integer.cpp
modified: iterhash.cpp
modified: luc.h
modified: misc.cpp
modified: misc.h
modified: modes.cpp
modified: modes.h
modified: nbtheory.cpp
modified: network.cpp
modified: oaep.cpp
modified: panama.cpp
modified: pkcspad.cpp
modified: polynomi.cpp
modified: pssr.cpp
modified: pubkey.h
modified: pwdbased.h
modified: queue.cpp
modified: rijndael.cpp
modified: rsa.cpp
modified: rw.cpp
modified: salsa.cpp
modified: seal.cpp
modified: secblock.h
modified: simple.h
modified: smartptr.h
modified: socketft.cpp
modified: socketft.h
modified: sosemanuk.cpp
modified: strciphr.cpp
modified: strciphr.h
modified: test.cpp
modified: validat1.cpp
modified: validat2.cpp
modified: vmac.cpp
modified: wait.cpp
modified: winpipes.cpp
modified: winpipes.h
modified: words.h
modified: xtr.cpp
modified: xtr.h
modified: zdeflate.cpp
modified: zinflate.cpp
回答1:
git status --porcelain
This will output in short format but will be consistent across all versions of Git.
git-status documentation
Here is an excerpt from the reference:
--porcelain
Give the output in an easy-to-parse format for scripts. This is similar to the short output, but will remain stable across Git versions and regardless of user configuration.
回答2:
If you have unstaged changes, you can list all the touched files in a one-column list similar to ls -1
with this command:
git ls-files --modified --others --exclude-standard --directory
The --modified
option shows modified files and the --others
option shows other untracked files such as new files; --exclude-standard
ignores excluded files and --directory
lists only directory names and not the files inside them. Refer to the documentation for more information.
Here's the command I use to quickly copy all modified and new files to my temp directory while preserving the full directory path (a dirty alternative to git stash
):
git ls-files --modified --others --exclude-standard --directory | xargs -I {} cp --parents {} ~/temp
If you have already added the files to git to be committed (e.g., git add -A .
), then you can use the command in the accepted answer and extract the second column to get your plain list of files:
git status --porcelain | awk '{ print $2 }'
If you want to filter the rows by git status, then you can do something like this:
git status --porcelain | grep ^[AM] | awk '{ print $2 }'
This gives you a list containing only modified (M
) and newly added (A
) files.
Updates:
- Added @jotik's suggestion.
回答3:
As Thomas suggested, the --porcelain
option is the thing you want. But of course, to get JUST the filename of modified files, you need to parse that output as well. For example, piping the output through a simple sed script like this may work:
git status --porcelain | sed -ne '/^M */s///p'
This script searches for a M
and whitespace at the beginning of the line. If they are found, they are removed and the line is printed. If they are not found (i.e. the output is something other than a M
odified file), no output is shown.
The output of the command line above should be just about equivalent to what you get from ls -1
-- that is, a list of files, with no other information. Note that --porcelain
terminates filenames with a NULL, so if the output does not function as you expect, you may need to handle that in your script, or in another pipe. (Read about xargs(1)
).
回答4:
For modified file list, the following commands can be a help.
git diff --name-only
or
git diff --name-status
int the output of --name-status, the status(A, M, D) and file pathname is separated by tab, you can parse it by cut
command.
If you can to get file list on staging too, `--cache' option can be used.
回答5:
To detect changed files and scp
them directly to the remote server :
scp `git status --porcelain | cut -c 4-` bb:~/${PWD##*/}
来源:https://stackoverflow.com/questions/31523712/git-status-in-brief-or-short-format-like-ls-1