The previous escaping method of wrapping the arguments with double
quotes would eventually fail in some cases, since Linux allows pretty
much any character for a filename.
Using a different quoting character, like the single quote would have
brought you back to the exact same issue. As soon as any part of the
path contained your escape quote character, the code would break.
The code would use `shlex`, a parser for Linux shells. However, this
wasn't working since even that wouldn't know where your argument began
and ended, since it wasn't escaped properly. Meaning, a string like:
`diff -r /home/test/.config/Code - OSS/t"t't.test mytestfile.test`
Would then break any of the quoting solutions. And shlex, since it
wouldn't know where arguments start and end, it would think an
argument ends at `home/test/.config/Code`, since the spaces haven't
been escaped. But escaping the spaces with quote characters is not a
good idea since any parts of the path with those quote arguments would
then again break shlex and it wouldn't be able to tell when your
argument starts and ends.
The solution for that is to, before we replace our diff template
string with the given files arguments, we can just split it by
whitespace, and manually replace the `{0}` and `{1}` placeholders.
This allows us to keep the separation with a Python list. What does
this mean? That when you then call `subprocess.Popen` with this list,
`subprocess` knows where all your arguments start and end, even if
they themselves are not properly escaped. But since it's all split in
a list, `subprocess` has a concept of what is a single argument and
would apply the needed escaping to each individual argument.
The current diffs are confusing, since they compare the source against
the destination file. To make it less confusing: source is the file
that contains modifications, and destination is the one to be
overwritten.
With the current order, it displays changes as if you were applying
the destination file on the source file.
This commit makes it so that it displays the changes it would need to
apply source on destination. This is consistent with tools such as
patch, that take first the destination file, and second the patch
you're going to apply. Diffing should be done the same way, first the
destination, second the file with the new changes. This is how other
tools that provide diffs such as git also work.