diff and patch using wrong line ending when creating new files or line end changed - diff

I'm trying to create a patch using diff, but I can't get the patch to use the line end characters used in the files when creating a new file or to change the line ending when the file changes it. Basically, I'm doing:
cp -r dir1 dir3
diff -ruN dir1 dir2 > dir3\patch.txt
cd dir3
patch -p1 < patch.txt
All the changes between dir1 and dir2 properly apply, except the end of line character for new files is defaulting to CR+LF, even where the file in dir2 uses LF as an end of line marker. Also, any files where the difference between them is just a line end change are not patched in any way -- diff doesn't seem to see any change.
So running diff -rq dir2 dir3 gives a bunch of Files aaa and bbb differ, but diff -rwq dir2 dir3 works fine.
I'm using diff - GNU diffutils version 2.7 and patch 2.5 from UnxUtils on Windows XP.
Is there any way to make new and changed files included in the patch keep the line ending from the original file?

This works:
cp -r dir1 dir3
diff --binary -ruN dir1 dir2 > dir3\patch.txt
cd dir3
patch --no-backup-if-mismatch --binary -u -p1 < patch.txt
Not using the --binary flag means that the file is parsed line by line, ignoring EOL. For some reason, it won't always patch cleanly (gives a Hunk #1 succeeded at 1 with fuzz 1. message) so I had to include --no-backup-if-mismatch to prevent it making .orig files. The -u seems to be optional, since patch will figure the patch type out on it's own.

Related

How do I "inverse" a diff file?

Say I have a diff file looking basically like the following.
+line a
-line b
Is it possible to do one (or both) of the following:
Inverse this file (so I'd get)
-line a
+line b
Pass some argument to patch so the end result the same as applying
the inversed diff file described above
You can leave the diff as is and apply in reverse
git apply --reverse backwards-diff
Here is what you should do (assuming newFile.txt is the file you want to apply the reversed diff file on and diffFile.txt is the diff file):
patch -R newFile.txt diffFile.txt -o oldFile.txt
To rewrite a reversed / inverted diff file, use interdiff from diffutils:
interdiff -q my-diff-file /dev/null

Is there a command to diff all the kept files in accurev?

I am new to accurev, used to use SVN earlier. I want to a get diff file consisting of all the changes in kept files in a given directory. I know ac diff -b <file>
gives diff in a file, but if I have many files and I want the diff of all the kept files in a given directory, is there a straight forward command to do this like svn diff?
You are going to need to create a script if you only want to diff kept files in a given directory. Basically you will run an 'accurev stat -k' -> parse output for given directory -> 'accurev diff -b'
On a *NIX machine the commands below work nicely.
The -k option to AccuRev's stat command says find the file with "(kept)" status. Using the -fal options to stat provides just the Depot relative pathway to the file. No addition filtering needed. So the command line would be:
accurev stat -k -fal | xargs accurev diff -b
Produces output like:
accurev stat -k -fal | xargs accurev diff -b
diffing element /./COPYING
341a342
> Tue Mar 18 08:38:39 EDT 2014
> Change for demo purposes.
diffing element /./INSTALL
3a4,7
> New Change
>
> Another Change
>
Dave

comparing two directories with separate diff output per file

I'd need to see what has been changed between two directories which contain different version of a software sourcecode. While I have found a way to get a unique .diff file, how can I obtain a different file for each changed file in the two directories? I'd need this, as the "main" is about 6 MB and wanted some more handy thing.
I came around this problem too, so I ended up with some lines of a shell script. It takes three arguments: Source and destination directory (as used for diff) and a target folder (should exist) for the output.
It's a bit hacky, but maybe it would be useful for someone. So use with care, especially if your paths have special characters.
#!/bin/sh
DIFFARGS="-wb"
LANG=C
TARGET=$3
SRC=`echo $1 | sed -e 's/\//\\\\\\//g'`
DST=`echo $2 | sed -e 's/\//\\\\\\//g'`
if [ ! -d "$TARGET" ]; then
echo "'$TARGET' is not a directory." >&2
exit 1
fi
diff -rqN $DIFFARGS "$1" "$2" | sed "s/Files $SRC\/\(.*\?\) and $DST\/\(.*\?\) differ/\1/" | \
while read file
do
if [ ! -d "$TARGET/`dirname \"$file\"`" ]; then
mkdir -p "$TARGET/`dirname \"$file\"`"
fi
diff $DIFFARGS -N "$1/$file" "$2/$file" > "$TARGET"/"$file.diff"
done
if you want to compare source code it is better to commit it to a source vesioning program as "svn".
after you have done so. do a diff of your uploaded code and pipe it to file.diff
svn diff --old svn:url1 --new svn:url2 > file.diff
A bash for loop will work for you. The following will diff two directories with C source code and produce a separate diff for each file.
for FILE in $(find <FIRST_DIR> -name '*.[ch]'); do DIFF=<DIFF_DIR>/$(echo $FILE | grep -o '[-_a-zA-Z0-9.]*$').diff; diff -u $FILE <SECOND_DIR>/$FILE > $DIFF; done
Use the correct patch level for the lines starting with +++

SED Delete lines and replace with new from file

Have been looking at SED documention but need a little pointer in the right direction
I have 200 files I want to modify in a batch.
Source is html file.
Need to create a new file for the changes.
Want to delete the first part of each file up to the first tag (This is 20 or so lines but can vary slightly).
Then insert the contents of a source file (the same for all files) into the new target file starting at line 1, for 30 or so lines. The number of lines to insert does not match the number that are deleted though.
Hope you can help.
Paul
This can certainly be done with sed(1), but I would probably use the vanilla editor ed(1).
$ cat > bigfix.sh
for i in "$#"; do
ed "$i" << \eof
1,/<tag>/-1d
0r otherfile.html
w
q
eof
done
$ sh bigfix.sh file*.html
This shell script takes arguments and runs ed(1) on each arg. It deletes lines starting from the first and ending on the line right before the one with <tag>. It then puts otherfile.html at the top and writes out the result.
For an individual file:
sed -e '1,/tag/{/tag/r insertfile' -e ';d}' inputfile > outputfile
For many files:
find . -name 'criterion*.ext' -type f -exec sh -c 'sed -e "1,/tag/{/tag/r insertfile" -e ';d}" "{}" > "{}.new"' \;
Edit:
Fixed the find command to use sh because of the redirection. Note the change in quoting from the previous version.

