Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I modify the file path in a set of Git patches?

Tags:

git

I'm working on a Git repo that's been pulled from an SVN repo using git svn. Many moons ago, the SVN repo was created from a source tarball of the original (upstream) project. The original project had a file structure like the following:

/
  COPYING
  README
  src/
      ...many source files...

However, when the SVN repo was created, the README files, etc., were stripped out, and the app was created with src/ as the root, so the repo now just looks like:

/
  ...many source files

I recently converted this SVN repo into a Git repo. The original project is also in a Git repo, and I'd like to start tracking upstream changes so I can easily see what custom changes have been made (and submit patches back to the original project, if applicable). I've found the commit in the upstream repo that our SVN repo was created from, so now I'd like to apply our changes to that commit (in a branch). I can easily create a set of patches using git format-patch and apply them to the cloned upstream repo...except that the file structures are different, so the patches don't point to the correct files anymore. Is there a way to apply the patches from git format-patch to the src/ directory in the cloned repo? (Note that the Git patches also have the necessary info like the original author name, email, and date, which I'd also like to apply and not have to do by hand, i.e., by messing around with GIT_AUTHOR_EMAIL, etc.)

like image 859
mipadi Avatar asked Jul 29 '10 21:07

mipadi


People also ask

How do I format a patch in git?

The first rule takes precedence in the case of a single <commit>. To apply the second rule, i.e., format everything since the beginning of history up until <commit>, use the --root option: git format-patch --root <commit> . If you want to format only <commit> itself, you can do this with git format-patch -1 <commit> .

What are patch files in git?

A patch is a text file whose contents are similar to Git diff but along with code it contains metadata about commits, for example, a patch file will include commit ID, date, commit message, etc. We can create a patch from commits and other people can apply them to their repository.

How do you make a patch for uncommitted changes?

In order to create Git patch file for a specific commit, use the “git format-patch” command with the “-1” option and the commit SHA. In order to get the commit SHA, you have to use the “git log” command and look for the corresponding commit SHA.

What is the format of a patch file?

Patchfile Format The patch file must contain zero or more lines of header information followed by one or more patches. Each patch must contain zero or more lines of filename identification in the format produced by diff -c, and one or more sets of diff output, which are customarily called hunks.


2 Answers

Seems to me that you should be able to use git filter-branch to change the paths in the previously-cloned-from-SVN repo. Then, after all the file paths have been updated, you can now just use git format-patch to create patches that will apply to the newly-cloned-from-upstream repo.

Try:

git filter-branch --tree-filter 'mkdir src; git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files src'

like image 159
Dan Moulding Avatar answered Sep 23 '22 17:09

Dan Moulding


I recently had a similar problem. My solution was to create a new target repository with a src subdirectory, then I created a set of patches in the source repository:

/data/source-repository$ git format-patch -k --root

then those patches were applied to the src directory in the target repository:

/data/target-repository$ git am -k --committer-date-is-author-date --directory src ../source-repository/*.patch

All patches from the source repository ended in src in the target repository, i.e. all paths were tweaked accordingly.

From there you could again create patches and import those into the upstream repository inside of a branch.

like image 32
hochl Avatar answered Sep 20 '22 17:09

hochl