How to split every commit by file?

2019-01-19 05:41发布

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.

2条回答
爷、活的狠高调
2楼-- · 2019-01-19 06:14

For every commit, you would need

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.

查看更多
\"骚年 ilove
3楼-- · 2019-01-19 06:31

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.

查看更多
登录 后发表回答