webdiff


Namewebdiff JSON
Version 1.1.1 PyPI version JSON
download
home_pagehttps://github.com/danvk/webdiff/
SummaryTwo-column web-based git difftool
upload_time2024-06-07 17:24:13
maintainerNone
docs_urlNone
authorDan Vanderkam
requires_python<4.0,>=3.10
licenseApache-2.0
keywords git difftool web
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # git webdiff

Two-column web-based git difftool.

<p align="center">
  <a href="https://pypi.org/project/webdiff/" target="_blank"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/webdiff" /></a>
  <a href="https://dl.circleci.com/status-badge/redirect/gh/danvk/webdiff/tree/master" target="_blank"><img alt="CircleCI 📝" src="https://dl.circleci.com/status-badge/img/gh/danvk/webdiff/tree/master.svg?style=svg" /></a>
  <a href="https://github.com/danvk/webdiff/blob/master/LICENSE" target="_blank"><img alt="License: Apache2 📝" src="https://img.shields.io/github/license/danvk/webdiff" /></a>
  <a href="https://github.com/sponsors/danvk" target="_blank"><img alt="Sponsor: On GitHub 💸" src="https://img.shields.io/badge/sponsor-on_github_💸-21bb42.svg" /></a>
</p>

Features include:

* Side-by-side (two column) diff view
* Runs in the browser of your choice on any platform.
* Syntax highlighting via highlight.js
* Step back and forth through multiple files in a single diff
* Rich support for image diffs

