合并而不更改工作目录

Ida*_*n K 16 git

我有以下场景:

* ab82147 (HEAD, topic) changes
* 8993636 changes
* 82f4426 changes
* 18be5a3 (master) first
Run Code Online (Sandbox Code Playgroud)

我想(非快进)合并topicmaster.这需要我:

  • git checkout master
  • git merge --no-ff topic

但是检查master,然后将主题合并到它会导致git更改我的工作目录(虽然最终结果与检查master之前的结果相同),而我遇到的问题是由于我们项目的大小,构建它需要大约30分钟(使用IncrediBuild)虽然没有真正改变,但它简直无法忍受.

所以我想得到的是以下内容:

*   9075cf4 (HEAD, master) Merge branch 'topic'
|\  
| * ab82147 (topic) changes
| * 8993636 changes
| * 82f4426 changes
|/  
* 18be5a3 first
Run Code Online (Sandbox Code Playgroud)

没有真正触及工作目录(或至少以某种方式欺骗git).

Cas*_*bel 8

有趣!我不认为有这样做的内置方法,但你应该能够使用管道来捏造它:

#!/bin/bash

branch=master
# or take an argument:
# if [ $@ eq 1 ];
#      branch="$1";
# fi

# make sure the branch exists
if ! git rev-parse --verify --quiet --heads "$branch" > /dev/null; then
     echo "error: branch $branch does not exist"
     exit 1
fi

# make sure this could be a fast-forward   
if [ "$(git merge-base HEAD $branch)" == "$(git rev-parse $branch)" ]; then
    # find the branch name associated with HEAD
    currentbranch=$(git symbolic-ref HEAD | sed 's@.*/@@')
    # make the commit
    newcommit=$(echo "Merge branch '$currentbranch'" | git commit-tree $(git log -n 1 --pretty=%T HEAD) -p $branch -p HEAD)
    # move the branch to point to the new commit
    git update-ref -m "merge $currentbranch: Merge made by simulated no-ff" "refs/heads/$branch" $newcommit
else
    echo "error: merging $currentbranch into $branch would not be a fast-forward"
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)

有趣的是那条newcommit=线; 它使用commit-tree直接创建合并提交.第一个参数是要使用的树; 那是树HEAD,你要保留其内容的分支.提交消息在stdin上提供,其余参数命名新提交应具有的父项.提交的SHA1打印到stdout,因此假设提交成功,您捕获它,然后合并该提交(这将是快进).如果你是痴迷,你可以确保commit-tree成功 - 但这应该是非常有保证的.

限制:

  • 这仅适用于可能是快进的合并.显然,在这种情况下,您实际上必须签出并合并(可能在克隆中,以保存您的构建系统).
  • reflog消息不同.我故意这样做,因为当你使用时--no-ff,git实际上会强迫自己使用默认(递归)策略,但是在reflog中写这个是骗局.
  • 如果你处于独立的HEAD模式,事情就会变得糟糕.那必须要特别对待.

是的,我在一个玩具回购中测试了它,它似乎工作正常!(虽然我没有努力打破它.)