git rebase-将原始提交哈希添加到提交消息

时间:2019-01-14 16:15:56

标签: git rebase

是否有任何方法可以在重新设置基础上与cherry-pick -x(将原始提交的哈希添加到复制的提交的消息中)做相同的事情?

我目前可以通过替换以下内容来解决此问题

git checkout other-branch
git rebase master
git checkout master
git merge other-branch

使用

git checkout master
....
git cherry-pick -x other-branch^^^^
git cherry-pick -x other-branch^^^
git cherry-pick -x other-branch^^
git cherry-pick -x other-branch^
git cherry-pick -x other-branch

4 个答案:

答案 0 :(得分:6)

所以,这是我的解决方案:

git rebase <branch> \
-ix "git rev-parse --short HEAD > tmp &&  \
echo 'from: $<branch_shortid>' > tmp && \
git commit --amend -F tmp"

请确保branch_shortid是正确的,并且是在您希望将内容来自的分支上生成的。

免责声明:我不确定这是否在所有情况下都能奏效,特别是如果您正在使用某些奇怪或复杂的引用系统。我在由以下生成的非常简单的git repo上运行了此代码:

$ git init 
$ echo "a" > a.txt && git add . && git commit -m "first commit"
$ git checkout -b "feature1" 
$ echo "b" > b.txt && git add . && git commit -m "second commit"
$ echo "c" > c.txt && git add . && git commit -m "third commit"
$ feature1id=$(git rev-parse --short HEAD)
$ git checkout master
$ git rebase feature1 \
  -ix "git rev-parse --short HEAD > tmp &&  \
  echo 'from: $feature1_id' > tmp && \
  git commit --amend -F tmp"

以下是相应的输出:

enter image description here


讨论:

如前所述,我认为您使用git reflog是一个更好的解决方案,用于调查哪个分支上的提交已合并到所需分支上。

变基点是将提交应用到另一个分支的顶部,就像首先是提交结构一样:

  

重新设置基准会产生linear history

答案 1 :(得分:4)

这不是很漂亮,但是可以完成工作;

git rebase --exec='git log --pretty="format:%B" -n 1 > tmp;
    grep -o "\w\{40\}" .git/rebase-merge/done | tail -n 1 >> tmp; 
    git commit --amend -F tmp; 
    rm tmp;' master

解释--exec脚本的每个部分;

  • 将我们刚刚完成的提交消息放入tmp;
  • .git/rebase-merge/done获取刚刚重新建立的提交的哈希,并将其附加到tmp
  • 使用tmp作为提交消息来修改我们刚刚进行的提交。
  • 删除tmp文件。

我敢肯定,您可以将其破解为一种令人愉悦的格式。

原始作品的日志;

commit 1ebdfc2fd26b0eed9f131197dc3274f6d5048e97
Author: Adam
Date:   Thu Jan 24 16:33:09 2019 +0000

    Content C

commit 632f1a4e1ab5d47c9e4c3ca3abd02a207a5dda09
Author: Adam
Date:   Thu Jan 24 16:33:06 2019 +0000

    Content B

commit a7e0d1eb2e412ec51865ccd405ea513c7677c150
Author: Adam
Date:   Thu Jan 24 16:33:04 2019 +0000

    Content A

基础工作日志;

commit 79d7ece06185b21631248a13416e5ca5c23e55b2
Author: Adam
Date:   Thu Jan 24 16:33:09 2019 +0000

    Content C
    1ebdfc2fd26b0eed9f131197dc3274f6d5048e97

commit d2fe6267165fa05f5fe489a6321b0b1742d1a74c
Author: Adam
Date:   Thu Jan 24 16:33:06 2019 +0000

    Content B
    632f1a4e1ab5d47c9e4c3ca3abd02a207a5dda09

commit da72fab2008e74f6a8e247f93619943805ebf86e
Author: Adam
Date:   Thu Jan 24 16:33:04 2019 +0000

    Content A
    a7e0d1eb2e412ec51865ccd405ea513c7677c150

答案 2 :(得分:2)

https://stackoverflow.com/a/54352290/5203563为基础,我最终得到了一个看起来像这样的脚本

#! /usr/bin/env bash

set -e

if [[ "$@" != "" ]];
then
    git rebase $@ --exec="$0"
    exit 0
fi

HASH="$(grep -o "\w\{40\}" .git/rebase-merge/done | tail -n1)"

git log --pretty="format:%B%n%nwas $HASH" -n1 | git commit --amend -F -

我想避免使用临时文件。我最初是用两个脚本来完成的,但是后来通过递归的方式将它们组合为一个脚本,以便可以轻松地共享它。我将其称为git-record,所以如果您去git record HEAD^^^^,它将把当前的哈希值放入所有提交中(并在此过程中更改所有哈希值)。

答案 3 :(得分:1)

如果您只是使用rebase来进行批处理Cherrypick,则可以轻松地自己构造其选择列表,并使用所需的任何选项进行Cherrypick:

batchxpickto() {
        local U=${1-@{u\}}      # given branch or default to configured upstream 
        local B=`git symbolic-ref -q --short HEAD`  # branch name to move if any
        local L=`git cherry $U.. | awk /^+/{print\$2}`  # commits to pick if any
        git checkout $U && ${L:+git cherry-pick -x $L}
        ${B:+git checkout -B $B}
}

使用batchxpickto master的方式使用git rebase master

真的,我更喜欢Adam's answer,但这是另一种选择,其策略可能更有用。