A long time ago - and long before I joined the project - my project was migrated from clearcase to git. This migration led to the following file layout:

├── bar
│   ├── bar.c
│   └── bar.h
├── foo
│   ├── foo.c
│   └── foo.h
└── patches
    ├── bar
    │   └── bar.c
    └── foo
        └── foo.h

On the day of the clearcase to git migration, patch and patched files were mostly copies with some -mostly- minor changes that were the reflect of clearcase differences.

The build system makes the patches hide the patched files. Patched files have been kept as a testimony of the patches that had been done in the ancient clearcase time. Patched files have (normally) experienced no changes since the migration.

Developers of the team have always feel really confused that when changing bar/bar.h the implementation file that needs to be updated is patches/bar/bar.c and not bar/bar.c which is just a confusing testimony of the ancient times.

Now comes the time to apply these patches!

Now comes the time for bar/bar.c to become the real source file again and for patches/bar/bar.c to get back to the ancient times (Nonetheless bar/bar.c shall reflect the git change history of patches/bar/bar.c).

I see two options:

Option 1

Tricking the devs into believing there has never been a patch!

# This totally is a pseudo script. Sorry, friday night, not at work anymore!
for commit in $(git log -- pfile)
   git show commit:pfile > ofile
   git commit -m"%B" --date %aN --author %cI

(This might be doable by some sort of rebase I haven't worked on today, feel free to improve)


  • git log -- bar/bar.c really shows the history of the file with the application of the clearcase patch as one of the top commits.
  • If I want to run a filter to move foo and bar to their own repo, the history will be preserved (and clean)


  • This adds a lot of commit!
  • Does not easily preserves commit coherency: if commit 01234567 modified both bar/bar.h and patches/bar/bar.c, this will now appear in two different commits

Option 2

The commit saving way. It can be found eg here:

git rm bar/bar.c
git commit -m 'Remove unpatched clearcase file'
git mv patches/bar/bar.c bar/bar.c
git commit -m 'Apply clearcase and git patches'


  • Few commits added
  • If I set git config log.follow true (thanks @VonC), my fellow devs will be tricked in looking at the history but the initial clearcase patch. This shall be enough.


  • Unless I put a lot of effort this is not resilient to future (and foreseen) subdirectory filters.
  • Initial clearcase patch hidden. To see the unpatched file history, I'll need some git trickery now that --follow is the default or setting an alias get_clearcase_patch that will compute the diff.

The question

Is there a third option I haven't seen (which preserves history, I thought of some which doesn't of course ^^)? Are there any pros and cons I haven't seen? Which is the best solution?

  • What do the patch files contain? – Greg Burghardt Jan 31 '20 at 21:26
  • Why do they need to be updated? I'm starting to think this is not a "git" question at all. Something about the team or build process is broken here. – Greg Burghardt Jan 31 '20 at 21:28
  • The clearcase to git was IMHO not well performed. This led to have together patch files and their patched files they applied to. I fear to have led to a confusion by talking of patch file: these are clearly no git patch file. Just a copy of the file. As far as I understand the former clearcase workflow (which I clearly do not), they had an original file and patches (copy of the file with minor differences) and they would regularly apply the patches to the files. Patch files ware only copy of the original files with minor differences that are now used as reference files. – Vser Jan 31 '20 at 21:41
  • How do the patches "get applied?" Is it part of the build process? – Greg Burghardt Feb 10 '20 at 15:08
  • @GregBurghardt They don't get applied anymore, they simply hide/replace the original files. Back then, on clearcase (which AFAICT is file-centric), they were from time to time applied back to the files (which were shared by different projects). They were a conceptual equivalent of git branches. – Vser Feb 12 '20 at 14:15

Honestly the effort to do this just isn't worth it. Leave the patch files. If it had been long enough and those patches are no longer relevant because the original files have been removed or changed, then remove the patch files. Then again if the patch files don't take up much space, don't do anything to the files. Just leave them as is.

The only possible way to remove them and preserve history is to rewrite history — all of it. Basically create a branch from the last commit representing the migration from Clearcase and make new commits for each patch file. Then you are stuck with a monster rebase that orphans everyone else's work in every branch ever... so basically don't do this.

Just live with it. The cleanup will be more traumatic to the team and history than just keeping it.

  • I clearly don't want to do the monster rebase :) I might have expressed my needs not correctly though. New team members clearly do not understand why when changing bar/bar.h they need to update patches/bar/bar.c and not bar/bar.c. So there clearly is a need to clean this. – Vser Jan 31 '20 at 20:58
  • I figured you didn't. :) – Greg Burghardt Jan 31 '20 at 21:00
  • Sorry, updated my comment, was too easy on the <enter> switch :) – Vser Jan 31 '20 at 21:01
  • I figured the trouble might be in the use of patch and patched files which can lead to confusion. If you think of a better way to express this, I'll update my question. – Vser Jan 31 '20 at 21:02
  • @Vser Sorry, but I don’t get the apparent contradiction that on one side /bar/bar.c is the file to keep up-to-date now and that patched version is for historical reasons only, and that on the other side, new developers have still to update the patched version instead of the current one? Surely I missed something, but Greg’s proposal to keep history as is is and now work only on the current version (looking for the patched version only for archeological reasons) seems quite straightforward and easy to grasp fir newcomers, isn’t it? – Christophe Feb 1 '20 at 10:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.