Search code examples
gitversion-control

Rewording large number of Git commits automatically, specific for a project file contained in a folder with bunch of other files


I used rebase tool for rewording the commits but that opens VIM editor and I have to reword the commit messages one by one which a very time-consuming process, especially when you have large number git commits to reword. I can't find a way to automatically reword commits messages without opening VIM editor again and again.

I am trying to find the way that lets me extract particular commits for a specific project by picking up the Hash IDs in the excel and automatically reword the commits according the excel data, in git repository.


Solution

  • You can pass one or more --exec <cmd> to git rebase. The cmd is appended to each line creating a commit, and they are executed as part of the rebase todo.

    In your case, don't use r/reword, use p/pick plus a cmd like git commit --amend --no-edit -m "$(some_gen_msg_function)" to rewrite the commit message. Implement some_gen_msg_function to generate the commit message for each rebased commit. During the rebase process, the symbolic refs like HEAD, ORIG_HEAD and other files under .git and .git/rebase-merges could help to retrieve necessary information. Instead of joining path segments, git rev-parse --absolute-git-dir is recommended to get the absolute path to .git.

    Here's a demo.

    # The log before rebase
    * 265fbf7 (HEAD -> master) d
    * cc4d19a c
    * 0fc1698 b
    * 6233cf2 a
    * de7e639 root
    
    # You may want -r, --keep-empty, --empty=keep to deal with merge commits and empty commits
    git rebase -i --onto de7e639 6233cf2 master \
        --exec 'git commit --amend --no-edit -m "$(git log -1 --pretty=%s) oops"'
    
    # The rebase todo
    pick 0fc1698 b
    exec git commit --amend --no-edit -m"$(git log -1 --pretty=%s) oops"
    pick cc4d19a c
    exec git commit --amend --no-edit -m"$(git log -1 --pretty=%s) oops"
    pick 265fbf7 d
    exec git commit --amend --no-edit -m"$(git log -1 --pretty=%s) oops"
    
    # The log after rebase
    * 4dda51c (HEAD -> master) d oops
    * e38b153 c oops
    * adc8b70 b oops
    * de7e639 root
    

    In git rebase, you may want -r, --keep-empty and --empty=keep.