问题
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.
回答1:
The Script
The following script splits HEAD
by file:
#!/usr/bin/env bash
set -e
SHA=$(git rev-parse --short HEAD)
git reset HEAD^
git diff-tree --no-commit-id --name-only -r $SHA | while read -r f; do
git add "$f"
GIT_EDITOR="echo '0a\n$SHA $f\n\n.\nw' | ed -s" git commit -c $SHA
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.
回答2:
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.
来源:https://stackoverflow.com/questions/40698651/how-to-split-every-commit-by-file