How to split every commit by file?

烈酒焚心 提交于 2019-11-30 17:04:23

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!