0

I need to modify a commit's message given the commit id without changing any other commit info. However, the commit message should accept line breaks,etc similar to how it is done using the git commit command.

For example, consider the following commit

commit <id>
Author: <user-name> <user-email.com>
Date:   ...

    Hello World

I want to reword the commit message to this

    Hello World

    Text after line break1
    More text

The normal method would be to rebase interactively, and then edit the commit using git commit --amend or perform a reword operation on that commit. However, this will modify commit info such as committer email, time etc.

(Check the update section for rebase)

Filter-branch in git will allow to rewrite the commit by only changing the commit message and ids as shown in this answer.

But, how do I reword a commit with the above commit message format using filter-branch ?

Update:

Here's an example for interactive rebase.

  • Create a test repository with 2 commits
    test@ubuntu:~/temp_git$ git init
    Initialized empty Git repository in /home/test/temp_git/.git/
    test@ubuntu:~/temp_git$ touch file1
    test@ubuntu:~/temp_git$ git add .
    test@ubuntu:~/temp_git$ git -c "user.name=A" -c "user.email=a@xyz.com" commit -am "Add File1" --author="B <b@xyz.com>"
    [master (root-commit) f122a34] Add File1
     Author: B <b@xyz.com>
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 file1
    test@ubuntu:~/temp_git$ touch file2
    test@ubuntu:~/temp_git$ git add .
    test@ubuntu:~/temp_git$ git -c "user.name=B" -c "user.email=b@xyz.com" commit -am "Add File2" --author="B <b@xyz.com>"
    [master 3b023cf] Add File2
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 file2
    
  • Commits created above have different author and committer. The complete log is as follows :

    test@ubuntu:~/temp_git$ git log --format="fuller"
    commit 3b023cf256ae3498fbaf740329d94842143a5e4a (HEAD -> master)
    Author:     B <b@xyz.com>
    AuthorDate: Tue Oct 15 08:28:07 2019 +0530
    Commit:     B <b@xyz.com>
    CommitDate: Tue Oct 15 08:28:07 2019 +0530
    
        Add File2
    
    commit f122a341e31691f3170207c9a452ff18846fe120
    Author:     B <b@xyz.com>
    AuthorDate: Tue Oct 15 08:27:22 2019 +0530
    Commit:     A <a@xyz.com>
    CommitDate: Tue Oct 15 08:27:22 2019 +0530
    
        Add File1
    
  • Performing interactive rebase as user A and rewording the root commit

    test@ubuntu:~/temp_git$ git -c "user.name=A" -c "user.email=a@xyz.com" rebase -i --root
    [detached HEAD 228b423] Add File1 (test)
     Author: B <b@xyz.com>
     Date: Tue Oct 15 08:27:22 2019 +0530
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 file1
    Successfully rebased and updated refs/heads/master.
    
  • Updated log with the changes in committer info

    test@ubuntu:~/temp_git$ git log --format="fuller"
    commit 0d5e6a5fed5b22fc5f8e310c6e98b1e6b8a821b8 (HEAD -> master)
    Author:     B <b@xyz.com>
    AuthorDate: Tue Oct 15 08:28:07 2019 +0530
    Commit:     A <a@xyz.com>
    CommitDate: Tue Oct 15 08:31:41 2019 +0530
    
        Add File2
    
    commit 228b423e3e511c5954823e42df51a6f6acae91cf
    Author:     B <b@xyz.com>
    AuthorDate: Tue Oct 15 08:27:22 2019 +0530
    Commit:     A <a@xyz.com>
    CommitDate: Tue Oct 15 08:31:28 2019 +0530
    
        Add File1 (test)
    
Saurabh P Bhandari
  • 6,014
  • 1
  • 19
  • 50

3 Answers3

2

Here are my recommendations:

  1. (Preferred) Don't do it. Don't worry about old commit messages and just be better at new ones.

  2. filter-branch way that you showed in your answer.

  3. Impersonate (this will still affect commit timestamps):

    1. Change your git config to have the name and email of original author of the commit.
    2. git commit --amend or git rebase
tymtam
  • 31,798
  • 8
  • 86
  • 126
1

As answered here, the following script can be used to reword the commit using filter branch:

#! /bin/bash
REV=$1
MESSAGE=$2
FILTER="test $(echo '$GIT_COMMIT') = $(git rev-parse $REV) && echo $MESSAGE || cat"
git filter-branch --msg-filter "$FILTER" -- --all

usage: ./script_name.sh <commit-id> "commit message"

However to add line breaks to the new commit message, I had to modify the commit message to this: "$(echo -e 'summary_line\n\nmessage\nmore_message')" as answered here. The above command adds two line breaks after the summary_line as per the general convention for commits.

Furthermore, the script had to be modified due to the escape sequence characters as mentioned in the comments here:

$MESSAGE in this line $(git rev-parse $REV) && echo $MESSAGE is changed to \"$MESSAGE\"

So the final command if the script name were reword-commit.sh, (to be run inside the git repository)

./reword-commit.sh <commit-id> "$(echo -e 'Hello World\n\nText after line break1\nMore Text')"
Saurabh P Bhandari
  • 6,014
  • 1
  • 19
  • 50
  • Is there a way to specify a text file for the `$MESSAGE` text? And this text file will contain new line characters and apostrophe characters. – Mr-IDE Mar 21 '21 at 16:37
  • @Mr-IDE Probably something like this should help `./reword-commit.sh "$(echo -e '$(cat /path/to/file)')"` – Saurabh P Bhandari Mar 22 '21 at 02:00
  • Just to let you know, this does not work: `./reword-commit.sh "$(echo -e '$(cat /path/to/file)')"` - It gives error: "`cat: /path/to/file: No such file or directory`" . **However this works fine:** `./reword-commit.sh ABC123 "$(cat /path/to/file.txt)"` . On a separate note, the first part of your answer says to use "`echo $MESSAGE`" , but the second part says to use "`echo \"$MESSAGE\"`" . So which one should we use? – Mr-IDE Mar 22 '21 at 14:26
  • @Mr-IDE First part just quotes another answer, the second part talks about what modifications were needed to get it working for my case. For this `It gives error: "cat: /path/to/file: No such file or directory" ` - probably you didn't give the aboslute path of the file containing the message. – Saurabh P Bhandari Mar 22 '21 at 15:47
0

See this link.

You can do an interactive rebase using git rebase -i HEAD~N, which will display "N" commits. You can then go to the commit line you wanna change and rename pick to reword.

After this, you adjust the commit message in the upcoming editor.

[NOTE]

It is not recommended to change/rebase pushed commits because you have to force push and other people have to merge/re-clone the repository.

dan1st
  • 12,568
  • 8
  • 34
  • 67
  • Thank you for the answer, however I would request you to go through the question again, I have already mentioned about interactive rebase – Saurabh P Bhandari Oct 14 '19 at 15:48
  • @SaurabhPBhandari I know but I think that this way of rebase(`reword` instead of `amend commits`) does not change the user info. – dan1st Oct 14 '19 at 16:40