Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a patch for a whole directory to update it?

Tags:

diff

patch

I know there are several threads on this already, but no one has fully explained exactly how to perform the initial diff to create the patch file, then how to apply that patch to the initial directory to update it.

In my case, there is a directory of files that anyone can download from the web. I have taken that directory and made changes to it, and want to create a patch file such that others can apply it to the downloaded directory to reproduce exactly what I have in my modified directory.

Help? What do I need to tell the other person with respect to how to apply my patch?

like image 491
poundifdef Avatar asked Apr 02 '12 16:04

poundifdef


People also ask

How do I create a patch between two folders?

If the project is under git and you haven't committed your changes locally, you can simply do git diff > file. patch to get patchable diff data. If you have committed the changes locally, you can do git log to find the commit before you and than git diff commit_string > file.

How do I apply a patch from the command line?

In the box displayed in the command line terminal, the first line shows the file to be patched. Copy the file path and paste it into the File to patch: prompt and press Enter and the patch should complete. For the changes to be reflected, refresh the cache in the Admin under System > Tools > Cache Management.


2 Answers

I just had this same problem - lots of advice on how to half do it. Well, here is what I did to get both the patching and unpatching to work:

To Create the Patch File:

  1. Put copies of both directories in say /tmp, so we can create the patch file, or if brave, get them side by side - in one directory.

  2. Run an appropriate diff on the two directories, old and new:

    diff -ruN orig/ new/ > file.patch # -r == recursive, so do subdirectories # -u == unified style, if your system lacks it or if recipient #       may not have it, use "-c" # -N == treat absent files as empty 

If a person has the orig/ directory, they can recreate the new one by running patch.

To Recreate the new folder from old folder and patch file:

  1. Move the patch file to a directory where the orig/ folder exists

  2. This folder will get clobbered, so keep a backup of it somewhere, or use a copy.

    patch -s -p0 < file.patch # -s == silent except errors # -p0 == needed to find the proper folder 
  3. At this point, the orig/ folder contains the new/ content, but still has its old name, so:

    mv orig/ new/    # if the folder names are different 
like image 65
David H Avatar answered Sep 25 '22 21:09

David H


I needed to create a patch file and send it to someone so they could update their directory to match mine. There are many caveats with diff and patch however, so it ended up taking me hours to figure out something so conceptually simple. Absolute paths seem to be preferred over relative paths, and many of the options seem to have evolved from niche use cases. I finally figured out a solution based on David H's answer, with additional tips from Lakshmanan Ganapathy):

  • Back up your directory to directory.orig
  • Modify your directory to reach the desired state
  • Save diff from directory.orig to directory in file.patch so name matches for recipient

Here are my notes:

# to create patch: # copy <directory> backup to something like <directory>.orig alongside it cp -r <path_to>/<directory> <path_to>/<directory>.orig # create/update/delete files/folders in <directory> until desired state is reached # change working directory to <directory> cd <path_to>/<directory> # create patch file alongside <directory> diff -Naru ../<directory>.orig . > ../file.patch # -N --new-file Treat absent files as empty. # -a --text Treat all files as text. # -r --recursive Recursively compare any subdirectories found. # -u -U NUM --unified[=NUM] Output NUM (default 3) lines of unified context.  # to apply patch: # change working directory to <directory> cd <path_to>/<directory> patch -s -p0 < <path_to>/file.patch # -s or --silent or --quiet Work silently, unless an error occurs. # -pN or --strip=N Strip smallest prefix containing num leading slashes from files.  # to undo patch (note that directories created by patch must be removed manually): # change working directory to <directory> cd <path_to>/<directory> patch -Rs -p0 < <path_to>/file.patch # -R or --reverse Assume that patch was created with the old and new files swapped. # -s or --silent or --quiet Work silently, unless an error occurs. # -pN or --strip=N Strip smallest prefix containing num leading slashes from files. 
like image 23
Zack Morris Avatar answered Sep 24 '22 21:09

Zack Morris