【问题标题】:How to view a git branch ONLY back to the point where it was branched off? [duplicate]如何仅查看 git 分支回到分支的位置? [复制]
【发布时间】:2024-05-01 21:40:01
【问题描述】:

我注意到当我在一个只有几个提交的分支(我们称之为feat-123)上时,git log 显示了我从 (develop) 分支的分支的整个历史记录。有没有什么方法可以显示日志只回溯到 feat-123 的创建点?

【问题讨论】:

    标签: git


    【解决方案1】:

    如果您知道feat-123 是从develop 分支的,则可以使用双点.. 语法将git log 输出限制为仅在feat-123 中的那些提交,而这些提交不在develop 中:

    git log --oneline --graph develop..feat-123
    

    要了解有关双点和其他有用的提交过滤语法的更多信息,请参阅

    1. Revision Selection - Commit Ranges 来自**FREE online Pro Git book
    2. Git Revisions - Specifying Ranges 来自official Linux Kernel Git documentation

    【讨论】:

      【解决方案2】:

      要查看哪些提交在一个分支上而不是另一个分支上的列表,请使用 git log:

         git log oldbranch ^newbranch --no-merges
      

      显示旧分支上所有不在新分支上的提交的提交日志。

      此外,您可以列出要包含和排除的多个分支,例如

         git log oldbranch1 oldbranch2 ^newbranch1 ^newbranch2 --no-merges
      

      【讨论】:

      • 这对我没有返回任何结果。我做了git log master ^my-feature --no-merges
      【解决方案3】:

      “找到历史重新加入的任何点”没有简写,因此您必须使用类似CupcakeD4NI3LS 建议的内容:在此类事件之前或之前明确停止记录点。

      但是,有一种方法可以自动执行此操作。可以封装在“一行”的shell脚本中:

      git log HEAD --not $(
          git for-each-ref --format='%(refname:short)' refs/heads/ |
          grep -v "^$(git symbolic-ref -q --short HEAD)$"
      ) "$@"
      

      这是如何工作的:

      • 最里面的位 git symbolic-ref -q --short HEAD 打印当前分支名称,如果您不在分支上,则根本不打印(“分离 HEAD”状态)。
      • 我们通过添加 ^(行首锚点)和 $(行尾锚点)将其转换为 grep 模式。
      • 我们使用它来删除git for-each-ref 输出中的当前分支(如果有)。
      • for-each-ref 输出是每个分支的短引用名,即refs/heads/ 中的每个引用。因此,如果您的完整分支名称集是 montypythonflyingcircus,并且您在分支 flying 上,则此列表列出 montypython、和circus
      • 最后,在要求git logHEAD 开始之后,我们将所有这些都交给--notlog 命令使用git rev-list 从您要求的任何地方开始,并继续向后移动,直到某些东西(在本例中为--not 列表)使其停止。当然,我们添加了"$@",以便包含任何其他命令行参数。

      因为它是一个单行,它可以嵌入到~/.gitconfig,作为alias

      [alias]
              ltf = !git log HEAD --not $(git for-each-ref \
                      --format='%(refname:short)' refs/heads | \
                      grep -v "^$(git symbolic-ref -q --short HEAD)$")
      

      现在git ltfgit ltf --oneline 等都可以解决问题。 (我不知道我喜不喜欢ltf这个名字,它代表“log to fork”,但这更像是一个“log to join”。也许lbr代表“log branch”?)

      【讨论】:

      • 别名可能需要终止 --(在最后一个右括号之后)以确保将引用与可能的文件名区分开来。避免错误致命:不明确的参数“文档”:修订和文件名使用“--”将路径与修订分开,如下所示:'git [...] -- [. ..]'。加上最后的"$@" 没有被复制到别名中(但又可能与-- 位置冲突)。
      • 别名的副作用就像"$@" 已经存在一样。我不想终止--,因为我想为log 提供更多选项,例如--oneline。另一方面,--not 仍然有效,也许应该有第二个--not 来取消它...
      • 我会试试 (--not)。我不知道别名 "$@" 操作。谢谢。