Code Monkey home page Code Monkey logo

ydiff's Introduction

Ydiff

Tests status

Term based tool to view colored, incremental diff in a version controlled workspace (supports Git, Mercurial, Perforce and Svn so far) or from stdin, with side by side (similar to diff -y) and auto pager support. Requires python (>= 2.6.0) and less.

default

side by side

Ydiff only supports diff in Unified Format. This is default in most version control system except Perforce, which needs an environment variable P4DIFF="diff -u" to output unified diff.

Installation

Ydiff only depends on Python built-in libraries, so you can just download the source and run without worrying about any installation.

Git tagged releases will be packaged and uploaded to PyPI timely, however, packages hosted elsewhere are not (please note they are not managed by the author @ymattw).

Download directly

Just save ydiff.py to whatever directory which is in your $PATH, for example, $HOME/bin is in my $PATH, so I save the script there and name as ydiff.

curl -L https://raw.github.com/ymattw/ydiff/master/ydiff.py > ~/bin/ydiff
chmod +x ~/bin/ydiff

Install with pip

Ydiff is already listed on PyPI, you can install with pip if you have the tool.

pip install --upgrade ydiff

Install with setup.py

You can also run the setup.py from the source if you don't have pip.

git clone https://github.com/ymattw/ydiff.git
cd ydiff
./setup.py install

Install with Homebrew

You can also install with Homebrew on Mac. (Thanks to @josa42, @bfontaine, @hivehand and @nijikon for contributing to the Homebrew Formula).

brew install ydiff

Install on Fedora

On Fedora, you can install ydiff with dnf.

dnf install ydiff

Install on FreeBSD

On FreeBSD, you can install ydiff with pkg.

pkg install ydiff

Usage

Type ydiff -h to show usage:

$ ydiff -h
Usage: ydiff [options] [file|dir ...]

View colored, incremental diff in a workspace or from stdin, with side by side
and auto pager support

Options:
  --version            show program's version number and exit
  -h, --help           show this help message and exit
  -s, --side-by-side   enable side-by-side mode
  -w N, --width=N      set text width for side-by-side mode, 0 for auto
                       detection, default is 80
  -l, --log            show log with changes from revision control
  -c M, --color=M      colorize mode 'auto' (default), 'always', or 'never'
  -t N, --tab-width=N  convert tab characters to this many spaces (default: 8)
  --wrap               wrap long lines in side-by-side view
  -p M, --pager=M      pager application, suggested values are 'less' or 'cat'
  -o M, --pager-options=M
                       options to supply to pager application

  Note:
    Option parser will stop on first unknown option and pass them down to
    underneath revision control. Environment variable YDIFF_OPTIONS may be
    used to specify default options that will be placed at the beginning
    of the argument list.

Read diff from local modification in a Git/Mercurial/Perforce/Svn workspace (output from e.g. git diff, svn diff):

cd proj-workspace
ydiff                         # view colored incremental diff
ydiff -s                      # view side by side, use default text width 80
ydiff -s -w 90                # use text width 90 other than default 80
ydiff -s -w 0                 # auto set text width based on terminal size
ydiff -s -w 0 --wrap          # same as before, but also wrap long lines
ydiff -s file1 dir2           # view modification of given files/dirs only
ydiff -s -w90 --wrap -- -U10  # pass '-U10' to underneath revision diff tool
ydiff -s -w90 --wrap -U10     # '--' is optional as it's unknown to ydiff
ydiff -s --cached             # show git staged diff (git diff --cached)
ydiff -s -r1234               # show svn diff to revision 1234

Read log with changes in a Git/Mercurial/Svn workspace (output from e.g. git log -p, svn log --diff), note --diff option is new in svn 1.7.0:

cd proj-workspace
ydiff -l                    # read log along with changes
ydiff -ls                   # equivalent to ydiff -l -s, view side by side
ydiff -ls -w90 --wrap       # set text width 90 and enable wrapping as well
ydiff -ls file1 dir2        # see log with changes of given files/dirs only

Utilize a specific pager application:

ydiff                           # default pager - less
LESS_OPTS='-FRSX --shift 1'
ydiff -p less -o "${LESS_OPTS}" # emulate default pager
ydiff -p /usr/bin/less          # custom pager
ydiff -p cat                    # non-paging ANSI processor for colorizing

Pipe in a diff:

git log -p -2 | ydiff       # view git log with changes of last 2 commits
git show 15bfa | ydiff -s   # view a given git commit, side by side
svn diff -r1234 | ydiff -s  # view svn diff comparing to given revision
diff -u file1 file2 | ydiff # view diff between two files (note the '-u')
diff -ur dir1 dir2 | ydiff  # view diff between two dirs

