6

我克隆了一些 git 存储库,并做了“git branch abcd”,将我切换到从 origin/abcd 派生的分支。abcd 不是默认的原始分支。然后,我从 abcd 创建了一个功能分支“my_feature”。我想在脚本中将“git merge origin/abcd”添加到 my_feature 中,无论使用的源分支的名称如何(或者至少适用于在其他一些答案中没有描述复杂分支结构的简单情况下)混帐)。

如何找到创建当前分支的“最近”/“父”分支?

4

2 回答 2

3

这很难做好。在 git 中,分支只是指向提交的自动前进指针,提交上可以有任意数量的分支名称。考虑这种情况:

your master:      y1---y2---y3
                 /
master: a---b---c---d---e
                 \
feature:          f1---f2---f3---f4

您在 、 、 和 签出了分支“master” c,并提交了y1y2y3。您的历史因此看起来像a b c y1 y2 y3。同时master已经升级到dand e,但是有人创建了一个特性分支并f1通过f4基于c. Git 无法确定您的分支来自master而不是feature,因此您最多可以选择要合并的分支。

如果您自动执行此操作,则必须应用启发式方法来选择最短的分支,最长的分支,或提交最多/最少的分支,或其他类似的东西。自然,既然有这么多的选择,对于一个git内置函数来说,它并不是一个真正的好选择。但是,使用 git 的“管道”功能,您可以编写自己的:

#!/bin/bash

# Tries to determine a good merge base from among all local branches.
# Here used, a "good" merge base is the one sharing the most recent commit
# on this branch. This function will exit 1 if no branch is found,
# or exit 2 in a tie.
#
# Untested - use at your own risk.

MAX_SEARCH=20   # only search the last 20 commits on this branch
FOUND=0
LAST_BRANCH=

# iterate through the commits, most recent first
for COMMIT in $(git rev-list --max-count=$MAX_SEARCH HEAD); do
  # check every local branch
  for BRANCH in $(git for-each-ref --format="%(refname)" refs/heads); do
    # look for the commit in that branch's history
    if (git rev-list $BRANCH | fgrep -q COMMIT); then
      echo $BRANCH
      FOUND=$((FOUND + 1))
      LAST_BRANCH="$BRANCH"
    fi
  done
  if [ $FOUND -gt 1 ]; then
    # more than one choice; exit
    exit 2
  elif [ $FOUND -eq 1 ]; then
    git merge $LAST_BRANCH
    exit 0
  fi
done
exit 1   # could not find a parent
于 2012-11-01T17:01:18.170 回答
2

对于 DVCS,没有“父分支”之类的东西。

一个分支是:

  • 一个名字
  • 开始提交,并且该提交可以:
    • 多个分支的一部分,来自本地仓库和上游仓库,如“ origin”。
    • 在分支变基后更改

查看更多:

脚本工作的唯一方法是记录 的名称origin/branch,最好记录为 a git notes(因为它不会更改历史记录和 SHA1,但会添加元数据)。

于 2012-11-01T01:34:34.817 回答