简体   繁体   English

如何显示在 git 工作树中修改的分支上更改的文件

[英]How to show files changed on a branch that are modified in the git working tree

I need Linux-only shell pipeline or single script that shows the list of files that I've locally modified (either staged or unstaged) that are already committed into some different branch, call that topic-branch , without having to first commit my changes onto any branch.我需要仅 Linux shell 管道或单个脚本,以显示我已在本地修改(暂存或未暂存)的文件列表,这些文件已提交到某个不同的分支,调用该topic-branch ,而无需先提交我的更改到任何分支。 Typically, topic-branch , would be master , but not always.通常, topic-branch将是master ,但并非总是如此。 The current git repository may or may not be checked out into topic-branch .当前的 git 存储库可能会也可能不会检出到topic-branch中。

Ideally, the above should be expressed as a single git command whereby I pass it a name of a branch, and it outputs the list in the format that is emitted by this command:理想情况下,上述内容应表示为单个git 命令,我将分支名称传递给它,并以该命令发出的格式输出列表:

git ls-files --full-name

I am not asking for comparing what is already checked into two separate branches, as there are answers for that already.我不是要求比较已经检查到两个单独分支的内容,因为已经有答案了。

This is the answer I have right now, and it works: I add the following script into a directory that is in my $PATH , called git-cfm , give it execute permissions, and then can invoke it via simply:这是我现在得到的答案,它可以工作:我将以下脚本添加到我的$PATH目录中,名为git-cfm ,赋予它执行权限,然后可以通过简单地调用它:

git cfm

However, this is not the solution I'm looking for, because it incurs a social burden to convince my fellow developers to modify their $PATH in their startup scripts ( ~/.bashrc or ~/.cshrc etc.) to include the central directory where the git-cfm file would resides.但是,这不是我正在寻找的解决方案,因为说服我的开发人员在他们的启动脚本( ~/.bashrc~/.cshrc等)中修改他们的$PATH以包含中央会产生社会负担git-cfm文件所在的目录。 Strangely enough, this is technically possible, but sociologically difficult in my social context:奇怪的是,这在技术上是可行的,但在我的社会背景下在社会学上是困难的:

#!/bin/bash

# git-cfm: <c>hanged <f>iles on <m>aster
#
# List files that have been changed on $branch, that are
# also locally modified (or staged for commit).
# 
# This could be simplified by using, say, Python.
#

# Default $branch to master
branch=${1:-master}

(
  # Get the status using -s which shows both unstaged and staged files
  # in a line-sequential output format, rip off the first column using
  # cut, and then call git-ls-files multiple times on each one to get
  # the full-name of each of them (e.g., a path relative to whatever
  # directory would be returned by "git rev-parse --show-toplevel") .
  # Use the -r option on the call to git-ls-files to avoid calling
  # git-ls-files _unless_ there is actual output from the command,
  # because without the -r, git-ls-files will dump ALL of the files
  # relative to the current working directory, which is NOT what we
  # want.  What we want is the full path name, relative to the
  # top-level directory of the working tree. :
  git status -s 2>/dev/null | cut -c4- | xargs -n100 -r git ls-files --full-name

  # In addition to the above possibly empty output, get all files from
  # all commits on the master branch, that are not changed from
  # commits on the current branch.  Uniquify the output, because of
  # commits that change the same file will result in duplicate files
  # being listed. The empty --pretty option prevents git log default
  # output to include the commit hash, and instead only give us the
  # filenames by using the --name-only option. This comes out as
  # "full-path"'s as indicated above, and is the reason for the
  # --full-name above, too:
  git log --pretty= --name-only @..master | sort | uniq

  # Explanation of the subsequent pipeline below: The file sort and
  # uniq -c emits lines that give counts of occurances in the input.
  # Any occurrances greater than 1 are the ones that we want, so we
  # use awk to show only those. This is just set-theory (AND
  # operation) of the two sets (one set of files per pipeline above)
  # above:
) | sort | uniq -c | awk '{ if ($1 != 1) { print $2; } }'   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM