{"id":13477350,"url":"https://github.com/ymattw/ydiff","last_synced_at":"2026-04-07T19:31:57.218Z","repository":{"id":6642473,"uuid":"7886632","full_name":"ymattw/ydiff","owner":"ymattw","description":"View colored, incremental diff in workspace or from stdin, side by side and auto paged.","archived":false,"fork":false,"pushed_at":"2025-12-06T20:33:30.000Z","size":6231,"stargazers_count":915,"open_issues_count":1,"forks_count":64,"subscribers_count":14,"default_branch":"master","last_synced_at":"2026-02-18T18:30:02.175Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ymattw.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2013-01-29T06:20:34.000Z","updated_at":"2026-01-26T10:45:08.000Z","dependencies_parsed_at":"2024-06-08T11:27:04.497Z","dependency_job_id":"fc5dc56e-c8c0-4071-a132-7c19e1ae411d","html_url":"https://github.com/ymattw/ydiff","commit_stats":{"total_commits":285,"total_committers":17,"mean_commits":"16.764705882352942","dds":0.3192982456140351,"last_synced_commit":"c8bf5928ce5be62a513b9c04ed16c471d1a78893"},"previous_names":["ymattw/cdiff"],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/ymattw/ydiff","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymattw%2Fydiff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymattw%2Fydiff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymattw%2Fydiff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymattw%2Fydiff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ymattw","download_url":"https://codeload.github.com/ymattw/ydiff/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymattw%2Fydiff/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31526666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T16:01:41.504Z","updated_at":"2026-04-07T19:31:57.194Z","avatar_url":"https://github.com/ymattw.png","language":"Python","funding_links":[],"categories":["Python","General","others","\u003ca name=\"diff\"\u003e\u003c/a\u003eDiff","Source Code"],"sub_categories":["Diff Enhancers"],"readme":"Ydiff\n=====\n\n.. image:: https://github.com/ymattw/ydiff/actions/workflows/test.yml/badge.svg\n   :alt: Tests status\n   :target: https://github.com/ymattw/ydiff/actions\n\nYdiff is a terminal-based tool to view *colored*, *incremental* diffs in\na version-controlled workspace or from stdin, in *side-by-side* (similar to\n``diff -y``) or unified mode, and *auto-paged*. It only requires Python \u003e= 3.3\n*without external dependencies* and ``less`` as a pager.\n\nThe diffs in side-by-side mode appear below. See also the `screenshots`_ of the\nunified mode.\n\n.. _`screenshots`: https://github.com/ymattw/ydiff/tree/26857b8/img\n\n*Theme \"default\" on a dark terminal background:*\n\n.. image:: https://raw.githubusercontent.com/ymattw/ydiff/26857b8/img/darkbg-side-by-side-default.png\n   :alt: side by side, theme 'default' on a dark background\n   :align: center\n   :height: 300 px\n\n*Theme \"default\" on a light terminal background:*\n\n.. image:: https://raw.githubusercontent.com/ymattw/ydiff/26857b8/img/lightbg-side-by-side-default.png\n   :alt: side by side, theme 'default' on a light background\n   :align: center\n   :height: 300 px\n\n*Theme \"dark\" on a dark terminal background:*\n\n.. image:: https://raw.githubusercontent.com/ymattw/ydiff/26857b8/img/darkbg-side-by-side-dark.png\n   :alt: side by side, theme 'dark' on a dark background\n   :align: center\n   :height: 300 px\n\n*Theme \"light\" on a light terminal background:*\n\n.. image:: https://raw.githubusercontent.com/ymattw/ydiff/26857b8/img/lightbg-side-by-side-light.png\n   :alt: side by side, theme 'light' on a light background\n   :align: center\n   :height: 300 px\n\nInstallation\n------------\n\nYdiff only depends on Python built-in libraries, so you can just download the\nsource and run without worrying about any installation. Git `tagged`_ revisions\nwill be packaged and uploaded to `PyPI`_ timely, however, packages hosted\nelsewhere are not (please note they are not managed by the author `@ymattw`_).\n\n.. _`tagged`: https://github.com/ymattw/ydiff/tags\n.. _`PyPI`: http://pypi.python.org/pypi/ydiff\n.. _`@ymattw`: https://github.com/ymattw\n\nTo run from source directly, just save `ydiff.py`_ as ``ydiff`` to whatever\ndirectory which is in your ``$PATH``, for example, ``$HOME/bin``:\n\n.. _`ydiff.py`: https://raw.github.com/ymattw/ydiff/master/ydiff.py\n\n.. code-block:: bash\n\n    curl -L https://raw.github.com/ymattw/ydiff/master/ydiff.py \u003e ~/bin/ydiff\n    chmod +x ~/bin/ydiff\n\nTo install from `PyPI`_:\n\n.. code-block:: bash\n\n    pip install --upgrade ydiff\n\nTo install with Homebrew (`Formula`_) on macOS:\n\n.. _`Formula`: https://github.com/Homebrew/homebrew-core/blob/master/Formula/y/ydiff.rb\n\n.. code-block:: bash\n\n    brew install ydiff\n\nTo install on Fedora:\n\n.. code-block:: bash\n\n    dnf install ydiff\n\nTo install on FreeBSD:\n\n.. code-block:: bash\n\n    pkg install ydiff\n\nUsage\n-----\n\nType ``ydiff -h`` to show usage::\n\n    $ ydiff -h\n    Usage: ydiff [options] [file|dir ...]\n\n    View colored, incremental diff in a workspace or from stdin, with side by side\n    and auto pager support.\n\n    Options:\n      --version             show program's version number and exit\n      -h, --help            show this help message and exit\n      -s, --side-by-side    enable side-by-side mode (default True; DEPRECATED)\n      -u, --unified         show diff in unified mode (disables side-by-side mode)\n      -w N, --width=N       set text width for side-by-side mode, 0 (default) for\n                            auto detection and fallback to 80 when not possible\n      -l, --log             show log with changes from revision control\n      -c WHEN, --color=WHEN\n                            colorize mode 'auto' (default), 'always', or 'never'\n      -t N, --tab-width=N   convert tab chars to this many spaces (default: 8)\n      --wrap                wrap long lines in side-by-side mode (default True;\n                            DEPRECATED)\n      --nowrap, --no-wrap   do not wrap long lines in side-by-side mode\n      -p PAGER, --pager=PAGER\n                            pager application to feed output to, default is 'less'\n      -o OPT, --pager-options=OPT\n                            options to supply to pager application\n      --theme=THEME         option to pick a color theme (one of dark, default,\n                            light)\n\n      Note:\n        Option parser will stop on first unknown option and pass them down to\n        underneath revision control. Environment variable YDIFF_OPTIONS may be\n        used to specify default options that will be placed at the beginning\n        of the argument list.\n\nRead diff from local modification in a *Git/Mercurial/Perforce/Svn* workspace\n(output from e.g. ``git diff``, ``svn diff``):\n\n.. code-block:: bash\n\n    cd proj-workspace\n    ydiff                       # view colored side by side diff, auto set text\n                                # width based on terminal size\n    ydiff -u                    # view colored incremental diff in unified mode\n    ydiff -w 90                 # use text width 90, wrap long lines\n    ydiff --no-wrap             # auto set text width but do not wrap long lines\n    ydiff file1 dir2            # view modification of given files/dirs only\n    ydiff -w90 -U10             # pass '-U10' to underneath revision diff tool\n    ydiff --cached              # show git staged diff (git diff --cached)\n    ydiff -r1234                # show svn diff to revision 1234\n\nRead log with changes in a *Git/Mercurial/Svn* workspace (output from e.g.\n``git log -p``, ``svn log --diff``), note *--diff* option is new in svn 1.7.0:\n\n.. code-block:: bash\n\n    cd proj-workspace\n    ydiff -l                    # read log along with changes, side by side\n    ydiff -lu                   # equivalent to ydiff -l -u, unified mode\n    ydiff -l -w90 --no-wrap     # set text width 90 and disable wrapping\n    ydiff -l file1 dir2         # see log with changes of given files/dirs only\n\nUtilize a specific pager application:\n\n.. code-block:: bash\n\n    ydiff -p more                   # use \"more\" as a pager\n    ydiff -p cat                    # when neither less nor more is avilable\n    ydiff -o \"-FRSX --shift 2\"      # customized option (pager defaults to less)\n\nPipe in a diff:\n\n.. code-block:: bash\n\n    git log -p -2 | ydiff       # view git log with changes of last 2 commits\n    git show 15bfa | ydiff      # view a given git commit, side by side\n    svn diff -r1234 | ydiff     # view svn diff comparing to given revision\n    diff -u file1 file2 | ydiff # view diff between two files (note the '-u')\n    diff -ur dir1 dir2 | ydiff  # view diff between two dirs\n\n    # View diff in a GitHub pull request, side by side\n    curl https://github.com/ymattw/ydiff/pull/11.diff | ydiff\n\n    # View a patch file in colored unified format.\n    ydiff -u \u003c foo.patch\n\nRedirect output to another patch file is safe even without ``-u``:\n\n.. code-block:: bash\n\n    svn diff -r PREV | ydiff \u003e my.patch\n\nCustomized themes\n-----------------\n\nYou can define your own themes in ``~/.config/ydiff/themes.ini``. Check out the\n`built-in themes`_ for examples.\n\n.. _`built-in themes`: https://github.com/search?q=repo%3Aymattw%2Fydiff+%2F_BUILTIN_THEMES+%3D%2F\u0026type=code\n\nThe section names are theme names. Undeclared theme keys will inherit values\nfrom the same-named built-in theme or from the \"default\" theme otherwise.\n\nNotes\n-----\n\n1. Ydiff only supports diffs in `Unified Format`_. Diffs in other format may be\n   converted to Unified Format via tool ``filterdiff`` (usually offered by\n   package ``patchutils``.)\n\n   .. _`Unified Format`: https://en.wikipedia.org/wiki/Diff#Unified_format\n\n2. Environment variable ``YDIFF_OPTIONS`` may be used to specify default\n   options that will be placed at the beginning of the argument list, for\n   example:\n\n   .. code-block:: bash\n\n    export YDIFF_OPTIONS='-w100'\n    ydiff foo  # equivalent to \"ydiff -w100 foo\"\n\n3. If you feel more comfortable with a command such as ``git d`` to trigger the\n   ydiff command, you may symlink the executable to one named ``git-d``, or\n   configure an alias:\n\n   .. code-block:: bash\n\n    # Create a symlink git-d -\u003e ydiff\n    D=$(dirname $(which ydiff)); ln -s ydiff $D/git-d\n\n    # Or configure an alias\n    git config --global alias.d '!ydiff'\n\nKnown issues\n------------\n\n- Wide characters may cause alignment problem in side-by-side mode.\n- Terminal might be in a mess on exception (type ``reset`` can fix it).\n\n.. vim:set ft=rst et sw=4 sts=4 tw=79:\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fymattw%2Fydiff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fymattw%2Fydiff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fymattw%2Fydiff/lists"}