Git 如何选择提交范围并合并到另一个分支中?

Git 如何选择提交范围并合并到另一个分支中?,git,git-merge,git-cherry-pick,Git,Git Merge,Git Cherry Pick,我有以下存储库布局: 总科(生产) 整合 工作 我想要实现的是从工作分支中挑选一系列提交,并将其合并到集成分支中。我对git还很陌生,我不知道如何准确地做到这一点(在一个操作中选择提交范围,而不是合并),而不破坏存储库。有什么建议或想法吗?谢谢 当涉及到一系列提交时,挑选樱桃是不实际的 到目前为止,Git 1.7.2+引入了樱桃选择一系列提交的功能(但您仍然需要注意) git cherry pick“学会了选择一系列提交 (例如“cherry pick A..B”和“cherry pick-

我有以下存储库布局:

  • 总科(生产)
  • 整合
  • 工作

我想要实现的是从工作分支中挑选一系列提交,并将其合并到集成分支中。我对git还很陌生,我不知道如何准确地做到这一点(在一个操作中选择提交范围,而不是合并),而不破坏存储库。有什么建议或想法吗?谢谢

当涉及到一系列提交时,挑选樱桃是不实际的

到目前为止,Git 1.7.2+引入了樱桃选择一系列提交的功能(但您仍然需要注意)

git cherry pick“学会了选择一系列提交
(例如“
cherry pick A..B
”和“
cherry pick--stdin
”,还有“
git revert
”。不过,这些都不支持更好的排序控制“
rebase[-i]
”已经

并警告我们:

在“
cherry pick A..B
”表单中,
A
应早于
B

如果顺序错误,命令将自动失败

如果您想通过
D
(包括
B
选择范围
B
则为
B^..D
(而不是
B..D
)。
请参见“”作为示例

如前所述:

这假定
B
不是根提交;否则将出现“
未知修订版”
”错误

注意:从Git 2.9.x/2.10(2016年第3季度)开始,您可以在孤立分支(空头)上直接选择提交范围:请参阅“”


原始答复(2010年1月)

rebase--on
会更好,您可以在集成分支的顶部重放给定的提交范围,如下所示。
(另外,请在中查找“以下是如何将基于一个分支的主题分支移植到另一个分支”,以查看
git-rebase--on
的实际示例)

如果您当前的分支是集成:

#在当前位置签出新的临时分支
git签出-b tmp
#将集成分支移动到新补丁集的头部
git branch-f集成工作分支范围的最后一个分支
#将补丁集重新设置到tmp上,tmp是旧的集成位置
git rebase——进入tmp第一个\u SHA-1 \u工作\u分支\u范围~1集成
将在以下时间之间重播所有内容:

  • 工作分支范围的第一个\u SHA-1\u的父级之后(因此是
    ~1
    ):要重播的第一个提交
  • 直到“
    integration
    ”(从
    working
    分支指向要重播的最后一次提交)
到“
tmp
”(指向
integration
之前指向的位置)

如果在重播其中一个提交时存在任何冲突:

  • 解决它并运行“
    git-rebase--continue
  • 或者跳过此修补程序,而是运行“
    git-rebase--skip
  • 或者使用“
    git-rebase--abort
    ”(并将
    tmp
    分支上的
    integration
    分支放回)来取消所有操作
在此之后,
rebase--on
integration
将在集成分支的最后一次提交时返回(即“
tmp
”分支+所有重播的提交)

在樱桃采摘或
重设基础--
时,不要忘记它会对后续合并产生影响,如


一个纯粹的“
cherry pick
”解决方案是,并将涉及如下内容:

如果您想使用补丁方法,那么“git格式补丁| git am”和“git cherry”是您的选项。
目前,
git cherry pick
只接受一次提交,但是如果您想从
B
D
选择范围,那么在git行话中应该是
B^..D
,所以

git版本列表--反向--拓扑顺序B^..D |同时读取版本
做
git cherry pick$rev | | break
完成

但无论如何,当您需要“重播”一系列提交时,“重播”一词应该会促使您使用Git的“
rebase
”功能。

当涉及到一系列提交时,cherry Pick是不实用的

到目前为止,Git 1.7.2+引入了樱桃选择一系列提交的功能(但您仍然需要注意)

git cherry pick“学会了选择一系列提交
(例如“
cherry pick A..B
”和“
cherry pick--stdin
”),以及“
git revert
”;但是,它们不支持“
rebase[-i]
”所具有的更好的排序控制

并警告我们:

在“
cherry pick A..B
”表单中,
A
应早于
B

如果顺序错误,命令将自动失败

如果您想通过
D
(包括
B
选择范围
B
则为
B^..D
(而不是
B..D
)。
请参见“”作为示例

如前所述:

这假设
B
不是根提交;否则将出现“
未知修订版”
”错误

注意:从Git 2.9.x/2.10(2016年第3季度)开始,您可以在孤立分支(空头)上直接选择提交范围:请参阅“”


原始答复(2010年1月)

rebase--on
会更好,您可以在集成分支的顶部重放给定的提交范围,如下所示。
(另外,请在中查找“以下是如何将基于一个分支的主题分支移植到另一个分支”,以查看
git-rebase--on
的实际示例)

如果您当前的分支是集成:

#在当前位置签出新的临时分支
git签出
git format-patch A..B
git checkout integration
git am *.patch
#!/bin/bash

if [ -z $1 ]; then
    echo "Equivalent to running git-cherry-pick on each of the commits in the range specified.";
    echo "";
    echo "Usage:  $0 start^..end";
    echo "";
    exit 1;
fi

git rev-list --reverse --topo-order $1 | while read rev 
do 
  git cherry-pick $rev || break 
done 
master: 1234 2345 3456 4567 git merge -s ours 4567 git merge 2345
enter code here



  #!/bin/bash

    # This script will merge the diff between two git revisions to checked out branch
    # Make sure to cd to git source area and checkout the target branch
    # Make sure that checked out branch is clean run "git reset --hard HEAD"


    START=$1
    END=$2

    echo Start version: $START
    echo End version: $END

    mkdir -p ~/temp
    echo > /tmp/status
    #get files
    git --no-pager  diff  --name-only ${START}..${END} > ~/temp/files
    echo > ~/temp/error.log
    # merge every file
    for file in `cat  ~/temp/files`
    do
      git --no-pager diff --binary ${START}..${END} $file > ~/temp/git-diff
      if [ $? -ne 0 ]
      then
#      Diff usually fail if the file got deleted 
        echo Skipping the merge: git diff command failed for $file >> ~/temp/error.log
        echo Skipping the merge: git diff command failed for $file
        echo "STATUS: FAILED $file" >>  /tmp/status
        echo "STATUS: FAILED $file"
    # skip the merge for this file and continue the merge for others
        rm -f ~/temp/git-diff
        continue
      fi

      git apply  --ignore-space-change --ignore-whitespace  --3way --allow-binary-replacement ~/temp/git-diff

      if [ $? -ne 0 ]
       then
#  apply failed, but it will fall back to 3-way merge, you can ignore this failure
         echo "git apply command filed for $file"
       fi
       echo
       STATUS=`git status -s $file`


       if [ ! "$STATUS" ]
       then
#   status is null if the merged diffs are already present in the target file
         echo "STATUS:NOT_MERGED $file"
         echo "STATUS: NOT_MERGED $file$"  >>  /tmp/status
       else
#     3 way merge is successful
         echo STATUS: $STATUS
         echo "STATUS: $STATUS"  >>  /tmp/status
       fi
    done

    echo GIT merge failed for below listed files

    cat ~/temp/error.log

    echo "Git merge status per file is available in /tmp/status"
 git checkout <branchA>
git checkout <branchB>
git cherry-pick <commitA>^..<commitB>
git cherry-pick --continue
git rebase -i FIRST LAST~0 --onto integration
git rebase @ integration