# View diff in a GitHub pull request, side by side
curl https://github.com/ymattw/ydiff/pull/11.diff | ydiff -s

# View a patch file in unified format.
ydiff -s < foo.patch

Redirect output to another patch file is safe:

svn diff -r PREV | ydiff -s > my.patch

Environment variable

Environment variable YDIFF_OPTIONS may be used to specify default options that will be placed at the beginning of the argument list, for example:

export YDIFF_OPTIONS='-s -w0 --wrap'
ydiff foo                   # equivalent to "ydiff -s -w0 --wrap foo"

Note the default pager less takes options from the environment variable LESS.

Notes

If you feel more comfortable with a command such as git ydiff to trigger the ydiff command, you may symlink the executable to one named git-ydiff as follows:

ydiff_dir=$(dirname $(which ydiff))
ln -s "${ydiff_dir}/ydiff" "${ydiff_dir}/git-ydiff"

Known issues

Ydiff has following known issues:

  • Side by side mode has alignment problem for wide chars
  • Terminal might be in a mess on exception (type reset can fix it)

Pull requests are very welcome, please make sure your changes can pass unit tests and regression tests by run make docker-test.

ydiff's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ydiff's Issues

specify number of context lines

maybe it is somehow supported, I just don't see how.
I would like to specify the number of lines displayed before and after each difference in side-by-side mode. It seems the default is three lines.

Problem when using side by side for diff of diff

Hi,

I'm a FreeBSD port committer, and in that capacity, I patch software a lot to coerce it to work on FreeBSD, or with newer version of software that upstream does not support yet, and in that capacity, we deal with a lot of patches, that change over time, and there's a bug in the side by side thingie.

To get the diff I'm talking about, you can run svn diff -c 384636 https://svn0.eu.freebsd.org/ports /head/devel/p5-Data-Alias/files/patch-Alias.xs

The unified version of cdiff looks quite all right:

capture d ecran 2015-04-24 a 15 08 21

But the side by side eats all the + at the beginning of the lines, and does not look that good:

capture d ecran 2015-04-24 a 15 08 38

problem with tabs on start of lines

$ printf "\tbar\n" > a
$ printf "\tbam\n" > b
$ diff -u a b
--- a   2016-03-24 13:37:11.867648342 +0100
+++ b   2016-03-24 13:37:07.492648951 +0100
@@ -1 +1 @@
-       bar
+       bam

with --color=never, the output is ok

$ diff -u a b|cdiff --color=never
--- a   2016-03-24 13:37:11.867648342 +0100
+++ b   2016-03-24 13:37:07.492648951 +0100
@@ -1 +1 @@
-       bar
+       bam

but with --color=auto, it does

capture d ecran 2016-03-24 a 13 39 53

assertion violated on a diff produced by GNU diff

Hello,

I just tried diffing two files (which happened to be completely different) and piping the result into cdiff (current master), and it tripped an assertion. Steps to reproduce (on Ubuntu 14.04 LTS) attached, with some output elided with [...] for brevity:

% diff --version
diff (GNU diffutils) 3.3
[...]
% wget https://raw.githubusercontent.com/moteus/lua-path/master/lua/path.lua
% wget https://raw.githubusercontent.com/stevedonovan/Penlight/master/lua/pl/path.lua
% diff -ru path.lua path.lua.1 | cdiff
--- path.lua    2014-09-09 13:26:44.921422660 +0100
+++ path.lua.1  2014-09-09 13:27:22.745423613 +0100
@@ -1,533 +1,413 @@
-local pacakge = require "package"
-local string  = require "string"
[...]
-PATH.DIR_SEP    = DIR_SEP
-PATH.IS_WINDOWS = IS_WINDOWS
-

---
Traceback (most recent call last):
  File "/home/cpressey/toolshelf/.bin/cdiff", line 7, in <module>
    sys.exit(cdiff.main())
  File "/home/cpressey/toolshelf/github.com/ymattw/cdiff/cdiff.py", line 770, in main
    markup_to_pager(stream, opts)
  File "/home/cpressey/toolshelf/github.com/ymattw/cdiff/cdiff.py", line 631, in markup_to_pager
    for line in color_diff:
  File "/home/cpressey/toolshelf/github.com/ymattw/cdiff/cdiff.py", line 396, in markup
    for diff in diffs:
  File "/home/cpressey/toolshelf/github.com/ymattw/cdiff/cdiff.py", line 374, in get_diff_generator
    assert diff._new_path is not None
