我在一个有两个分支a和B的项目上工作。我通常在分支a上工作,并合并分支B中的内容。对于合并,我通常会这样做:

git merge origin/branchB

但是,我也希望保留分支B的本地副本,因为我可能会偶尔检查分支,而不必首先与分支a合并。为此,我会:

git checkout branchB
git pull
git checkout branchA

有没有一种方法可以在一个命令中完成上述操作,而不必来回切换分支?我应该使用gitupdate-ref吗?怎样


当前回答

您可以简单地git将原始分支B拉到分支A中,git将为您完成此操作。

其他回答

您可以克隆回购并在新回购中进行合并。在同一个文件系统上,这将硬链接而不是复制大部分数据。最后将结果拉入原始回购。

正如Amber所说,快进合并是唯一可以想象得到的情况。任何其他合并都可能需要经过整个三方合并,应用补丁,解决冲突-这意味着需要有文件。

我身边正好有一个脚本:在不接触工作树的情况下进行快速向前合并(除非您要合并到HEAD)。它有点长,因为它至少有点健壮——它检查以确保合并是快速前进的,然后在不检查分支的情况下执行它,但会产生与之前相同的结果——您可以看到更改的diff-stat摘要,并且reflog中的条目与快速前进的合并完全相同,而不是使用branch-f时得到的“重置”结果。如果将其命名为gitmergeff并将其放到bin目录中,则可以将其作为git命令调用:gitmergeff。

#!/bin/bash

_usage() {
    echo "Usage: git merge-ff <branch> <committish-to-merge>" 1>&2
    exit 1
}

_merge_ff() {
    branch="$1"
    commit="$2"

    branch_orig_hash="$(git show-ref -s --verify refs/heads/$branch 2> /dev/null)"
    if [ $? -ne 0 ]; then
        echo "Error: unknown branch $branch" 1>&2
        _usage
    fi

    commit_orig_hash="$(git rev-parse --verify $commit 2> /dev/null)"
    if [ $? -ne 0 ]; then
        echo "Error: unknown revision $commit" 1>&2
        _usage
    fi

    if [ "$(git symbolic-ref HEAD)" = "refs/heads/$branch" ]; then
        git merge $quiet --ff-only "$commit"
    else
        if [ "$(git merge-base $branch_orig_hash $commit_orig_hash)" != "$branch_orig_hash" ]; then
            echo "Error: merging $commit into $branch would not be a fast-forward" 1>&2
            exit 1
        fi
        echo "Updating ${branch_orig_hash:0:7}..${commit_orig_hash:0:7}"
        if git update-ref -m "merge $commit: Fast forward" "refs/heads/$branch" "$commit_orig_hash" "$branch_orig_hash"; then
            if [ -z $quiet ]; then
                echo "Fast forward"
                git diff --stat "$branch@{1}" "$branch"
            fi
        else
            echo "Error: fast forward using update-ref failed" 1>&2
        fi
    fi
}

while getopts "q" opt; do
    case $opt in
        q ) quiet="-q";;
        * ) ;;
    esac
done
shift $((OPTIND-1))

case $# in
    2 ) _merge_ff "$1" "$2";;
    * ) _usage
esac

注:如果有人看到该脚本有任何问题,请评论!这是一份写就忘的工作,但我很乐意改进它。

另一种公认的蛮力方法是重新创建分支:

git fetch remote
git branch -f localbranch remote/remotebranch

这将丢弃本地过时的分支,并重新创建一个同名分支,因此请谨慎使用。。。

输入git前向合并:

无需签出目标,git forward merge<source><destination>将源合并到目标分支。

https://github.com/schuyler1d/git-forward-merge

仅适用于自动合并,如果存在冲突,则需要使用常规合并。

在您的情况下,您可以使用

git fetch origin branchB:branchB

它可以满足您的需要(假设合并是快速进行的)。如果由于需要非快速合并而无法更新分支,那么这将安全地失败,并显示一条消息。

这种形式的获取也有一些更有用的选项:

git fetch <remote> <sourceBranch>:<destinationBranch>

请注意,<remote>可以是本地存储库,<sourceBranch>可以是跟踪分支。因此,您可以在不访问网络的情况下更新本地分支,即使它未检出。

目前,我的上游服务器访问是通过一个缓慢的VPN,所以我定期连接,gitfetch更新所有远程设备,然后断开连接。如果远程主机发生了变化,我可以

git fetch . remotes/origin/master:master

即使我目前有其他分支机构结账,也能安全地让我的本地主管了解最新情况。无需网络访问。