【问题标题】:How do I find the most recent git commit that modified a file?如何找到修改文件的最新 git 提交?
【发布时间】:2011-06-14 15:35:40
【问题描述】:

我想查找修改源文件的最新提交。

我可以使用git blame 来查看每一行的所有提交日期,但很难确切地看到哪个提交是最后一次触及文件的提交。

如何在我的 git 存储库中找到触及给定文件的最后一次提交?

【问题讨论】:

    标签: git search


    【解决方案1】:

    git log 支持查看特定文件(和目录)的历史记录,所以你可以这样称呼它:

    git log my/file.c
    

    如果您真的只想列出 一个 最近的提交,例如在脚本中使用它,请使用 -n 1 选项:

    git log -n 1 --pretty=format:%H -- my/file.c
    

    --pretty=format:%h 告诉git log 只显示提交哈希。 -- 分隔符阻止文件名被解释为提交名称,以防它不明确。

    【讨论】:

    • 如果想知道文件最后一次修改的时间,不管是哪个分支,都可以考虑所有分支,加上--all选项。
    • 如果这里的任何人有代表进行 1 个字符的编辑,现在这个答案中链接到的 URL 的 https 版本。
    【解决方案2】:

    要仅在一行中获取 ref,请尝试:

    git log -n1 --oneline <path> | awk '{print $1;}'
    

    【讨论】:

      【解决方案3】:

      如果您只想查找最近的提交,那么您不需要git-log,您需要git-rev-list,它列出了在该提交路径中更改该文件的提交对象,从最近的一个开始(按时间顺序)。简单地说:

      git rev-list -1 &lt;commit&gt; &lt;filename&gt;

      对于您的情况,git-rev-list,您只需提供:

      • 要包含的提交数,或 -1 仅表示最近的提交,
      • 开始回顾的分支(或提交 ID),HEAD 如果你已经在上面,或者 --all 如果你想要所有已知的提交,并且
      • 文件的相对路径。

      这只是返回当前分支中最近的提交 ID 以更改该文件,例如:215095e2e338525be0baeeebdf66bfbb304e7270

      对于更复杂的示例,您可以使用标记名称,甚至是远程引用,并包含带有通配符的相对路径名称,例如:

      git rev-list origin/user/bob/testbranch -1 src/bfiles/*.txt

      ...这将告诉您该分支历史上通配符匹配的最新变化。 rev-list 的选项是极端的,它是最重要的管道命令之一,因此您可以按照您能想象到的任何标准来包含或排除。

      当然可以参考git-rev-list(1) Manual Page

      【讨论】:

      • 你真的没有解释为什么使用git-log是劣等的。
      • 我不会说逊色,只是它默认提供无关信息。 git-rev-list 只返回提交 ID,如果您要将响应提供给脚本或其他自动化过程,这就是您想要的。 git-log 返回有关所选提交的信息,首先使用 git-rev-list 收集提交 ID,然后收集每个提交的信息。如果您只是要过滤掉提交信息并使用 id,那么您可以首先使用 git-rev-list。由于 log 是基于 rev-list 的,所以它采用了大部分相同的过滤器参数。
      • git-log 是瓷器,git-rev-list 是管道。
      • 请注意,如果您合并了来自不同分支的提交,则此方法不会为您提供合并提交(正如我所预料的那样,因为它是向我的分支引入此更改的提交)但是合并的原始提交。只是要记住的事情。还没有找到获取合并提交的命令,但我确定有一个
      【解决方案4】:

      如果您只想获取最新提交的哈希来修改一组特定的文件(并且想避免awk),您可以使用:

      git log -n 1 --pretty=format:%h -- <path>
      

      这对于获取提交哈希以便随后与git describe 一起使用非常有用。

      例如(如果它对任何人都有用)……

      我通过考虑更改任何源文件的最新提交来创建当前版本 ID(假设您使用 mycode-1.2.1 之类的标签标记版本):

      COMMIT=$(git log -n 1 --pretty=format:%h -- *.c *.h)
      if VN=$(git describe --always --abbrev=5 --match "mycode-*" $COMMIT 2>/dev/null) &&
      case "$VN" in
      mycode-*)
          git update-index -q --refresh
          test -z "$(git diff-index --name-only HEAD *.c *.h)" ||
          VN="$VN-mod" ;;
      *) VN="mycode-unknown-g$VN" ;;
      esac
      then
          continue
      else
      VN="mycode-unknown"
      fi
      

      这会产生像这样的 id:

      • mycode-1.2.1 - 当源文件的当前状态对应于标记版本时
      • mycode-1.2.1-g3k7s2 - 当源文件的当前状态对应于标记版本之后的提交时
      • mycode-1.2.1-g3k7s2-mod - 源文件的当前状态自标记版本后的最后一次提交以来已被修改
      • mycode-unknown - 尚未创建版本标签时

      【讨论】:

      • $VN 看起来像是某种噩梦不死 SVN
      【解决方案5】:

      一旦您有了想要使用git log FILENAME 查看的提交的SHA id,您应该能够执行git show SHA_ID_HERE 来查看您为该特定提交做了什么。您甚至不需要输入整个 ID;前 6 个字符应该足够了。

      【讨论】:

      • 这比 OP 要求的要多一点,但仅供参考,您可以将其组合成一条线:git show $(git log -1 --pretty="%H" -- FILENAME)
      【解决方案6】:

      我不确定这是否是您想要的,但如果您执行git log &lt;thefile&gt; 来获取更改该文件的提交。您可以选择最上面的一个。它应该是你要找的那个。

      【讨论】:

      • 如果您使用git log -n1 -- &lt;thefile&gt;(或者如果您想浪费资源,则将输出通过管道传输到head -1),您不必手动选择顶行(参见Jo Liss 的answer
      • 好点。我想你也可以跳过-n,直接使用-1
      猜你喜欢
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 2019-03-08
      • 2011-04-22
      • 2015-11-29
      • 1970-01-01
      相关资源
      最近更新 更多