查找包含对给定文件的更改的Git分支

时间:2011-06-06 21:50:23

标签: git

我有57个当地分支机构。我知道我对其中一个文件中的某个文件进行了更改,但我不确定是哪一个。是否有某种命令可以运行以查找哪些分支包含对某个文件的更改?

5 个答案:

答案 0 :(得分:69)

查找包含对FILENAME的更改的所有分支(即使在(未记录的)分支点之前)

FILENAME="<filename>"
git log --all --format=%H $FILENAME | while read f; do git branch --contains $f; done | sort -u

手动检查:

gitk --all --date-order -- $FILENAME

查找未合并到主控的FILENAME的所有更改:

git for-each-ref --format="%(refname:short)" refs/heads | grep -v master | while read br; do git cherry master $br | while read x h; do if [ "`git log -n 1 --format=%H $h -- $FILENAME`" = "$h" ]; then echo $br; fi; done; done | sort -u

答案 1 :(得分:38)

你需要的只是

git log --all -- path/to/file/filename

如果您想立即了解分支,您也可以使用:

git log --all --format=%5 -- path/to/file/filename | xargs -I{} -n 1 echo {} found in && git branch --contains {}

此外,如果您有任何重命名,您可能希望在Git日志命令中包含--follow

答案 2 :(得分:4)

看起来,如果没有适当的解决方案,这仍然是一个问题。我没有足够的积分来发表评论,所以这是我的一点贡献。

塞思·罗伯逊(Seth Robertson)的第一种解决方案对我来说很奏效,但只给了我本地分支机构,其中有许多误报,可能是由于稳定分支机构的合并所致。

亚当·迪米特鲁克(Adam Dymitruk)的第二个解决方案对我根本不起作用。对于初学者来说,--format =%5是什么?它无法被git识别,我找不到任何信息,也无法与其他格式选项一起使用。

但是他的第一个解决方案与--source选项和简单的grep相结合被证明是有帮助的:

git log --all --source -- <filename> | grep -o "refs/.*" | sort -u

这给了我许多远程标记和分支以及一个本地分支,在这里我对该文件进行了最新更改。不知道这有多完善。

答案 3 :(得分:1)

我知道这个问题很古老,但是在开发自己的解决方案之前,我一直回头再问。我觉得它更优雅,这要归功于使用合并基础过滤掉不需要的分支。

#!/bin/bash

file=$1
base=${2:-master}

b=$(tput bold) # Pretty print
n=$(tput sgr0)

echo "Searching for branches with changes to $file related to the $base branch"

# We look through all the local branches using plumbing
for branch in $(git for-each-ref --format='%(refname:short)' refs/heads/); do
  # We're establishing a shared ancestor between base and branch, to only find forward changes.  
  merge_base=$(git merge-base $base $branch)
  # Check if there are any changes in a given path.
  changes=$(git diff $merge_base..$branch --stat -- $file)

  if [[ ! -z $changes ]]; then
    echo "Branch: ${b}$branch${n} | Merge Base: $merge_base"
    # Show change statistics pretty formatted
    git diff $merge_base..$branch --stat -- $file
  fi
done

如果您以git-find-changes的身份将其放入PATH(具有可执行权限),则可以使用git find-changes /path进行调用

示例输出 git find-changes app/models/

Branch: update_callbacks | Merge base: db07d23b5d9600d88ba0864aca8fe79aad14e55b
 app/models/api/callback_config.rb | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
Branch: repackaging | Merge base: 76578b9b7ee373fbe541a9e39cf93cf5ff150c73
 app/models/order.rb                 | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

答案 4 :(得分:0)

以下是一种不优雅的暴力方法,但我认为它应该有效。确保首先隐藏任何未提交的更改,因为它会切换您当前所在的分支。

for branch in $(git for-each-ref --format="%(refname:short)" refs/heads); do
    git checkout $branch && git grep SOMETHING
done