<!-- These are absolute URLs so that they display on pypi.org -->
<!-- This is `git webdiff 05157bba^..05157bba`, in this repo -->
![Screenshot of webdiff in action](https://raw.githubusercontent.com/danvk/webdiff/master/images/webdiff.png)

<!-- This is `git webdiff c80f969^..c80f969` in the dygraphs-dpxdt repo -->
![Screenshot of image diffs](https://raw.githubusercontent.com/danvk/webdiff/master/images/webdiff-images.png)

## Installation

    pip install webdiff

or, if you prefer [Homebrew]:

    brew install danvk/webdiff/webdiff

(the latter will also install [ImageMagick] as a recommended dependency.)

## Usage

Instead of running "git diff", run:

    git webdiff

You can also start webdiff via:

    git webdiff [args]

You can pass all the same arguments that you would to `git diff`, e.g.
`1234..5678` or `HEAD`.

`webdiff` can also be invoked directly to diff two directories or files:

    webdiff <left_dir> <right_dir>
    webdiff <left_file> <right_file>

You can also use `webdiff` to view GitHub pull requests:

    webdiff https://github.com/owner/repo/pull/123
    webdiff '#150'  # if you're in a git repo with a github remote

This will download the files relevant to the Pull Request and run `webdiff`.

If you run into GitHub API quota limits or you'd like to use webdiff with
private repos, you can set your credentials in a `.githubrc` file:

    user.login: yourusername
    user.token: your-personal-access-tokens

Make sure you chmod this file to only be readable by yourself. You can generate
a personal access token for webdiff via github.com → profile → Settings →
Personal access tokens. Make sure to grant all the "repo" privileges.

## Configuration

webdiff can be configured via [`git config`][git config]. To change the syntax highlighting theme, for example:

    git config webdiff.theme rainbow

(You can find a list of supported themes in the [themes] directory.)

As with any git configuration setting, these can be set globally or per-repo.

Options are:

| Setting        | Default       | Notes  |
| -------------- | ------------- | ------ |
| webdiff.theme  | googlecode    | Syntax highlighting theme (see [themes] directory). |
| webdiff.port   | -1            | Port on which to serve webdiff. Default is random open port. This can be overridden with the `--port` command line flag or the `WEBDIFF_PORT` environment variable. |
| webdiff.host   | localhost     | Host name on which to serve the webdiff UI. Use `0.0.0.0` to serve publicly. The special value `<hostname>` uses your computer's network name. This can be overridden with the `--host` command line flag or the `WEBDIFF_HOST` environment variable. |
| webdiff.maxDiffWidth | 100 | Maximum length of lines in the diff display. After this width, lines will wrap. |
| webdiff.unified | 8 | Lines of context to display by default (`git diff -U`) |
| webdiff.extraDirDiffArgs | "" | Any extra arguments to pass to `git diff` when diffing directories. |
| webdiff.extraFileDiffArgs | "" | Any extra arguments to pass to `git diff` when diffing files. |
| webdiff.openBrowser | true | Whether to automatically open the browser UI when you run webdiff. |
| webdiff.maxLinesForSyntax | 10000 | Maximum lines in file to do syntax highlighting. |
| webdiff.colors.delete | #fee | CSS background color for delete (left) lines |
| webdiff.colors.insert | #efe | CSS background color for insert (right) lines |
| webdiff.colors.charDelete | #fcc | CSS background color for deleted characters in a delete (left) line |
| webdiff.colors.charInsert | #cfc | CSS background color for inserted characters in an insert (right) line |

## Development

    poetry install
    cd ts
    yarn
    # see https://github.com/webpack/webpack/issues/14532
    NODE_OPTIONS=--openssl-legacy-provider webpack

Then from the root directory:

    poetry run webdiff/app.py testdata/dygraphsjs/{left,right}

or to launch in debug mode:

    ./test.sh $(pwd)/testdata/manyfiles/{left,right}

(or any other directory in testdata)

To run the Python tests:

    poetry run pytest

To format the code, run:

    poetry run ruff format
    cd ts
    yarn prettier

To debug `git webdiff`, run:

    ./test-gitwebdiff.sh

## Publishing

To iterate on the PyPI package, run:

    pip3 uninstall webdiff
    poetry build
    pip3 install dist/webdiff-?.?.?.tar.gz

To publish to pypitest:

    poetry build
    poetry publish -r testpypi

And to the real pypi:

    poetry publish

See [pypirc][] and [poetry][] docs for details on setting up tokens for pypi.

Publication checklist. Do these from _outside_ the webdiff directory:

- Run `webdiff webdiff/testdata/.../{left,right}`
- Run `git webdiff 52aa15f^..52aa15f` in the codediff.js repo
- Run `webdiff https://github.com/danvk/webdiff/pull/160`

## Implementation notes

webdiff doesn't calculate any diffs itself. Instead, it relies on `git diff`. This is possible because `git diff` has a `--no-index` mode that allows it to operate outside of a git repository. Of course, this means that you need to have `git` installed to use webdiff!

When you run `webdiff dir1 dir2`, webdiff runs:

    git diff --raw --no-index dir1 dir2

To ask `git` which files are adds, removes, renames and changes. Then, when it's serving the web UI for a particular diff, it runs:

    git diff --no-index (diff args) file1 file2

This produces a patch, which is what the web UI renders. (It also needs both full files for syntax highlighting.)

When you run `git webdiff (args)`, it runs:

    git difftool -d -x webdiff (args)

This tells `git` to set up two directories and invoke `webdiff leftdir rightdir`.

There's one complication involving symlinks. `git difftool -d` may fill one of the sides (typically the right) with symlinks. This is faster than copying files, but unfortunately `git diff --no-index` does not resolve these symlinks. To make this work, if a directory contains symlinks, webdiff makes a copy of it before diffing. For file diffs, it resolves the symlink before passing it to `git diff --no-index`. The upshot is that you can run `git webdiff`, edit a file, reload the browser window and see the changes.

[pypirc]: https://packaging.python.org/specifications/pypirc/
[Homebrew]: https://brew.sh/
[ImageMagick]: https://imagemagick.org/index.php
[git config]: https://git-scm.com/docs/git-config
[themes]: http://example.com
[poetry]: https://python-poetry.org/docs/repositories/#publishable-repositories

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/danvk/webdiff/",
    "name": "webdiff",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.10",
    "maintainer_email": null,
    "keywords": "git, difftool, web",
    "author": "Dan Vanderkam",
    "author_email": "danvdk@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/dc/6d/0b8a1d209ed08c6fa704d517a423f1110b2fe7892cae8aab0b6144d4ade1/webdiff-1.1.1.tar.gz",
    "platform": null,
    "description": "# git webdiff\n\nTwo-column web-based git difftool.\n\n<p align=\"center\">\n  <a href=\"https://pypi.org/project/webdiff/\" target=\"_blank\"><img alt=\"PyPI - Version\" src=\"https://img.shields.io/pypi/v/webdiff\" /></a>\n  <a href=\"https://dl.circleci.com/status-badge/redirect/gh/danvk/webdiff/tree/master\" target=\"_blank\"><img alt=\"CircleCI \ud83d\udcdd\" src=\"https://dl.circleci.com/status-badge/img/gh/danvk/webdiff/tree/master.svg?style=svg\" /></a>\n  <a href=\"https://github.com/danvk/webdiff/blob/master/LICENSE\" target=\"_blank\"><img alt=\"License: Apache2 \ud83d\udcdd\" src=\"https://img.shields.io/github/license/danvk/webdiff\" /></a>\n  <a href=\"https://github.com/sponsors/danvk\" target=\"_blank\"><img alt=\"Sponsor: On GitHub \ud83d\udcb8\" src=\"https://img.shields.io/badge/sponsor-on_github_\ud83d\udcb8-21bb42.svg\" /></a>\n</p>\n\nFeatures include:\n\n* Side-by-side (two column) diff view\n* Runs in the browser of your choice on any platform.\n* Syntax highlighting via highlight.js\n* Step back and forth through multiple files in a single diff\n* Rich support for image diffs\n\n<!-- These are absolute URLs so that they display on pypi.org -->\n<!-- This is `git webdiff 05157bba^..05157bba`, in this repo -->\n![Screenshot of webdiff in action](https://raw.githubusercontent.com/danvk/webdiff/master/images/webdiff.png)\n\n<!-- This is `git webdiff c80f969^..c80f969` in the dygraphs-dpxdt repo -->\n![Screenshot of image diffs](https://raw.githubusercontent.com/danvk/webdiff/master/images/webdiff-images.png)\n\n## Installation\n\n    pip install webdiff\n\nor, if you prefer [Homebrew]:\n\n    brew install danvk/webdiff/webdiff\n\n(the latter will also install [ImageMagick] as a recommended dependency.)\n\n## Usage\n\nInstead of running \"git diff\", run:\n\n    git webdiff\n\nYou can also start webdiff via:\n\n    git webdiff [args]\n\nYou can pass all the same arguments that you would to `git diff`, e.g.\n`1234..5678` or `HEAD`.\n\n`webdiff` can also be invoked directly to diff two directories or files:\n\n    webdiff <left_dir> <right_dir>\n    webdiff <left_file> <right_file>\n\nYou can also use `webdiff` to view GitHub pull requests:\n\n    webdiff https://github.com/owner/repo/pull/123\n    webdiff '#150'  # if you're in a git repo with a github remote\n\nThis will download the files relevant to the Pull Request and run `webdiff`.\n\nIf you run into GitHub API quota limits or you'd like to use webdiff with\nprivate repos, you can set your credentials in a `.githubrc` file:\n\n    user.login: yourusername\n    user.token: your-personal-access-tokens\n\nMake sure you chmod this file to only be readable by yourself. You can generate\na personal access token for webdiff via github.com \u2192 profile \u2192 Settings \u2192\nPersonal access tokens. Make sure to grant all the \"repo\" privileges.\n\n## Configuration\n\nwebdiff can be configured via [`git config`][git config]. To change the syntax highlighting theme, for example:\n\n    git config webdiff.theme rainbow\n\n(You can find a list of supported themes in the [themes] directory.)\n\nAs with any git configuration setting, these can be set globally or per-repo.\n\nOptions are:\n\n| Setting        | Default       | Notes  |\n| -------------- | ------------- | ------ |\n| webdiff.theme  | googlecode    | Syntax highlighting theme (see [themes] directory). |\n| webdiff.port   | -1            | Port on which to serve webdiff. Default is random open port. This can be overridden with the `--port` command line flag or the `WEBDIFF_PORT` environment variable. |\n| webdiff.host   | localhost     | Host name on which to serve the webdiff UI. Use `0.0.0.0` to serve publicly. The special value `<hostname>` uses your computer's network name. This can be overridden with the `--host` command line flag or the `WEBDIFF_HOST` environment variable. |\n| webdiff.maxDiffWidth | 100 | Maximum length of lines in the diff display. After this width, lines will wrap. |\n| webdiff.unified | 8 | Lines of context to display by default (`git diff -U`) |\n| webdiff.extraDirDiffArgs | \"\" | Any extra arguments to pass to `git diff` when diffing directories. |\n| webdiff.extraFileDiffArgs | \"\" | Any extra arguments to pass to `git diff` when diffing files. |\n| webdiff.openBrowser | true | Whether to automatically open the browser UI when you run webdiff. |\n| webdiff.maxLinesForSyntax | 10000 | Maximum lines in file to do syntax highlighting. |\n| webdiff.colors.delete | #fee | CSS background color for delete (left) lines |\n| webdiff.colors.insert | #efe | CSS background color for insert (right) lines |\n| webdiff.colors.charDelete | #fcc | CSS background color for deleted characters in a delete (left) line |\n| webdiff.colors.charInsert | #cfc | CSS background color for inserted characters in an insert (right) line |\n\n## Development\n\n    poetry install\n    cd ts\n    yarn\n    # see https://github.com/webpack/webpack/issues/14532\n    NODE_OPTIONS=--openssl-legacy-provider webpack\n\nThen from the root directory:\n\n    poetry run webdiff/app.py testdata/dygraphsjs/{left,right}\n\nor to launch in debug mode:\n\n    ./test.sh $(pwd)/testdata/manyfiles/{left,right}\n\n(or any other directory in testdata)\n\nTo run the Python tests:\n\n    poetry run pytest\n\nTo format the code, run:\n\n    poetry run ruff format\n    cd ts\n    yarn prettier\n\nTo debug `git webdiff`, run:\n\n    ./test-gitwebdiff.sh\n\n## Publishing\n\nTo iterate on the PyPI package, run:\n\n    pip3 uninstall webdiff\n    poetry build\n    pip3 install dist/webdiff-?.?.?.tar.gz\n\nTo publish to pypitest:\n\n    poetry build\n    poetry publish -r testpypi\n\nAnd to the real pypi:\n\n    poetry publish\n\nSee [pypirc][] and [poetry][] docs for details on setting up tokens for pypi.\n\nPublication checklist. Do these from _outside_ the webdiff directory:\n\n- Run `webdiff webdiff/testdata/.../{left,right}`\n- Run `git webdiff 52aa15f^..52aa15f` in the codediff.js repo\n- Run `webdiff https://github.com/danvk/webdiff/pull/160`\n\n## Implementation notes\n\nwebdiff doesn't calculate any diffs itself. Instead, it relies on `git diff`. This is possible because `git diff` has a `--no-index` mode that allows it to operate outside of a git repository. Of course, this means that you need to have `git` installed to use webdiff!\n\nWhen you run `webdiff dir1 dir2`, webdiff runs:\n\n    git diff --raw --no-index dir1 dir2\n\nTo ask `git` which files are adds, removes, renames and changes. Then, when it's serving the web UI for a particular diff, it runs:\n\n    git diff --no-index (diff args) file1 file2\n\nThis produces a patch, which is what the web UI renders. (It also needs both full files for syntax highlighting.)\n\nWhen you run `git webdiff (args)`, it runs:\n\n    git difftool -d -x webdiff (args)\n\nThis tells `git` to set up two directories and invoke `webdiff leftdir rightdir`.\n\nThere's one complication involving symlinks. `git difftool -d` may fill one of the sides (typically the right) with symlinks. This is faster than copying files, but unfortunately `git diff --no-index` does not resolve these symlinks. To make this work, if a directory contains symlinks, webdiff makes a copy of it before diffing. For file diffs, it resolves the symlink before passing it to `git diff --no-index`. The upshot is that you can run `git webdiff`, edit a file, reload the browser window and see the changes.\n\n[pypirc]: https://packaging.python.org/specifications/pypirc/\n[Homebrew]: https://brew.sh/\n[ImageMagick]: https://imagemagick.org/index.php\n[git config]: https://git-scm.com/docs/git-config\n[themes]: http://example.com\n[poetry]: https://python-poetry.org/docs/repositories/#publishable-repositories\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Two-column web-based git difftool",
    "version": "1.1.1",
    "project_urls": {
        "Homepage": "https://github.com/danvk/webdiff/",
        "Repository": "https://github.com/danvk/webdiff/"
    },
    "split_keywords": [
        "git",
        " difftool",
        " web"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0eb136c4dcb58acee29ff66a6ef0aa3eface1cb231b660f74c2d2e1e6fc97270",
                "md5": "4b01becb76e4221bf9fc4b3921fef6b7",
                "sha256": "b35aa151b20973c244184669cfdd5799fca632b4b7564d42a1ee59bf2b60f5e5"
            },
            "downloads": -1,
            "filename": "webdiff-1.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "4b01becb76e4221bf9fc4b3921fef6b7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.10",
            "size": 1009751,
            "upload_time": "2024-06-07T17:24:10",
            "upload_time_iso_8601": "2024-06-07T17:24:10.340573Z",
            "url": "https://files.pythonhosted.org/packages/0e/b1/36c4dcb58acee29ff66a6ef0aa3eface1cb231b660f74c2d2e1e6fc97270/webdiff-1.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "dc6d0b8a1d209ed08c6fa704d517a423f1110b2fe7892cae8aab0b6144d4ade1",
                "md5": "9b61c9bda58c777125a301ac71ec4bda",
                "sha256": "9430660520a96661668e983844152a7fcd6f00dc27678d1a0f82c5a81a81017b"
            },
            "downloads": -1,
            "filename": "webdiff-1.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "9b61c9bda58c777125a301ac71ec4bda",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.10",
            "size": 851515,
            "upload_time": "2024-06-07T17:24:13",
            "upload_time_iso_8601": "2024-06-07T17:24:13.124736Z",
            "url": "https://files.pythonhosted.org/packages/dc/6d/0b8a1d209ed08c6fa704d517a423f1110b2fe7892cae8aab0b6144d4ade1/webdiff-1.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-06-07 17:24:13",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "danvk",
    "github_project": "webdiff",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "circle": true,
    "lcname": "webdiff"
}
        
Elapsed time: 0.25004s