Julien__
Julien__

Reputation: 2038

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.

Upvotes: 6

Views: 1974

Answers (2)

raphinesse
raphinesse

Reputation: 20968

The Script

The following script splits HEAD by file:

#!/usr/bin/env bash
set -e

SHA=$(git rev-parse --short HEAD)

# Change to repo root directory
cd $(git rev-parse --show-toplevel)

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.

Upvotes: 11

VonC
VonC

Reputation: 1323943

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.

Upvotes: 3

Related Questions