Previous: dopatch, Up: Introducing Changesets


A.2.3 Inexact Patching – How Conflicts are Handled

What if a tree patched by dopatch is not exactly the same as the original tree seen by mkpatch?

Below is a brief description of what to expect. Complete documentation of the dopatch process is included with the source code.

dopatch takes an inventory of the tree being patched. It uses inventory ids to decide which files and directories expected by the changeset are present or missing from the tree, and to figure out where each file and directory is located in the tree.

Simple Patches If the changeset contains an ordinary patch or metadata patch for a link, directory or file, and that file is present in the tree, dopatch applies the patch in the ordinary way. If the patch applies cleanly, the modified file, link, or directory is left in place.

If a simple patch fails to apply cleanly, dopatch will always leave behind a .orig file (the file originally in the tree being patched, without any changes) and a .rej file (the part of the patch that could not be applied).

If the patch was a context diff, dopatch will also leave behind the file itself – partially patched.

If an (unsuccessful) patch was for a binary file, no partially-patched file will be left. Instead, there will be:

             .orig   -- the file originally in the tree being patched,
                        without modifications.

             .rej    -- a complete copy of the file from the modified tree,
                        with permissions copied from `.orig'.

             .patch-orig -- a complete copy of the file from the original
                            tree seen by `mkpatch', with permissions
                            retained from that original

                             -or-

                            the symbolic link from the original tree seen
                            by `mkpatch' with permissions as in the original
                            tree.

If an (unsuccessful) patch was for a symbolic link, no partially patched file will be left. Instead there will be:

             .orig   -- the unmodified file from the original tree

             .rej    -- a symbolic link with the target intended by the
                        patch and permissions copied from .orig

             .patch-orig -- a complete copy of the file from the original
                            tree seen by `mkpatch', with permissions
                            retained from that original

                             -or-

                            the symbolic link from the original tree seen
                            by `mkpatch' with permissions as in the original
                            tree.

Patches for Missing Files

All patches for missing files and directories are stored in a subdirectory of the root of the tree being patched called

             ==missing-file-patches-PATCH-DATE

where PATCH is the basename of the changeset directory and DATE a time-stamp.

Directory Rearrangements and New Directories

Directories are added, deleted, and rearranged much as you would expect, even if you don't know it's what you'd expect.

Suppose that when mkpatch was called the ORIGINAL tree had:

             Directory or file:              Id:

             a/x.c                           id_1
             a/bar.c                         id_2

but the MODIFIED tree had:

             a/x.c                           id_1
             a/y.c                           id_2

with changes to both files. The patch will want to rename the file with id id_2 to y.c, and change the contents of the files with ids id_1 and id_2.

Suppose, for example, that you have a tree with:

             a/foo.c                         id_1
             a/zip.c                         id_2

and the you apply the patch to that tree. After the patch, you'll be left with:

             a/foo.c                         id_1
             a/y.c (was zip.c)               id_2

with patches made to the contents of both files.

Here's a sample of some subtleties and ways of handling conflicts:

Suppose that the original tree seen by mkpatch has:

             Directory or file:              Id:

             ./a                             id_a
             ./a/b                           id_b
             ./a/b/c                         id_c

and that the modified directory has:

             ./a                             id_a
             ./a/c                           id_c
             ./a/c/b                         id_b

Finally, suppose that the tree has:

             ./x                             id_a
             ./x/b                           id_b
             ./x/c                           id_new_directory
             ./x/c/b                         id_different_file_named_b
             ./x/c/q                         id_c

When patch gets done with the tree, it will have:

             ./x                             id_a
                     Since the patch doesn't do anything
                     to change the directory with id_a.

             ./x/c.orig                      id_new_directory
             ./x/c.rej                       id_c
                     Since the patch wants to make the
                     directory with id_c a subdirectory named "c"
                     of the directory with id_a, but the tree
                     already had a different directory there,
                     with the id id_new_directory.

             ./x/c.rej/b                     id_b
                     Since the patch wants to rename the directory
                     with id_b to be a subdirectory named "b"
                     of the directory with id_c.

             ./x/c.orig/b                    id_different_file_named_b
                     Since the patch made new changes to this file,
                     it stayed with its parent directory.