AssertionError

Add linter output to diffs

Hi, I was wondering how open you would be to adding linter output to diffs? I currently have a branch of cdiff that does the following:

$ cdiff --lint pep8 master
diff --git a/cdiff.py b/cdiff.py
index 229f848..d5b23da 100755
--- a/cdiff.py
+++ b/cdiff.py
@@ -14,6 +14,8 @@ import signal
 import subprocess
 import select
 import difflib
+import six
+from collections import OrderedDict
 
 META_INFO = {
     'version'     : '0.9.8',                                            21: E203 whitespace before ':'
[...]

I was about to package it up as a PR, but before fighting with python 2.5 and the like, I wanted to check if you were willing to accept linting as a feature, or should I just fork (and probably drop <2.7 support for my needs, fwiw)?

Another Subversion property change

I noticed another one recently that results in a RuntimeError: unknown diff type.

Index: foo
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Syntax highlighting

Thanks for creating this project! It's just what I was looking for and it's freaking awesome.

Any chance of getting syntax highlighting for the diff? I'm a big fan of Meld and it has syntax highlighting, but is overkill to bring up the whole GUI for smaller changes.

This wouldn't have to be complicated or anything; you could use the mimetypes module to detect the filetype and then do basic highlighting with pygments.

Having this feature would make cdiff truly perfect for my needs.

'Del' and 'Add' colors don't display correctly when converted to HTML.

cdiff outputs block diffed text with red foreground AND red background, or green foreground AND green background, but I think the terminal is kind enough to display it with just the background color set.
I noticed this when I was converting output from cdiff to html using aha.
For example (I've trimmed a bit of the unnecessary bits):

$ diff <(echo 'a') <(echo 'b') --unified | cdiff -s --color=always | aha
<head>
<title>stdin</title>
</head>
<body>
<pre>
</span><span style="color:olive;">1</span> <span style="color:red;"></span><span style="color:gray;background-color:red;"></span><span style="color:red;background-color:red;">a</span><span style="color:red;"></span>                                                                                <span style="color:olive;">1</span> <span style="color:green;"></span><span style="color:gray;background-color:green;"></span><span style="color:green;background-color:green;">b</span><span style="color:green;"></span>
</pre>
</body>
</html>

I think it's because aha is converting from

ESC[0mESC[33m1ESC[0m ESC[31mESC[7mESC[31maESC[0mESC[31mESC[0m                                                                                ESC[0mESC[33m1ESC[0m ESC[32mESC[7mESC[32mbESC[0mESC[32mESC[0m

which you'll notice has ESC[31mESC[7mESC[31ma, which I think should just be ESC[31mESC[7ma. As it is, it sets the foreground, reverses, and then sets the foreground again.

cdiff command name conflicts with colordiff

cdiff is great, I already got pretty much used to it. Today I was considering making an unofficial RPM package for it. However. it turns out the cdiff binary conflicts with a binary of the same name provided by colordiff package.

What now? Should we give cdiff an alternate name?

Multiple permission changes

The below results in a RuntimeError: unknown diff type.

diff --git a/cdiff b/cdiff
old mode 100755
new mode 100644
diff --git a/cdiff.py b/cdiff.py
old mode 100755
new mode 100644

This affects issue #16 too.

Using cdiff breaks my git diff

I installed and used cdiff and everything is fine. But now when I try to use git diff, I get the following error:

fatal: e73d677814f45daf7c9a340fe0ce4646e10cc698: no such path in the working tree.
Use 'git <command> -- <path>...' to specify paths that do not exist locally.
fatal: c2c295456e512256f0036fefc16aae7cc694bd10: no such path in the working tree.
Use 'git <command> -- <path>...' to specify paths that do not exist locally.

There are 2 fatal lines because I have 2 modified files. If I have 1, I only get it once etc.

I have cdiff v0.9.3 installed, git 1.9.1 on Ubuntu Linux 13.10. This repository is a git-svn cloned repository, but I've seen this happen with a regular pure git repository

Once I use cdiff it seems to 'infect' my git repository and I can't use git diff any more. Other git tools that look at diffs work file (e.g. git status works fine, I can use git log --patch, git checkout --path).

cdiff eating bits of hunks

With the following diff:

Index: book.xml
===================================================================
--- book.xml    (revision 43732)
+++ book.xml    (working copy)
@@ -5854,6 +5854,36 @@
      </tgroup>
    </table>

+   <table frame="none">
+     <title>Variables the Users can define for
+       <command>cmake</command> builds</title>
+
+     <tgroup cols="2">
+       <thead>
+         <row>
+       <entry>Variable</entry>
+       <entry>Means</entry>
+         </row>
+       </thead>
+
+       <tbody>
+         <row>
+       <entry><varname>CMAKE_VERBOSE</varname></entry>
+       <entry>Enable verbose build output. Default not set,
+         unless <varname>BATCH</varname> or
+         <varname>PACKAGE_BUILDING</varname> are set.</entry>
+         </row>
+
+         <row>
+       <entry><varname>CMAKE_NOCOLOR</varname></entry>
+       <entry>Disables colour build output. Default not set,
+         unless <varname>BATCH</varname> or
+         <varname>PACKAGE_BUILDING</varname> are set.</entry>
+         </row>
+       </tbody>
+     </tgroup>
+   </table>
+
    <para><application>CMake</application> supports the following
      build profiles: <literal>Debug</literal>,
      <literal>Release</literal>,

I get the following display:

cdiff bug

in which the bit before the diff is displayed after.

Make parser more robust

I noticed that the following results in a RuntimeError: unknown diff type.

$ chmod ugo+x foo
$ git diff
diff --git a/foo b/foo
old mode 100644
new mode 100755
$ cdiff
...
RuntimeError: unknown diff type

Subversion mergeinfo property changes also result in a similar error.

$ svn merge svn://repository/foo/branches/foo-bar svn://repository/foo/trunk
$ svn diff
Index: .
==================================================================
--- .   (revision 10)
+++ .   (working copy)

Property changes on: .
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /repository/foo/branches/foo-bar:r4-9
   Merged /repository/foo/trunk/foo:r2-3
$ cdiff
...
RuntimeError: unknown diff type

incorrect highlighting of evil unified diff

A unified diff designed to confuse diff colorizers successfully confuses cdiff.

--- evil.orig   2013-06-01 16:36:29.676003599 -0500
+++ evil.new    2013-06-01 16:36:28.280056137 -0500
@@ -1,12 +1,12 @@
 blah blah blah
-humbug
+bah humbug
 one two three
 four five six
--- vim73/src/ui.c      2013-06-01 14:48:45.012467754 -0500
+++ vim73/src/ui.c      2013-06-01 14:48:45.012467754 -0500
 @@ -1,6 +1,6 @@
 blah blah blah
 humbug
 one two three
 four five six
-eight nine ten
+seven eight nine ten
 zero

I found cdiff after writing about the subtleties of diff colorizing and it looked like you were doing a real parse of the diff. But cdiff highlights the false filename lines as real filename lines and highlights the lines after those as cyan.

moving diff lines

This is on cdiff 0.9.6. Consider this diff file:

$ cat a.diff
diff --git a/a.c b/a.c
index 5495151..7fce67e 100644
--- a/a.c
+++ b/a.c
@@ -5,6 +5,10 @@ void func1() {
   x += 1;
 }

+void functhreehalves() {
+  x += 1.5;
+}
+
 void func2() {
   x += 2;
 }

Execution 1 with no color is correct:

$ cat a.diff | cdiff -c never
diff --git a/a.c b/a.c
index 5495151..7fce67e 100644
--- a/a.c
+++ b/a.c
@@ -5,6 +5,10 @@ void func1() {
   x += 1;
 }

+void functhreehalves() {
+  x += 1.5;
+}
+
 void func2() {
   x += 2;
 }

Execution 2 with color---notice the + lines have moved / misidentified:

$ cat a.diff | cdiff -c always
diff --git a/a.c b/a.c
index 5495151..7fce67e 100644
--- a/a.c
+++ b/a.c
@@ -5,6 +5,10 @@ void func1() {
   x += 1;
+}
+
+void functhreehalves() {
+  x += 1.5;
 }

 void func2() {
   x += 2;
 }

Add support for configuration file

I use cdiff everyday and 99% of the time in side by side mode.

It would be very nice if the application automatically picked up the user preferences from an .cdiffrc file so I would not have to explicitly add the -s option every time.

What do you think?

Log messages get corrupted

Notice the Format docstring message gets moved to an incorrect location.

$ cat log
commit 65f33a326fb1d81e9b56cfa9dbe3af887ed91c8d
Author: Steven Myint
Date:   Fri Mar 22 14:59:34 2013 -0700

    Remove unused imports

diff --git a/libmodernize/fixes/__init__.py b/libmodernize/fixes/__init__.py
index f8628f1..2e06052 100644
--- a/libmodernize/fixes/__init__.py
+++ b/libmodernize/fixes/__init__.py
@@ -1,7 +1,3 @@
-import sys
-from lib2to3 import refactor
-
-
 lib2to3_fix_names = set([
     'lib2to3.fixes.fix_apply',
     'lib2to3.fixes.fix_except',

commit 2e80837bf815d0686138beec9a5bb94e3282204d
Author: Steven Myint
Date:   Fri Mar 22 14:33:55 2013 -0700

    Format docstring

diff --git a/libmodernize/main.py b/libmodernize/main.py
index caf847d..b24db29 100644
--- a/libmodernize/main.py
+++ b/libmodernize/main.py
@@ -14,6 +14,7 @@ def main(args=None):
     """Main program.

     Returns a suggested exit status (0, 1, 2).
+
     """
     # Set up option parser
     parser = optparse.OptionParser(usage="modernize [options] file|dir ...")
$ cdiff < log
commit 65f33a326fb1d81e9b56cfa9dbe3af887ed91c8d
Author: Steven Myint
Date:   Fri Mar 22 14:59:34 2013 -0700

    Remove unused imports

diff --git a/libmodernize/fixes/__init__.py b/libmodernize/fixes/__init__.py
index f8628f1..2e06052 100644
--- a/libmodernize/fixes/__init__.py
+++ b/libmodernize/fixes/__init__.py
@@ -1,7 +1,3 @@
-import sys
-from lib2to3 import refactor
-
-
 lib2to3_fix_names = set([
     'lib2to3.fixes.fix_apply',
     'lib2to3.fixes.fix_except',
    Format docstring

commit 2e80837bf815d0686138beec9a5bb94e3282204d
Author: Steven Myint
Date:   Fri Mar 22 14:33:55 2013 -0700


diff --git a/libmodernize/main.py b/libmodernize/main.py
index caf847d..b24db29 100644
--- a/libmodernize/main.py
+++ b/libmodernize/main.py
@@ -14,6 +14,7 @@ def main(args=None):
     """Main program.

     Returns a suggested exit status (0, 1, 2).
+
     """
     # Set up option parser
     parser = optparse.OptionParser(usage="modernize [options] file|dir ...")

Customizing git's external diff breaks cdiff output.

When the git diff command is customized through setting GIT_EXTERNAL_DIFF in the environment, the output of cdiff is broken and defaults to the output of the tool git has been configured to use.

$ cdiff
*** unknown format, fall through to 'unified'

After which, the output of whatever git uses is printed.

Temporarily unsetting this variable when cdiff invokes git diff fixes the issue.

I haven't yet figured out how to fix the issue when git config diff.external is used instead of exporting the environment variable.

using without source control

This tool would also be useful without source control, simply to diff two files and get a nice readable colored output. I was unable to use it in such a context.

cdiff is breaking blocks

Let's say I have...

case: 'one';
  return 'yes, one';
  break;

...and I change it to...

case: 'one';
  return 'yes, one';
  break;
case: 'two';
  return 'yes, two';
  break;

...then git diff will correctly identify the change as...

case: 'two';
  return 'yes, two';
  break;

...but if I pipe git diff to cdiff, it shows the change as:

  break;
case: 'two';
  return 'yes, two';

How can I fix this? Thanks.

Customize colors

Is there a way to customize the specific colors (foreground and background) ydiff uses?

diff two arbitrary directories

There doesn't seem to be any way to take two arbitrary (non-git) directories and do a side-by-side diff. Right now I'm working around this by initializing a git repo, deleting one directory, and copying the other where the first used to be, then using cdiff.

Not able to use cdiff with git difftool

First of all nice tool really.

I'm trying to use cdiff with git difftool but I always get the same error

fatal: external diff died, stopping at ....

Is it a known issue?

Will HTML or PDF format file containing the side-by-side diff output support ?

cdiff really helps me a lot : )

I prefer the side-by-side output on the screen, and would you like to make it into HTML or PDF format file ? Or do you have any time or plan ?

The result of command "git diff src.c | cdiff -s > src.c.diff" looks like not that shows on the screen, which is side-by-side. If supporting HTML or PDF, it will be better to share and get review from others.

Thanks for your time.

When trying to pipe UTF: UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

This works fine:

$ echo "ąłźą" | cdiff
*** unknown format, fall through to 'unified'
ąłźą

But when trying to pipe UTF data the following is perceived:

$ echo "ąłźą" | cdiff | less -X
Traceback (most recent call last):
  File "/usr/bin/cdiff-python2.7", line 7, in <module>
    sys.exit(cdiff.main())
  File "/usr/lib64/python2.7/site-packages/cdiff.py", line 728, in main
    sys.stdout.write(decode(line))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

$ echo "ąłźą" | cdiff > /dev/null
Traceback (most recent call last):
  File "/usr/bin/cdiff-python2.7", line 7, in <module>
    sys.exit(cdiff.main())
  File "/usr/lib64/python2.7/site-packages/cdiff.py", line 728, in main
    sys.stdout.write(decode(line))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

Discovered downstream by Marcin Mirosław.

Tested against current master HEAD.

We are both using UTF-8 locales, different languages (pl_PL and en_US).

width not working with terminator

Using cdiff 0.9.6 when I pipe diff output to cdiff it never seems to honour my terminal's window width. This includes both auto as well as hard setting of a width limit. I am using terminator (https://launchpad.net/terminator) on Ubuntu 14.04 with xterm-256color for TERM setting.

Where/what do I need to investigate in order to help resolve this issue?

Implement option to ignore deleted files

99% of the time when I'm doing a diff I am not interested in files that have been deleted. So it would be nice if cdiff had an option to suppress the inclusion of such files in its output. The obvious way to do this is to utilize git diff --irreversible-delete (which is what I normally run when I'm not using cdiff). The other solution is to use git diff --diff-filter=d which is similar but also omits the diff headers for the deleted files.

Use pager even when output fits in single page

cdiff is a great tool, but one minor annoyance is when using cdiff and expecting multiple pages, often have to press "Ctrl-D" to scroll. One side effect is when there is a single page output, the pager prompt is missing, so "Ctrl-D" will often log out of the terminal (or in my case, tmux pane).

Feature request would be to ensure prompt is available for all page lengths so Ctrl-D will not inadvertently log out of the terminal session.

Add examples for diff conflicting files

Diffting conflict files is as easy as doing:

$ cdiff :1:file :2:file
$ cdiff :1:file :3:file

Where:

  • 1: is base
  • 2: is ours
  • 3: is theirs

Things get complicated easily when using rebase command, where our changes become theirs and viceversa

Will it be helpful to add options like

$ cdiff --conflict-12 file
$ cdiff --conflict-13 file
$ cdiff --conflict-23 file

?

Maybe a --reverse option can be added to offer --conflict-21, etc. Or --rebase-12 that implies --conflict-12 --reverse etc

Non-deterministic output

On my (OS X 10.6) machine, I sometimes get no output at all when running against contextual diffs. It seems to be related to the _set_non_block(), as it goes away if I disable that. The problem only seems to occur under Python 3 (3.2 and 3.3). It seems to work fine on Python 2.

$ ./cdiff <  tests/context/in.diff
$ ./cdiff <  tests/context/in.diff
--- a/Lib/test/test_minidom.py  Fri Sep 30 08:46:25 2011 +0300
+++ b/Lib/test/test_minidom.py  Sat Oct 01 21:02:49 2011 +0300
@@ -467,6 +467,13 @@
         dom.unlink()
         self.confirm(domstr == str.replace("\n", "\r\n"))
+
+    def testPrettyTextNode(self):
+        str = '<A>B</A>'
+        dom = parseString(str)
+        dom2 = parseString(dom.toprettyxml())
+        self.confirm(dom.childNodes[0].childNodes[0].toxml()==
+                     dom2.childNodes[0].childNodes[0].toxml())

     def testProcessingInstruction(self):
         dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
         pi = dom.documentElement.firstChild
--- a/Lib/xml/dom/minidom.py    Fri Sep 30 08:46:25 2011 +0300
+++ b/Lib/xml/dom/minidom.py    Sat Oct 01 21:02:49 2011 +0300
@@ -836,7 +836,9 @@
             _write_data(writer, attrs[a_name].value)
             writer.write("\"")
         if self.childNodes:
-            writer.write(">%s"%(newl))
+            writer.write(">")
+            if self.childNodes[0].nodeType != Node.TEXT_NODE:     # Strict check
+                writer.write(newl)
             for node in self.childNodes:
                 node.writexml(writer,indent+addindent,addindent,newl)
             writer.write("%s</%s>%s" % (indent,self.tagName,newl))
@@ -1061,7 +1063,7 @@
         return newText

     def writexml(self, writer, indent="", addindent="", newl=""):
-        _write_data(writer, "%s%s%s"%(indent, self.data, newl))
+        _write_data(writer, self.data)

     # DOM Level 3 (WD 9 April 2002)


$ ./cdiff <  tests/context/in.diff

I don't use contextual diffs, so this doesn't really matter to me. But I noticed this when I was running the tests.

$ ./regression.sh
python   ./cdiff -c always          <  tests/context/in.diff          FAIL != tests/context/out.normal
python   ./cdiff -c always -s       <  tests/context/in.diff          PASS
python   ./cdiff -c always -s -w70  <  tests/context/in.diff          FAIL != tests/context/out.w70
$ ./regression.sh
python   ./cdiff -c always          <  tests/context/in.diff          PASS
python   ./cdiff -c always -s       <  tests/context/in.diff          PASS
python   ./cdiff -c always -s -w70  <  tests/context/in.diff          FAIL != tests/context/out.w70

Improve filename display for SVN

Using colordiff, the revision/working copy information is displayed at the top of the output; with cdiff the actual filenames are displayed instead - not very descriptive.

With colordiff:

~/Projects/als/my_app[my_branch|3339|!]»svn diff
Index: conf/application.yaml
===================================================================
--- conf/application.yaml       (revision 3339)
+++ conf/application.yaml       (working copy)

With cdiff:

~/Projects/als/my_app[my_branch|3339|!]»cdiff
Index: conf/application.json
===================================================================
--- /home/peter/Projects/als/my_app/.svn/pristine/75/75da522a5b6f74483e32c84ed53c547c300df1b0.svn-base        2012-12-17 16:46:35.000000000 +0000
+++ /tmp/svn-EtyEgj     2013-02-21 16:19:14.541701137 +0000

Also, it would be great if I could add cdiff straight to my Subversion config file as the default diff tool without having to create a wrapper.

Unexpected behavior when parsing output of `git show` run on `stash` reflog-style refs

Probably not a bug; just me not being a cdiff wizard yet. Haven't been able to figure out how to get it working yet, so help is appreciated!

Summary

Running something like this: git show stash@{1} | cdiff -s results in one column of mostly-cyan text that seems to be missing sections. I expected it to behave similarly to git show 4e2fc7b | cdiff -s, which results in the whole diff rendered in two columns of diff-colored text.

I've tried several different stash indexes as well as just git show stash and all of them behaved the same way.

To Reproduce

  • Operating system: Ubuntu 14.04 (I know, I know)
  • Version of cdiff: 1.0
  • Installation method: iirc, pip install cdiff at the system level (binary is in /usr/local/bin/cdiff)

I dumped the results of the two git-show commands above to two files described below. Create those files, then run the following:

cat git-show-stash.txt | cdiff -s  # unexpected behavior
cat git-show-sha.txt | cdiff -s  # expected behavior

Files

git-show-stash.txt

commit 7c931ec949fd936ebdc43cb7cff58a6dabe88bec                                                                                                                                                                                      [0/5]
Merge: adc3783 a2a6bd5
Author: Firstname Lastname <[email protected]>
Date:   Wed Jul 5 15:46:59 2017 -0500

    WIP on zone_delta_processing: adc3783 fix "no module named PythonMagick" error by switching to pgmagick

diff --cc rtls/urls.py
index 3ea1a0b,3ea1a0b..1cc7364
--- a/rtls/urls.py
+++ b/rtls/urls.py
@@@ -49,6 -49,6 +49,11 @@@ urlpatterns =
          views.api_disassociate_holder,
          name='api_disassociate_holder',
      ),
++    url(  # receives zone delta bundles, determines what actions to take (if any)
++        r'^(?i)api/triage-deltas/zone?$',
++        views.api_triage_zone_deltas,
++        name='api_triage_zone_deltas',
++    ),


      # --------- Map URLS ---------
diff --cc rtls/views.py
index 694ae27,694ae27..45e874c
--- a/rtls/views.py
+++ b/rtls/views.py
@@@ -6,6 -6,6 +6,7 @@@ from django.core.exceptions import Mult
  from django.core.mail import EmailMessage, send_mail
  from django.http import HttpResponse, HttpResponseNotFound, JsonResponse
  from django.shortcuts import render, render_to_response, get_object_or_404
++from django.views.decorators.csrf import csrf_exempt

  from contacts.models import Person, Location
  from mosaiq.models import (
@@@ -75,6 -75,6 +76,16 @@@ def api_potential_holder_list(request)
      ))


++@csrf_exempt
++def api_triage_zone_deltas(request):
++    '''Receives a bundle of zone delta objects as a POST and determines what
++    actions need to be taken because of them, if any.'''
++    # print 'REMOTE_HOST', request.META['REMOTE_HOST']
++    # print 'HTTP_HOST', request.META['HTTP_HOST']
++    print '\nContents of POST:', request.POST, '\n'
++    return HttpResponse(status=200)
++
++
  def association_node_list(request):
      return render(request, 'rtls/association_node_list.html', {
          'registration_nodes': Node.objects.filter(topic='tag_reg')

git-show-sha.txt

commit 4e2fc7b5cb84a459f82e2f913a97a0b49f6e8b0d                                                                                                                                                                                      [0/5]
Author: Firstname Lastname <[email protected]>
Date:   Fri Jun 30 11:47:52 2017 -0500

    document associate/disassociate urls

diff --git a/rtls/urls.py b/rtls/urls.py
index 378b0a7..3ea1a0b 100644
--- a/rtls/urls.py
+++ b/rtls/urls.py
@@ -39,12 +39,12 @@ urlpatterns = [
         views.api_potential_holder_list,
         name='api_potential_holder_list',
     ),
-    url(
+    url(  # used to associate a tag and a holder
         r'^(?i)api/association/associate/?$',
         views.api_associate,
         name='api_associate',
     ),
-    url(
+    url(  # used to disassociate a holder from any tag it may be associated with
         r'^(?i)api/association/disassociate/?$',
         views.api_disassociate_holder,
         name='api_disassociate_holder',

Tips for using cdiff as `git cdiff` :)

Hey there, love this package 😄

I discovered that simply symlinking or renaming the executable to git-cdiff meant that I could now use:

git cdiff

Which felt a little more natural with all the other git commands.

Is there any other recommended way to do this? Is it worth adding to the README file?

Cheers
Fotis

Cannot use cdiff to compare two files

I want to try cdiff just to compare two files in the folder. I type something like cdiff one.txt two.txt, and I get:

→ cdiff one.txt two.txt
fatal: two.txt: no such path in the working tree.
Use 'git -- ...' to specify paths that do not exist locally.

Yes, and I call cdiff in the folder which is git repository, and files are not added to repo.

UnicodeDecodeError - binary file diffs

When I tried to retrieve a commit diff which contains binary file (JPG image). cdiff complains about.

Traceback (most recent call last):
  File "diff.py", line 7, in <module>
    print commit.diffs
  File "/home/aleiphoenix/src/python/pygrit/src/pygrit/utils/wrappers.py", line 13, in template
    ret = func(*args)
  File "/home/aleiphoenix/src/python/pygrit/src/pygrit/commit.py", line 147, in diffs
    for diff in diffs:
  File "/home/aleiphoenix/.pyenv/versions/2.7.5/lib/python2.7/site-packages/cdiff.py", line 317, in get_diff_generator
    line = decode(line)
  File "/home/aleiphoenix/.pyenv/versions/2.7.5/lib/python2.7/site-packages/cdiff.py", line 641, in decode
    return line.decode('utf-8')
  File "/home/aleiphoenix/.pyenv/versions/2.7.5/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x80 in position 1: invalid start byte

Shouldn't we also catch UnicodeDecodeError and return line ?

def decode(line):
    """Decode UTF-8 if necessary."""
    try:
        return line.decode('utf-8')
    except AttributeError:
        return line

or check the diff header, if it has Binary files xxx xxx differs, just don't retrieve the diff info , additionally add an attribute to mark the diff is a binary file ?

Thanks.

Corrupted terminal

If I show a (relatively small) diff in cdiff and press control-c, I get a KeyboardInterrupt stack trace and a corrupted terminal. (The terminal will no longer show me what I'm typing.) I can wrap pager.wait() in a try/except, but the terminal will still get corrupted. I haven't figured out what cleanup needs to be done to avoid the terminal corruption yet.

This is somewhat related to #11. But that issue was fixed by handling the KeyboardInterrupt that occurs during diff generation. The current issue occurs after diff generation, while we wait idly.

Python API?

Hi,

Apologies if this was asked already.. couldn't find the answer.

Is it possible to use cdiff programmatically from the Python script?

Something like this:

import cdiff

diff_string = get_diff_somehow()

cdiff.print_colorized(diff_string)

This would be super useful for the utility we are writing.

Thanks!

Request a feature like git show

Hi, @ymattw. Thanks for your awesome work first.
If I want to view changes by specific commit. I have to run git show COMMIT_ID, and cdiff only work support something like git diff now.
Will you append this feature later?

Fedora package

With the comand conflict resiolved, I took the first step to get slop into Fedora. It's my second package ever, so 🤞!

Once (I mean, if) it succeeds, this issue can serve to add the info to the README.rst.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.