How do you get a list of files included in a diff?

I have a patch file containing the output from git diff. I want to get a summary of all the files that, according to the patch file, have been added or modified. What command can I use to achieve this?
patchutils includes a lsdiff utility.
grep '+++' mydiff.patch seems to do the trick.
I can also use git diff --names-only which is probably the better approach.
grep '+++' mydiff.patch|perl -pe 's/\+\+\+ //g'
Details:
git diff produces output in the format
+++ b/file
So if you're using grep as Nathan suggested
grep '+++' mydiff.patch
You'll have the list of affected files, prepended by '+++ ' (3 plus signs and a space).
I often need to further process files and find it convenient to have one filename per line without anything else. This can be achieved with the following command, where perl/regex removes these plus signs and the space.
grep '+++' mydiff.patch|perl -pe 's/\+\+\+ //g'
For patch files generated with diff -Naur, the mydiff.patch file contains entries with filename and date ( is indicating the tabulator whitespace character)
+++ b/file<tab>2013-07-03 13:58:45.000000000 +0200
To extract the filenames for this, use
grep '+++' mydiff.patch|perl -pe 's/\+\+\+ (.*)\t.*/\1/g'
A decent way to do this is to use the --stat flag (or the --summary flag, if you need only new / deleted / renamed files for some reason).
Example:
git apply --stat peer.diff | awk '{ print $1 }' | sed '$d'
1-js/03-code-quality/index.md
CONTR.md
LICENSE.md
README.md
chat-app.readme.md
When you parse patches generated by git format-patch or others containing additional information about number of lines edited, it's crucial to search for ^+++ (at the start of the line) rather than just +++.
For example:
grep '^+++' *.patch | sed -e 's#+++ [ab]/##'
will output paths without a/ or b/ at the begin.