"git status" 像 "ls -1" 这样的简短格式?

"git status" in brief or short format like "ls -1"?

我需要把一堆改变过的文件 scp 放到不同的盒子里进行测试。我无法弄清楚如何让 git status 给我一个像 ls -1 这样的列表,这样我就可以用最少的努力编写操作脚本。

我有一个现有脚本可以使用 ls -1 执行我需要的操作。我不是一个有天赋的脚本编写者,所以我不想修改脚本。相反,我希望该工具能够修改其输出。

显然,git status -1 没有用。 How can I get 'git status' to always use short format 中的格式与我的脚本不兼容。 git status --column 产生了与下面相同的结果。

如何让 git status 列出修改过的文件,一个到一行,只有修改过的文件在该行?


$ 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

git status --porcelain

这将以短格式输出,但在 Git 的所有版本中都是一致的。

git-status documentation

以下是参考文献的摘录:

--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.

正如 Thomas 所建议的,--porcelain 选项正是您想要的。但是当然,要仅获取修改文件的文件名,您还需要解析该输出。例如,通过像这样的简单 sed 脚本传输输出可能有效:

git status --porcelain | sed -ne '/^M  */s///p'

此脚本在行首搜索 M 和空格。如果找到它们,它们将被删除并打印该行。如果未找到它们(即输出不是 M 修改后的文件),则不会显示任何输出。

上面命令行的输出应该与您从 ls -1 获得的输出大致相同——即文件列表,没有其他信息。请注意 --porcelain 以 NULL 终止文件名,因此如果输出未按预期运行,您可能需要在脚本或另一个管道中处理它。 (阅读 xargs(1))。

如果您有未暂存的更改,您可以使用以下命令在类似于 ls -1 的单列列表中列出所有已触及的文件:

git ls-files --modified --others --exclude-standard --directory

--modified选项显示修改过的文件,--others选项显示新文件等其他未跟踪的文件; --exclude-standard 忽略排除的文件,--directory 只列出目录名而不是其中的文件。有关详细信息,请参阅 documentation

这是我用来将所有修改过的文件和新文件快速复制到我的临时目录同时保留完整目录路径的命令(git stash 的一个肮脏的替代方法):

git ls-files --modified --others --exclude-standard --directory | xargs -I {} cp --parents {} ~/temp

如果您已经将要提交的文件添加到 git(例如,git add -A .),那么您可以使用接受的答案中的命令并提取第二列以获取您的普通内容文件列表:

git status --porcelain | awk '{ print }'

如果你想按 git 状态过滤行,那么你可以这样做:

git status --porcelain | grep ^[AM] | awk '{ print }'

这为您提供了一个仅包含修改的 (M) 和新添加的 (A) 文件的列表。


更新:

  • 添加了@jotik 的建议。

对于修改后的文件列表,以下命令可以提供帮助。

git diff --name-only

git diff --name-status

int --name-status 的输出,status(A, M, D) 和文件路径名用制表符分隔,可以用cut命令解析。

如果你也可以在暂存中获取文件列表,可以使用 `--cache' 选项。

要检测更改的文件并将它们 scp 直接发送到远程服务器:

scp `git status --porcelain | cut -c 4-` bb:~/${PWD##*/}