【问题标题】:How can I know if a branch has been already merged into master?我怎么知道一个分支是否已经合并到 master 中?
【发布时间】:2021-05-17 07:49:44
【问题描述】:

我有一个带有多个分支的 git 存储库。

如何知道哪些分支已经合并到主分支中?

【问题讨论】:

    标签: git


    【解决方案1】:

    git branch --merged master 列出合并到 master

    中的分支

    git branch --merged 列出合并到 HEAD 中的分支(即当前分支的尖端)

    git branch --no-merged列出尚未合并的分支

    默认情况下,这仅适用于本地分支机构。 -a 标志将显示本地和远程分支,-r 标志仅显示远程分支。

    【讨论】:

    • 顺便说明一下,当我尝试查看远程分支是否已合并时,我首先设置了一个本地跟踪分支,使用git branch --merged 识别状态,然后删除本地和远程分支。
    • 显然,git branch -a --merged/no-merged 也可以工作,而无需在此过程中创建本地跟踪分支。
    • 或者只是 git branch -r --merged/--no-merged 只查找远程分支。
    • 有什么方法可以删除变基后实际合并的未合并分支?
    • 请注意,--merged/--no-merged 后面有一个可选的提交参数。至少在我的 git (1.9.1) 版本中,在它之后添加 -a-r 标志会给我一个致命错误。添加-a-r 之前 --(no-)merged
    【解决方案2】:

    您可以使用git merge-base 命令查找两个分支之间的最新共同提交。如果该提交与您的分支头相同,则该分支已完全合并。

    注意git branch -d 已经做了这种事情,因为它会拒绝删除一个还没有已经完全合并的分支。

    【讨论】:

    • @hari 的 answer 详细介绍了如何使用它。
    • 我们如何自动/以编程方式做到这一点?
    • "还没有完全合并" ...完全合并到哪个分支?
    • @AlexanderMills:进入你当前的分支。
    • @AlexanderMills: git branch -d 将拒绝删除尚未合并到当前分支的分支。不删除 current 分支。
    【解决方案3】:

    还有一个图形界面解决方案。只需输入

    gitk --all

    一个新的应用程序窗口将提示您整个 repo 的图形表示,在该窗口中很容易意识到一个分支是否已经合并

    【讨论】:

    • 需要明确的是,需要安装不属于git 客户端的应用程序。在 Ubuntu 上,apt-get install gitk.
    • 在 macOS 上,如果您安装了 Homebrew,则为 brew install git-gui,以在命令行上获取 gitk
    【解决方案4】:

    为了验证哪些分支被合并到master中,你应该使用这些命令:

    • git branch <flag[-r/-a/none]> --merged master 合并到 master 的所有分支列表。
    • git branch <flag[-r/-a/none]> --merged master | wc -lcount 合并到master的所有分支的数量。

    标志是:

    • -a 标志 - (全部) 显示远程和本地分支
    • -r 标志 - (远程) 仅显示远程分支
    • <emptyFlag> - 仅显示本地分支

    例如:git branch -r --merged master 将显示所有已合并到 master 中的远程存储库。

    【讨论】:

    • 感谢您的出色回答。非常有用且易于使用。这应该设置为答案,因为它使用 git(而不是第 3 方项目)。
    • git branch -r merged main 将显示您在 GitHub 上“删除”的分支,因为 GitHub keeps a record of recently deleted PR branches
    【解决方案5】:

    我正在使用以下 bash 函数,例如:git-is-merged develop feature/new-feature

    git-is-merged () {
      merge_destination_branch=$1
      merge_source_branch=$2
    
      merge_base=$(git merge-base $merge_destination_branch $merge_source_branch)
      merge_source_current_commit=$(git rev-parse $merge_source_branch)
      if [[ $merge_base = $merge_source_current_commit ]]
      then
        echo $merge_source_branch is merged into $merge_destination_branch
        return 0
      else
        echo $merge_source_branch is not merged into $merge_destination_branch
        return 1
      fi
    }
    

    【讨论】:

    • 这实际上不起作用。如果源分支已经被合并到目标分支,然后目标分支又得到了一些提交,它就不再工作了,但我不知道为什么
    • @AlexanderMills 它对我来说很好,即使目标分支在合并源分支后获得更多提交
    【解决方案6】:

    使用git merge-base <commit> <commit>

    此命令在两次提交之间找到最佳共同祖先。如果共同祖先与“分支”的最后一次提交相同,那么我们可以安全地假设“分支”已经合并到主节点中。

    步骤如下

    1. 在主分支上查找最后一次提交哈希
    2. 在“分支”上查找最后一次提交哈希
    3. 运行命令git merge-base <commit-hash-step1> <commit-hash-step2>
    4. 如果步骤 3 的输出与步骤 2 的输出相同,则“分支”已合并到 master。

    有关 git merge-base https://git-scm.com/docs/git-merge-base 的更多信息。

    【讨论】:

    • 我认为这只会告诉您提示是否合并。例如,这不会告诉您 master 是否被合并到 branch,然后又向 branch 添加了 4 个提交。
    • 为什么不是git log -1 $(git merge-base base-branch feature-branch),如果你在输出中看到feature-branch,那么你就知道它们被合并了?
    【解决方案7】:

    关于清理远程分支的话题

    git branch -r | xargs -t -n 1 git branch -r --contains
    

    这会列出每个远程分支,然后列出其最新 SHA 所在的远程分支。

    这有助于辨别哪些远程分支已合并但未删除,哪些尚未合并因此正在衰减。

    如果你使用 'tig'(它类似于 gitk,但基于终端),那么你可以

    tig origin/feature/someones-decaying-feature
    

    无需 git checkout 即可查看分支的提交历史

    【讨论】:

    • 干得好那个人!一旦您了解它实际显示的内容,它就非常有用! GitHub 应用程序需要将其合并到分支的可视化显示中,而不是没有层次结构的按字母顺序排列的列表!
    【解决方案8】:

    我使用git for-each-ref 获取已合并或未合并到给定远程分支的分支列表(例如origin/integration

    遍历所有匹配 的 refs 并根据给定的 显示它们,然后根据给定的 集对它们进行排序。

    注意:如果您倾向于使用git pull 而不是git fetch,请将origin/integration 替换为integration

    合并到远程origin/integration分支的本地分支列表

    git for-each-ref --merged=origin/integration --format="%(refname:short)" refs/heads/
    #                ^                           ^                           ^
    #                A                           B                           C
    branch1
    branch2
    branch3
    branch4
    

    A:只取合并到远程origin/integration分支的分支
    B:打印分支名称
    C:只看heads refs(即分支)

    未合并到远程origin/integration 分支的本地分支列表

    git for-each-ref --no-merged=origin/integration --format="%(committerdate:short) %(refname:short)" --sort=committerdate refs/heads
    #                ^                              ^                                                  ^                    ^
    #                A                              B                                                  C                    D
    2020-01-14 branch10
    2020-01-16 branch11
    2020-01-17 branch12
    2020-01-30 branch13
    

    A:只取未合并到远程origin/integration 分支的分支
    B:打印分支名称以及最后提交日期
    C:按提交日期排序输出
    D:只看heads refs(即分支)

    【讨论】:

      【解决方案9】:

      当我需要确定一个分支是否已被合并时,即使它可能已被重新定位以与我们的主分支保持同步,这是我的技术,这是功能分支的常见场景。

      这些方法都不是万无一失的,但我发现它们有用很多次。

      1 显示所有分支的日志

      使用 gitk 或 TortoiseGit 之类的可视化工具,或者只是 git log 和 --all,查看历史记录以查看所有与主分支的合并。您应该能够发现此特定功能分支是否已合并。

      2 在功能分支中合并时始终删除远程分支

      如果您有一个好习惯,即在合并功能分支时始终删除本地和远程分支,那么您只需在另一台计算机上更新和修剪远程分支,功能分支就会消失。

      为了帮助记住这样做,我已经在使用 git flow extensions (AVH edition) 在本地创建和合并我的功能分支,所以我添加了以下 git flow 挂钩来询问我是否还想自动删除远程分支。

      示例创建/完成功能分支

      554 Andreas:MyRepo(develop)$ git flow start tmp
      Switched to a new branch 'feature/tmp'
      
      Summary of actions:
      - A new branch 'feature/tmp' was created, based on 'develop'
      - You are now on branch 'feature/tmp'
      
      Now, start committing on your feature. When done, use:
      
           git flow feature finish tmp
      
      555 Andreas:MyRepo(feature/tmp)$ git flow finish
      Switched to branch 'develop'
      Your branch is up-to-date with 'if/develop'.
      Already up-to-date.
      
      [post-flow-feature-finish] Delete remote branch? (Y/n)
      Deleting remote branch: origin/feature/tmp.
      
      Deleted branch feature/tmp (was 02a3356).
      
      Summary of actions:
      - The feature branch 'feature/tmp' was merged into 'develop'
      - Feature branch 'feature/tmp' has been locally deleted
      - You are now on branch 'develop'
      
      556 Andreas:ScDesktop (develop)$
      

      .git/hooks/post-flow-feature-finish

      NAME=$1
      ORIGIN=$2
      BRANCH=$3
      
      # Delete remote branch
      # Allows us to read user input below, assigns stdin to keyboard
      exec < /dev/tty
      
      while true; do
        read -p "[post-flow-feature-finish] Delete remote branch? (Y/n) " yn
        if [ "$yn" = "" ]; then
          yn='Y'    
        fi
        case $yn in
            [Yy] ) 
              echo -e "\e[31mDeleting remote branch: $2/$3.\e[0m" || exit "$?"
              git push $2 :$3; 
              break;;
            [Nn] ) 
              echo -e "\e[32mKeeping remote branch.\e[0m" || exit "$?"
              break;;
            * ) echo "Please answer y or n for yes or no.";;
        esac
      done
      
      # Stop reading user input (close STDIN)
      exec <&-
      exit 0
      

      3 按提交信息搜索

      如果您并不总是删除远程分支,您仍然可以搜索类似的提交以确定该分支是否已合并。这里的陷阱是远程分支是否已被重新定位到无法识别的位置,例如压缩提交或更改提交消息。

      • 获取并修剪所有遥控器
      • 在功能分支上查找上次提交的消息
      • 查看是否可以在 master 分支上找到具有相同消息的提交

      master 分支上的示例命令:

      gru                   
      gls origin/feature/foo
      glf "my message"
      

      在我的 bash .profile 配置中

      alias gru='git remote update -p'
      alias glf=findCommitByMessage
      
      findCommitByMessage() {
          git log -i --grep="$1"
      }
      

      【讨论】:

      • @anjdeas - 第 1 步 - 你如何知道哪些分支已合并到 main.js 中。我一直在查看日志和 gui 工具 - 找不到任何明确显示此内容的地方???
      • @TheHuff 试试这个:git log --all --color --graph --decorate --topo-order --date=relative --abbrev-commit --pretty=format:"%C(green)%h %C(red bold)[%&lt;(14)%ad] %Creset%s%Cred%d%C(blue) [%an]"
      • @TheHuff 在 TortoiseGit 中,如果你在主分支上,它应该显示所有合并到主分支。
      • 谢谢 - 但我怎么知道什么是合并?我假设它们都是提交 - 这是对的吗?
      • @TheHuff:您应该直观地看到两个提交流/路径合并到一个提交“下游”(在日志视图中更高)。该提交是合并提交。此外,在 git log 中,您可以添加 --merges 以仅显示合并提交。 stackoverflow.com/a/25986615/134761
      【解决方案10】:

      这里有一个小单线,可以让您知道您当前的分支是否包含来自远程源/主分支的数据:

      $ git fetch && git branch -r --merged | grep -q origin/master && echo Incorporates origin/master || echo Out of date from origin/master
      

      我在处理功能分支时遇到了这个问题,并且经常想确保我将最新的工作合并到我自己的单独工作分支中。

      为了概括这个测试,我在 ~/.gitconfig 中添加了以下别名:

      [alias]
         current = !git branch -r --merged | grep -q $1 && echo Incorporates $1 || echo Out of date from $1 && :
      

      那我可以打电话了:

      $ git current origin/master
      

      检查我是否是最新的。

      【讨论】:

        【解决方案11】:

        要检查源分支是否已合并到主分支中,可以使用以下 bash 命令:

        git merge-base --is-ancestor <source branch name> master && echo "merged" || echo "not merged"
        

        【讨论】:

          猜你喜欢
          • 2023-03-20
          • 2016-03-23
          相关资源
          最近更新 更多