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

mnowg1ta  于 2023-11-15  发布在  Git
关注(0)|答案(4)|浏览(152)

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

git commit --amend -m 'xxxxxxx'

字符串
或者交互式随机提交:

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


我想以编程方式合并一条消息,但要更改到之前的提交,而不仅仅是最后一次提交。
我想要修改的提交已经被推送到git服务器上,但是让其他人重新同步git项目并不是一个问题。

nnt7mjpx

nnt7mjpx1#

你不能简单地“修改”一个任意提交的原因是提交是不可变的。当你修改一个提交时,它实际上是用另一个提交替换当前提交,并将你的分支移动到新提交。带有旧消息、作者姓名等的提交仍然存在于历史中,直到你清理它:

Before:

        master
          |
          v
A -- B -- C

字符串

After:

        master
          |
          v
A -- B -- C'
      \
       \- C


为了模拟“修改”一个任意的提交,你不仅要重写那个提交,还要重写它之后的整个历史,因为一个提交包括它的父提交作为它不可变数据的一部分:

Before:

        master
          |
          v
A -- B -- C

After:

         master
           |
           v
A -- B' -- C'
 \ 
  \- B --- C


你可以通过在你感兴趣的提交上创建一个分支,修改它,并将原始提交到原始分支顶端的提交范围重新定基到新的分支上。下面是一个例子来展示你的目标:

Start:

             master
               |
               v
A -- B -- C -- D

New Branch:

             master
               |
               v
A -- B -- C -- D
     ^
     |
    temp

Amend:

             master
               |
               v
A -- B -- C -- D
 \
  \- B'
     ^
     |
    temp

Rebase:

A -- B  -- C  -- D
 \
  \- B' -- C' -- D'
     ^           ^
     |           |
    temp       master

Cleanup:

A -- B  -- C  -- D
 \
  \- B' -- C' -- D'
                 ^
                 |
               master


这和交互式变基在你只修改一个提交时所做的差不多,顺便说一下,除了没有显式的临时分支。

tvokkenx

tvokkenx2#

如果你只是更改了一些提交,使用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

字符串
pick切换到reword,您将获得一个编辑器来重写提交消息。
如果你需要对很多提交做同样的事情,使用git filter-branch--msg-filter。原始提交消息在stdin上,新提交消息在stdout上。这里有一个在当前分支的所有提交中将“color”改为“color”的方法。

git filter-branch --msg-filter "perl -ple 's{color}{colour}g'"

sd2nnvve

sd2nnvve3#

因为你想以编程的方式进行修改,交互式rebase(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

字符串

goucqfw6

goucqfw64#

与重定基和强制推送修改后的分支不同,可以用不同的消息替换提交,而不会影响现有的提交哈希:

git checkout <commit>
git commit --amend -m "New message"
git replace <commit> $(git rev-parse HEAD)

字符串
这也可以通过以下交互方式完成:

git replace --edit <commit>


请注意,修改后的引用必须显式地通过以下命令进行推送和获取:

git push origin 'refs/replace/*'
git fetch origin 'refs/replace/*:refs/replace/*'

相关问题