【问题标题】:Show the original branch for a commit显示提交的原始分支
【发布时间】:2011-05-30 22:23:08
【问题描述】:

我使用 git-blame 来查找特定的提交。现在我想找到它最初来自的分支。 (从那里,我将使用分支名称来查找特定票证)

让我们将“原始分支”定义为“在分支合并到任何其他分支之前提交的分支”。

【问题讨论】:

    标签: git branch git-branch


    【解决方案1】:

    就像其他人所说的那样,如果您要查找的分支不是您指责此提交的存储库的本地分支(例如,仅在远程开发人员的个人存储库中的分支),那么您就完蛋了。

    但假设你可以看到广受欢迎的分支,当然你有提交的哈希,比如d590f2...,部分答案是你可以这样做:

    $ git branch --contains d590f2
      tests
    * master
    

    然后,只是为了确认你有罪魁祸首:

    $ git rev-list tests | grep d590f2
    

    当然,如果d590f2已经合并到多个分支中,你就必须比这更微妙。

    【讨论】:

    • 如果 3 个月后,一个提交现在属于多个分支,那么您的策略将如何给我原始分支名称?请注意,可以有快进/非快进合并。
    【解决方案2】:

    这在 git 中并不适用。分支是每个存储库的本地概念:一个人的“local-stuff”分支可以与另一个人的“local-stuff”分支完全分开。如果您执行诸如查看主要集成分支和查询提交之类的操作,并删除两者之间的所有合并基础,您应该能够获得提交历史的子树,这可能会有所启发......或者可能不会.例如如果您跟踪从查询提交到“master”的链接,您应该希望找到带有有用 cmets 的合并提交,说明合并的来源......但这些信息只是信息性的,没有以某种方式记录,旨在自动检索。

    例如gitk some-commit...master(几乎是gitk some-commit master --not $(git merge-base some-commit master)的缩写)

    【讨论】:

      【解决方案3】:

      Git 分支只不过是一个“指向提交的命名指针”(与其他著名的 VCS 相比,这是一个根本不同的概念)。

      这种情况很清楚,commit A 在branch-1,commit B 在branch-2

        o A [branch-1]
        |
      o | B [branch-2]
      | |
      

      合并后变得不清楚A(或B)最初是在branch-1还是branch-2

      o [branch-1] [branch-2]
      |
      o merged 
      |\
      | o A
      | |
      o | B
      | |
      

      如果你标记了 A 的父提交,也许你可以猜出提交 A 是哪个 Git 分支,例如release-1 并且您知道这个标签仅用于branch-1 中的提交。

      o [branch-1] [branch-2]
      |
      o merged 
      |\
      | o A
      | |
      o | B
      | |
      | o <release-1]
      | |
      

      【讨论】:

      • 严格来说,只有快进合并才不可能。如果所有合并都使用--no-ff 完成,那么 git 也会保留分支历史记录。就做git log --graph $commit_id .. HEAD
      • 一般来说,在 Git 中,提交不在分支上,分支在提交上。
      【解决方案4】:

      我试一试,由于不完全确定,请发表评论,但我相信它可以完成工作。

      仅当分支在合并到 master 之前仍然指向尖端时才有效,如果分支在同一个 repo 上就是这种情况:

      o [master]
      |
      o merged branch "great-feature" into master
      |\
      | o A [great-feature]
      | |
      o | B
      | |
      

      如果不是这样(例如,如果您从另一个仓库中提取),您仍然可以手动重新创建它们。

      首先获取你的提交所在的分支:

      $ git branch -a --contains=<sha-of-B>
      *master
      great-feature
      

      然后为每个分支获取将它们的头部与提交分开的提交数:这是在指定范围内输出 git log 的行数:

      $ git log --pretty=oneline <sha-of-B>..great-feature | wc -l
      1
      $ git log --pretty=oneline <sha-of-B>..master | wc -l
      4
      

      所以B最接近great-feature,这意味着它是在其中创建的。

      这可以做成一个不错的脚本,随意添加到答案中(我不擅长这个)

      【讨论】:

      • 我认为您可以使用git rev-list --count 而不是通过管道将git log 连接到wc
      【解决方案5】:

      首先确保您从远程获取更改

      $ git fetch --all
      

      还有,

      $ git branch -a --contains d590f2
      

      如果没有 -a 选项,您将无法找到仅存在于远程分支上的提交

      【讨论】:

        【解决方案6】:

        当您在分支上时,“原始分支” 已合并到。你可以运行:

        git log <SHA>..HEAD --ancestry-path --merges
        

        此命令将显示&lt;SHA&gt;..HEAD 之间的所有merge 提交。你需要最后一个。

        例如对于c0118fa 提交(最后一个),“原始分支”redesign_interactions

        * ccfd449 (HEAD -> develop) Require to return undef if no digits found
        *   93dd5ff Merge pull request #4 from KES777/clean_api
        |\  
        | * 39d82d1 Fix tc0118faests for debugging debugger internals
        | * ed67179 Move &push_frame out of core
        | * 2fd84b5 Do not lose info about call point
        | * 3ab09a2 Improve debugger output: Show info about emitted events
        | *   a435005 Merge branch 'redesign_interactions' into clean_api
        | |\  
        | | * a06cc29 Code comments
        | | * d5d6266 Remove copy/paste code
        | | * c0118fa Allow command to choose how continue interaction
        | | * 19cb534 Emit &interact event
        

        你应该运行:

        git log c0118fa..HEAD --ancestry-path --merges
        

        然后向下滚动以查找最后一次提交。即:

        commit a435005445a6752dfe788b8d994e155b3cd9778f
        Merge: 0953cac a06cc29
        Author: Eugen Konkov
        Date:   Sat Oct 1 00:54:18 2016 +0300
        
            Merge branch 'redesign_interactions' into clean_api
        

        【讨论】:

          【解决方案7】:

          我找到了一种更简单的方法:它在git log &lt;sha&gt;..HEAD --merges的最后一次提交的消息中!

          这个命令显示了master和commit之间发生的合并;该命令的最后一个提交输出是包含它的第一个合并提交。它通常包含分支名称,因此即使分支被删除,您也可以找到它的名称。

          要仅获取分支的名称,只需输入git log &lt;sha&gt;..HEAD --merges --oneline |tail -1

          【讨论】:

          • 这仅适用于没有快进合并的情况。
          • @meagar 同意,顺便说一句,将功能合并到 master 中并使用快进并不是一个好习惯,因为这个确切的原因:在历史上更好地看到功能已被合并
          • 谢谢 CharlesB,你刚刚救了我的培根。我不小心删除了一个远程分支并且没有本地 reflog,因为我的项目在另一台我无权访问的计算机上。所以我需要在合并之前重建最后一次提交,以便我可以复活分支。
          • @CharlesB ,下面我提出一个想法。我并不是假设包含 的工作线已合并到 master 中。一个通用的(可能是部分的)解决方案可以是:让 B ={所有包含 的分支引用}。过滤器 B 以丢弃所有创建日期晚于 的创建日期的分支 ref。现在,使用 ref log 跟踪剩余分支 ref 的移动并找到第一个接触/创建 的分支 ref。当然这里需要参考日志。有没有cmets?
          【解决方案8】:

          这似乎不是一个可以通过 git 100% 准确回答的问题。

          git branch --contains --merge <sha1>
          

          返回提交合并到的所有分支和原始分支的列表。 --no-merged 返回包含提交的所有后续分支,因为它们在合并点之后分支。

          因此,您可以获得每个合并但不是原始分支的列表,并且在命令执行之前删除的任何分支都会丢失(或您查看 reflog)

          结果

          git branch --contains <sha1 for "added feature/inital 1">
          * develop
            feature/inital
            feature/subsequent1
          
          git branch --contains <sha1 for "added feature/inital 1"> --merged
          * develop
            feature/inital
          
          git branch --contains <sha1 for "added feature/inital 1"> --no-merged
            feature/inital
          

          测试脚本

          function mkbranch {
            git checkout -b $1
            git push --set-upstream origin $1
          }
          
          # Develop
          mkbranch develop
          for f in 1 2 3; do date > file${f}.txt;  git add file${f}.txt; git commit -m "added develop $f"; done
          git push
          
          # Initial Feature Branch
          mkbranch feature/inital
          for f in 1 3; do date > file${f}.txt;  git add file${f}.txt; git commit -m "modified feature/inital $f"; done
          git push
          
          # Merge
          git checkout -b develop
          git merge feature/inital
          git push
          
          
          # Next Feature Branch
          mkbranch feature/subsequent1
          for f in 1 3; do date > file${f}.txt;  git add file${f}.txt; git commit -m "modified feature/subsequent1 $f"; done
          git push
          

          【讨论】:

            【解决方案9】:

            这足以让我从 Jenkins 工作区中的分离头获取分支名称:

            git show -s --pretty=%d

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-01-01
              • 1970-01-01
              • 2020-03-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多