This repository tries to explain and show at the same time how you can move and/or split a file under GIT and still keep all the history.
These actions are very common in projects where following certain guidelines requires to move things arround but at the same time keep all the history.
Examples are presented using Visual Studio 2015 IDE and Git CLI
These steps are advised to be taken when you do not have to change anything in a file, just move it, but as you would see in the second part, Edit and move a file the outcome is identical.
Moving a file is quite easy and there are two methods to accomplish it:
Pre drag-and-drop
Post drag-and-drop
Staged changes
History after check in
git mv source_file destination_file
A good example would be the following command that moves the file from Helpers to Filters folder as we did with drag-and-drop:
git mv Git.History.Web*Helpers\MovableSecurityHelperV5.cs* Git.History.Web*Filters\MovableSecurityHelperV5.cs*
Running the following command will inform you of the movement changes
git status
From this point, we can just commit and check the history of the moved file as described above
All the steps described above apply here as well. The only addition to this part is the fact that editing the moved file will have the same result.
If you only have to move and edit a file, perform the steps described above and also the additional edits you require.
Preserving the history of a file while moving/editing it is pretty easy as we already saw.
Splitting a file into two while preserving the history on the both ends it's a whole different adventure which I'll describe bellow.
Let's take the scenario in which a class contains two methods like the one below
public class MyFirstClass
{
public void Method1()
{
...
}
public void Method2()
{
...
}
}
And we want to move method Method1 into a different class, let's say MySecondClass, but preserve the history that it accumulated in MyFirstClass for all kinds of reasons
The outcome for which we want aim is the following
public class MyFirstClass
{
public void Method1()
{
...
}
}
public class MySecondClass
{
public void Method2()
{
...
}
}
Usually, people tend to simply create a new destination file and copy over the implementation they need from the source file. This will make Git to track changes of this new destination file from the time it was created which is the time of the movement of the implementation.
This will result in the loss of all history for those bits of code which were moved from source to destination
- The trick into preserving the history on both files is to create a new branch
- We will have to move/edit the file in the newly created branch then merge it with the current one
- This will create a conflict, but we will keep the new file from the new branch
Create 'split-helper-v5' branch
Rename and Move file on 'master' branch
Switch to 'split-helper-v5' branch
Rename and Move file on 'split-helper-v5' branch
Switch to 'master' branch
Open command prompt on 'master' branch
Run the merge command - be aware that mergeing directly from Visual Studio 2015 does not give the same results
git merge --no-ff split-helper-v5
Merge conflicts
Merge conflicts detailed
Keep file from 'master' branch - this will ensure history for the file on the 'master' branch
Keep file from 'split-helper-v5' branch - this will ensure history for the file on the 'split-helper-v5' branch and thus accomplish the split
Leave deleted file from both branches - we do not need the file from the place it was moved in neither of the two branches
Commit merge changes - don't bother the [add] status of the file
'master' branch file history
'split-helper-v5' branch file history
Completing these steps will make you end up with two files which have the same history
You will still have to move them in their right place, if you haven't in the above steps. For that, follow the instruction presented in Move a file