seaders
seaders

Reputation: 4106

Separate a git commit which has file renaming and editing into two commits

I'm going through a bit of refactoring, and for ease of looking through the history, I want to have clearly defined "Rename x folder to y" commits separate to commits with file edits in.

At the moment, I can't figure out how to separate these into two thing with git staging.

I absolutely know that I can move files - commit, edit files - commit, move - commit, edit - commit, but with some IDEs, you're absolutely better off using their move functions that include all other refactoring steps involved, but without being able to then separate that in the git commit steps, I find it a bit of a messy process.

My preference would be a catchall command, like git add -A :/, but in that, to specify only the move / rename part of the git file change steps.

Upvotes: 4

Views: 560

Answers (1)

Adi Levin
Adi Levin

Reputation: 5243

This will take some scripting, but it can be done: First, commit all of the changes that involve both renaming and editing, to a temporary branch (TMP1 in the diagram below).

Then, run

git show -M --name-status

This will show you the files that have been renamed, with their similarity index, marked by R<N>, as in this example:

$ git show -M --name-status
commit 07d207f4ca1754c6b12bddb4918f42f02f37ccc3
Author: Adi Levin <[email protected]>
Date:   Wed Mar 2 16:39:19 2016 +0200

    ttt

R100    assetsdb/assetsdb.iml   assetsdb2/assetsdb.iml
A       assetsdb2/mvnw
A       assetsdb2/mvnw.cmd
R100    assetsdb/pom.xml        assetsdb2/pom.xml
R100    assetsdb/src/main/java/com/aligntech/assetsdb/Asset.java        assetsdb2/src/main/java/com/aligntech/assetsdb/Asset.java
R100    assetsdb/src/main/java/com/aligntech/assetsdb/AssetsDBDemoApp.java      assetsdb2/src/main/java/com/aligntech/assetsdb/AssetsDBDemoApp.java
R100    assetsdb/src/main/java/com/aligntech/assetsdb/DynamodbAssetsApplication.java    assetsdb2/src/main/java/com/aligntech/assetsdb/DynamodbAssetsApplication.java
R100    assetsdb/src/main/java/com/aligntech/assetsdb/RandomString.java assetsdb2/src/main/java/com/aligntech/assetsdb/RandomString.java
R100    assetsdb/src/main/resources/application.properties      assetsdb2/src/main/resources/application.properties
A       assetsdb2/target/application.properties
A       assetsdb2/target/classes/application.properties
A       assetsdb2/target/classes/com/aligntech/assetsdb/Asset.class
A       assetsdb2/target/classes/com/aligntech/assetsdb/AssetsDBDemoApp.class

Notice that the default similarity index is 50%. If you want to control it, use -M90% or -M100% for identical files only.

Next, you need to parse this output and extract the list of renamed files, then go back to the base commit, and create a new commit ('Renamed' in the diagram below) where those files are only renamed - without any other changes.

Finally, you need to take the working directory of Tmp1 and make another commit from it, on top of Renamed, where files are both renamed and edited.

enter image description here

Upvotes: 4

Related Questions