git: recover older version of a file as new file, keeping history

48 Views Asked by At

I have a Java class file, say JavaClass.java, that has a commit history, like this:

01/01/2020 Commit1 JavaClass.java
...        ...     ...
01/01/2024 CommitN JavaClass.java

I want to recover an older version of the file and use it as a new file (with a new different name, of course), so that I can have both old and new file in the same branch, but keeping all the commit history for both files (i.e., something like splitting the file history), like this:

JavaClass.java         // file at CommitN, as it is modified by time
JavaClass_Renamed.java // file at Commit1, with a different name

Is it possible? I am trying various combinations of git commands but without success right now. For example, a merge between the old version of the file (renamed, in a new branch) and the current branch leads clearly to merge the two versions of the file, while I want the two versions to be separated.

1

There are 1 best solutions below

0
vatbub On

This task is easy, as long as you don't want to keep the history:

  1. Make sure that you have a clean working directory by either committing uncommitted changes or by stashing them with git stash.
  2. Check out the revision which you want to get the file from with git checkout --detach 3738368fb (while obviously replacing the commit hash with the hash that you want to check out).
  3. Copy the file in question to another folder. You can also rename the file in that other location to the new file name.
  4. Go back to where you started before with git checkout main and popping the stash if you created one earlier: git stash pop
  5. Move the file from the other location back into the git repo.

Keeping the history is a whole different thing, though. You would need to change the commit history, which comes with its own caveats: If you pushed the commits some place else (like GitHub) and other people may have pulled the commits already, you need to coordinate a force-push with all those people. If you are working on a feature-branch, this will probably be ok, but if you are working on main, master or develop this will probably not be very easy as you would need to ensure that nobody else is committing or pushing anything to your branch, since their work would be overwritten by your history rewrite.

Most importantly, though, modifying the history will be very time-consuming with little to no benefit:

  1. You could start an interactive rebase and edit any commit that contains edits to that file.
  2. You might also want to have a look at this StackOverflow question which discusses how to add a file to the git history, which is more or less what you want to do.