How to split every commit by file?

I know how to manually split a commit using git rebase -i , but how can I automatically split every commit in a branch by file?

For instance, commit A modified 3 files, f1, f2 and f3. After the split, there are 3 commits A-f1, A-f2 and A-f3.

I want to do this to make a major rewriting easier as I will only have to squash some small commits.


The Script

The following script splits HEAD by file:

#!/bin/bash

set -e

LF=$'n'
SHA=$(git rev-parse --short HEAD)
MSG=$(git show -s --format=%B HEAD)
set -f; IFS=$'n'
FILES=($(git diff-tree --no-commit-id --name-only -r HEAD))
set +f; unset IFS

git reset HEAD^

for f in "${FILES[@]}"; do
  git add "$f"
  git commit -m "$SHA $f$LF$LF$MSG"
done

The generated commit messages are of the form:

<original SHA> <file name>

<original commit message>

Usage

The following assumes that you can run above script as git-split .

If you want to split all commits in a range by file, use it like this:

git rebase --interactive --exec git-split <branch>

If you want to split a single commit during an interactive rebase, use it like this:

p Commit to split
x git-split

Any improvements to the script are welcome.


For every commit, you would need

  • first to list all files in that commit

    git diff-tree --no-commit-id --name-only -r <SHA1>
    
  • then for each file, extract that file

    git show <SHA1>:/path/within/repo/to/file
    
  • Do that in a working tree of a dedicated branch, and for every file extracted, add and commit.

    Then you can reset your current branch by that new one built commit-file by commit-file.

    链接地址: http://www.djcxy.com/p/26660.html

    上一篇: Gerrit触发器如何构建仅适用于项目的某个部分

    下一篇: 如何分割每个提交文件?