From 278a84ca84a9286190916cd6162dbe8e6a80030d Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Wed, 25 Sep 2013 17:14:31 +0200
Subject: [PATCH] Added --save-originals to patch

I added a new mode to store patches. If one saves them with
--save-originals (instead of -s) what happens is that
/patches/codename.diff
will be a directory. Instead of storing diff files there,
we will store original/modified pairs.

When patching, if a directory is found in
/patches/codename.diff
the diff are computed and then reapplied on the actual files.

The only change is that the diff is not stored but re-computed on-the-fly.
This has a completely equivalent effect of the original way.
E.g., one can patch two slightly different versions
of an MD code with the same patch.

However, it has the advantage that stored files are more friendly.
E.g., one could directly edit them. Also the git-merge of two
different patches should work better now.
---
 patches/patch.sh | 67 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 60 insertions(+), 7 deletions(-)

diff --git a/patches/patch.sh b/patches/patch.sh
index 082026b24..fc77435c8 100755
--- a/patches/patch.sh
+++ b/patches/patch.sh
@@ -13,6 +13,8 @@ Actions (choose one):
                     print a list of available MD engines
   -s, --save
                     save, this needs *.preplumed files (*)
+  --save-originals
+                    same as save, but save also original files
   -n NEWENGINE, --new NEWENGINE
                     create a new patch named NEWENGINE (*)
 Options:
@@ -45,6 +47,10 @@ newpatch=
 
 multiple_actions=
 
+otherfiles=
+save_originals=
+
+
 for option
 do
 
@@ -55,6 +61,7 @@ do
     (--help|-h)         echo "$MANUAL" ; exit ;;
     (--patch|-p)        test -n "$action" && multiple_actions=yes ; action=patch ;;
     (--save|-s)         test -n "$action" && multiple_actions=yes ; action=save ;;
+    (--save-originals)  test -n "$action" && multiple_actions=yes ; action=save ; save_originals=yes ;;
     (--revert|-R|-r)    test -n "$action" && multiple_actions=yes ; action=revert ;;
     (--list-engines|-l) test -n "$action" && multiple_actions=yes ; action=list ;;
     (--new=*)           test -n "$action" && multiple_actions=yes ; action=new ; newpatch="${prefix_option#--new=}" ;;
@@ -187,7 +194,7 @@ esac
 
 case "$action" in
   (patch)
-    if [ ! -f "$diff" ] ; then
+    if [ ! -e "$diff" ] ; then
       echo "ERROR: MD engine not supported (or mispelled)"
       exit
     fi
@@ -220,7 +227,24 @@ case "$action" in
     ln -s "$PLUMED_ROOT/src/wrapper/Plumed.h"
     ln -s "$PLUMED_ROOT/src/lib/Plumed.inc.$mode" Plumed.inc
     ln -s "$PLUMED_ROOT/src/lib/Plumed.cmake.$mode" Plumed.cmake
-    bash "$diff"
+
+    if [ -d "$diff" ]; then
+      echo "Patching with on-the-fly diff from stored originals"
+      PREPLUMED=$(cd $diff ; find . -name "*.preplumed" | sort)
+      for bckfile in $PREPLUMED ; do
+        file="${bckfile%.preplumed}"
+        if test -e "$file" ; then
+          diff -U 5 "$diff/$bckfile" "$diff/$file" --label="$bckfile" --label="$file" |
+          patch -u -l -b -F 5 --suffix=.preplumed "$file"
+        else
+          echo "ERROR: File $file is missing"
+        fi
+      done
+    else
+      echo "Patching with stored diff"
+      bash "$diff"
+    fi
+    
     if type -t plumed_after_patch 1>/dev/null ; then
       echo "Executing plumed_after_patch function"
       plumed_after_patch
@@ -250,13 +274,42 @@ case "$action" in
     echo "Saving your changes to $diff"
     echo "Preplumed files:"
     echo "$PREPLUMED"
-    test -e "$diff" && rm "$diff"
+    if [ -d "$diff" ] && [ -z "$save_originals" ]; then
+      echo "This patch uses the dir format (originals are saved)"
+      echo "Are you sure you want to save the single diff?"
+      echo "Possible reasons to do it are:"
+      echo "* because of licence you do not want to store originals in plumed"
+      echo "* you do not want to do a big change on the diff files now"
+      answer=
+      PS3="Choose:"
+      select answer in single-diff originals ; do
+        if [[ -n "$answer" ]] ; then
+          break
+        else
+          echo "ERROR: choose in the list above or interrupt (^c)"
+        fi
+      done
+      if [ "$answer" = originals ] ; then
+        echo "saving originals"
+        save_originals=yes
+      else
+        echo "saving single diff file"
+      fi
+    fi
+    test -e "$diff" && rm -r "$diff"
     for bckfile in $PREPLUMED ; do
       file="${bckfile%.preplumed}"
       if test -e "$file" ; then
-        echo "patch -u -l -b -F 5 --suffix=.preplumed \"${file}\" << \\EOF_EOF" >> "$diff"
-        diff -U 5 "${bckfile}" "$file" --label="$bckfile" --label="$file" >> "$diff"
-        echo "EOF_EOF"                                                   >> "$diff"
+        if [ -n "$save_originals" ] ; then
+          xx="$diff/$file"
+          mkdir -p "${xx%/*}"
+          cp "$file" "$diff/$file"
+          cp "$bckfile" "$diff/$bckfile"
+        else
+          echo "patch -u -l -b -F 5 --suffix=.preplumed \"${file}\" << \\EOF_EOF" >> "$diff"
+          diff -U 5 "${bckfile}" "$file" --label="$bckfile" --label="$file" >> "$diff"
+          echo "EOF_EOF"                                                   >> "$diff"
+        fi
       else
         echo "ERROR: File $file is missing"
       fi
@@ -270,7 +323,7 @@ cat <<EOF
 EOF
   ;;
   (revert)
-    if [ ! -f "$diff" ] ; then
+    if [ ! -e "$diff" ] ; then
       echo "ERROR: MD engine not supported (or mispelled)"
       exit
     fi
-- 
GitLab