如何以编程方式编辑旧的git提交消息?

Jes*_*s H 6 git git-rebase git-amend git-commit

您可以以编程方式仅编辑最后一次提交消息:

git commit --amend -m 'xxxxxxx'
Run Code Online (Sandbox Code Playgroud)

或者以交互方式随机提交:

git rebase -i HEAD~n
# Vim opens up, select the commit you want to modify, and change the word "pick" for "edit"
git commit --amend -m "Changing an old commit message!"
git rebase --continue
Run Code Online (Sandbox Code Playgroud)

我如何结合两者?我想以编程方式更改消息,但是先前提交,而不仅仅是最后一次.

我想要修改的提交已经被推送到git服务器,但让其他人重新同步git项目并不是一个问题.

Sch*_*ern 7

如果您只是更改了一些提交,请使用git rebase -i"reword"选项.例如...

pick 6256642 mv file1 file2
pick 20c2e82 Add another line to file2

# Rebase 8236784..20c2e82 onto 8236784 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
Run Code Online (Sandbox Code Playgroud)

切换pickreword,您将获得一个编辑器来重写提交消息.


如果你需要做同样的事情到了很多的提交,使用git filter-branch--msg-filter.原始提交消息在stdin上,新的提交消息在stdout上.这是在当前分支的所有提交中将"颜色"更改为"颜色"的一个.

git filter-branch --msg-filter "perl -ple 's{color}{colour}g'"
Run Code Online (Sandbox Code Playgroud)


小智 7

由于您想以编程方式进行更改,因此不能选择交互式变基(git rebase -i)。

无论出于何种原因,编辑旧的提交都会有效地重新调整所有在此基础上的提交。如果您仅更改提交消息,则无需担心合并冲突。

您创建一个新的临时分支,以目标提交作为其 HEAD,编辑提交消息,将旧分支合并到新分支上,然后删除旧的临时分支。

在 shell 脚本中:

CURBRANCH=`git rev-parse --abbrev-ref HEAD`
TMPBRANCH=tmp$$
git checkout $SHA -b $TMPBRANCH
MSG=`tempfile`
git log --format=%B -n 1 HEAD > $MSG
... edit the $MSG file
git commit --amend -F $MSG
SHA=`git rev-list -n 1 HEAD`   # Commit has change, so SHA has also changed
rm $MSG
git rebase --onto $TMPBRANCH HEAD $CURBRANCH
git branch -d $TMPBRANCH
Run Code Online (Sandbox Code Playgroud)


Mad*_*ist 5

您不能简单地“修改”任意提交的原因是提交是不可变的。当您修改提交时,它实际上将当前提交替换为另一提交,并将您的分支移至新提交。历史记录中仍然包含带有旧消息,作者姓名等的提交,直到您将其清除为止:

Before:

        master
          |
          v
A -- B -- C
Run Code Online (Sandbox Code Playgroud)

After:

        master
          |
          v
A -- B -- C'
      \
       \- C
Run Code Online (Sandbox Code Playgroud)

为了模拟“修改”任意提交,您不仅必须重写该提交,还必须重写其后的整个历史记录,因为提交将其父级包含为不可变数据的一部分:

Before:

        master
          |
          v
A -- B -- C
Run Code Online (Sandbox Code Playgroud)

After:

         master
           |
           v
A -- B' -- C'
 \ 
  \- B --- C
Run Code Online (Sandbox Code Playgroud)

为此,您可以在感兴趣的提交上创建一个分支,然后对其进行修改,然后将遵循原始提交范围的提交范围重新定位到新分支的尖端。这是显示您想要做什么的示例:

Start:

             master
               |
               v
A -- B -- C -- D
Run Code Online (Sandbox Code Playgroud)

New Branch:

             master
               |
               v
A -- B -- C -- D
     ^
     |
    temp
Run Code Online (Sandbox Code Playgroud)

Amend:

             master
               |
               v
A -- B -- C -- D
 \
  \- B'
     ^
     |
    temp
Run Code Online (Sandbox Code Playgroud)

Rebase:

A -- B  -- C  -- D
 \
  \- B' -- C' -- D'
     ^           ^
     |           |
    temp       master
Run Code Online (Sandbox Code Playgroud)

Cleanup:

A -- B  -- C  -- D
 \
  \- B' -- C' -- D'
                 ^
                 |
               master
Run Code Online (Sandbox Code Playgroud)

顺便说一下,这实际上是交互式rebase所做的,除非您没有显式的临时分支,否则仅修改单个提交。