AlexMax
AlexMax

Reputation: 1204

Add a licenses to file headers in tree, retroactively

There is a closed-source project that is going to be open-source, and I was asked to attempt to add licenses to all source files in the SVN repository retroactively, as the tree history might be of general interest. There is also interest in migrating to a DVCS, and hgsubversion doesn't appear to track svn mergeinfo, so I decided to try converting the SVN repository to git (doing a one-way conversion that fixed tags and such) and then attempt to edit history from there.

I was actually very lucky, as the very first revision happened to have a branch that led to work done for an earlier public source release. Thus, I decided to try git rebase sourcerelease-branch master. A few very painful hours later, I was finished...

...except for one problem. There were several branches in the converted repository (including a 'branch' that was actually mainline development past 2009 or so), and it didn't look like rebase had traversed them. Asking around in #git, I was told that it was not possible to make git rebase traverse branches.

Well shoot...what can I do? Is what I'm going after even possible, with git or with some other version control system?

EDIT: Here is a visual of what I have

          A---B random_branch
         /
C---D---E---F master
 \
  G---H add_license_branch

I essentially want to get the changes I made in change-license-branch to appear in master and in any branch that branches from master such as random_branch. When I'm through, I don't even want a add_license_branch, it'd be nice if I could squish C, G and H together and put the result where C is right now.

Upvotes: 4

Views: 1753

Answers (2)

David Mason
David Mason

Reputation: 2957

I have just done something like this but a little simpler, as I only wanted to keep one branch. I wanted to insert a copyright notice at the top of every (java) code file.

I used filter-branch with a--tree-filter, which will check out each commit and run a shell command against it, then re-commit. Child commits are not rebased, so it must be run against every commit or it will look like the notice was added, then later removed.

The following finds all Java code files, and runs sed against each to insert the contents of a file at /path/to/header.txt at the start of the file.

$ git filter-branch --tree-filter "find ./ -name '*.java' -exec sed -i '1 {
    h
    r /path/to/header.txt
    g
    N
}' {} \;" HEAD

Change '*.java' to match the files you want to modify, change /path/to/header.txt to an absolute path to the header you want to insert, and it should work for the simple case.

Note: the above assumes that the header is not yet present in any code files and will double them up if they are already present. To avoid this, the sed argument could be updated with a check for the first part of the header. Someone more experienced with sed might have an idea how to do this.

Upvotes: 4

Adam Dymitruk
Adam Dymitruk

Reputation: 129584

Not seeing the exact structure of your history please investigate the following concepts:

git filter-branch
git rebase --preserve-merges
git rebase --onto
grafting
git-svn # for further work with the 2 repos

Upvotes: 0

Related Questions