关于git:我怎么知道分支是否已经合并为master?


How can I know if a branch has been already merged into master?

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

我怎么知道哪些分支已经合并到主分支中?


git branch --merged master列出合并为master的分支

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

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

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


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

请注意,git branch -d已经做了这种事情,因为它将拒绝删除尚未完全合并的分支。


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

gitk --all

一个新的应用程序窗口将提示您整个仓库的图形表示,如果分支已经合并,很容易实现


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
}


使用git merge-base

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

这是步骤

  • 在master分支上查找最后一次提交哈希
  • 在"分支"上查找上次提交哈希
  • 运行命令git merge-base
  • 如果步骤3的输出与步骤2的输出相同,则"分支"已经合并到主设备中。
  • 有关git merge-base https://git-scm.com/docs/git-merge-base的更多信息。


    关于清理远程分支的主题

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

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

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

    如果你正在使用'tig'(它像gitk但是基于终端)那么你可以

    1
    tig origin/feature/someones-decaying-feature

    查看分支的提交历史,而无需git checkout


    当我需要弄清楚一个分支是否已经合并时,这是我的技术,即使它已经被重新定义为与我们的主分支最新,这是特征分支的常见场景。

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

    1显示所有分支的日志

    使用像gitk或TortoiseGit这样的可视化工具,或者简单地使用--all进行git log,浏览历史记录以查看与主分支的所有合并。您应该能够发现此特定功能分支是否已合并。

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

    如果您习惯在合并功能分支时始终同时删除本地和远程分支,则只需更新并修剪其他计算机上的远程分支,功能分支就会消失。

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

    示例创建/完成功能分支

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    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的/钩/流后的功能完成

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    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分支上找到具有相同消息的提交

    主分支上的示例命令:

    1
    2
    3
    gru                  
    gls origin/feature/foo
    glf"my message"

    在我的bash .profile配置中

    1
    2
    3
    4
    5
    6
    alias gru='git remote update -p'
    alias glf=findCommitByMessage

    findCommitByMessage() {
        git log -i --grep="$1"
    }


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

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

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

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

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

    然后我可以打电话:

    1
    $ git current origin/master

    检查我是否是最新的。


    为了验证哪些分支合并为master,您应该使用以下命令:

    • git branch --merged master所有分支的列表合并为master。
    • git branch --merged master | wc -l计算合并为master的所有分支的数量。

    标志是:

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

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