Skip to content

Commit e670239

Browse files
authored
Improve merge widgets (#1031)
* Improve merge widgets * Fix get base content * Improve style of conflicted files * Improve styles for merge raw file * Pass translator to diff widget * Improve style for notebook merge * Hide drag handles * Clean revert button styles * Move checkboxes in toolbar * Fix collapse unchanged cells in merge view * Fix unit tests * Display unmerged files separately in simple mode * Add test for content base * Less setup info duplication * Update class name * [skip ci] Remove commented line
1 parent b4590f8 commit e670239

25 files changed

+552
-165
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
run: |
6565
jlpm
6666
jlpm run eslint:check
67-
python -m pip install -e .[dev,tests]
67+
python -m pip install -e .[tests]
6868
6969
# Python formatting checks
7070
black . --check
@@ -82,8 +82,6 @@ jobs:
8282
8383
jupyter labextension list 2>&1 | grep -ie "@jupyterlab/git.*OK"
8484
python -m jupyterlab.browser_check
85-
# Run our extension-specific browser integration test
86-
# python tests/test-browser/run_browser_test.py
8785
8886
- uses: actions/upload-artifact@v2
8987
if: matrix.python-version == '3.9'

.github/workflows/publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ jobs:
2222
- name: Install dependencies
2323
run: |
2424
python -m pip install --upgrade pip
25-
pip install jupyter_packaging~=0.7.9 jupyterlab~=3.0 packaging setuptools twine wheel
25+
pip install jupyter_packaging~=0.7.9 jupyterlab~=3.0 packaging setuptools twine build
2626
- name: Publish the Python package
2727
env:
2828
TWINE_USERNAME: __token__
2929
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
3030
run: |
31-
python setup.py sdist bdist_wheel
31+
python -m build
3232
twine upload dist/*
3333
- name: Publish the NPM package
3434
run: |

jupyterlab_git/git.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import pexpect
1515
import tornado
1616
import tornado.locks
17-
from nbdime import diff_notebooks, merge_notebooks
1817
from jupyter_server.utils import ensure_async
18+
from nbdime import diff_notebooks, merge_notebooks
1919

2020
from .log import get_logger
2121

@@ -1219,11 +1219,41 @@ async def _get_tag(self, path, commit_sha):
12191219
)
12201220
)
12211221

1222-
async def show(self, filename, ref, path):
1222+
async def _get_base_ref(self, path, filename):
1223+
"""Get the object reference for an unmerged ``filename`` at base stage.
1224+
1225+
Execute git ls-files -u -z <filename>
1226+
1227+
Returns:
1228+
The object reference or None
1229+
"""
1230+
command = ["git", "ls-files", "-u", "-z", filename]
1231+
1232+
code, output, error = await execute(command, cwd=path)
1233+
if code != 0:
1234+
raise subprocess.CalledProcessError(
1235+
code, " ".join(command), output=output, stderr=error
1236+
)
1237+
1238+
split_line = strip_and_split(output)[0].split()
1239+
1240+
return split_line[1] if len(split_line) > 1 else None
1241+
1242+
async def show(self, path, ref, filename=None):
12231243
"""
1224-
Execute git show <ref:filename> command & return the result.
1244+
Execute
1245+
git show <ref:filename>
1246+
Or
1247+
git show <ref>
1248+
1249+
Return the file content
12251250
"""
1226-
command = ["git", "show", "{}:{}".format(ref, filename)]
1251+
command = ["git", "show"]
1252+
1253+
if filename is None:
1254+
command.append(ref)
1255+
else:
1256+
command.append(f"{ref}:{filename}")
12271257

12281258
code, output, error = await execute(command, cwd=path)
12291259

@@ -1286,7 +1316,11 @@ async def get_content_at_reference(
12861316
log_message="Error occurred while executing command to retrieve plaintext content as file is not UTF-8."
12871317
)
12881318

1289-
content = await self.show(filename, "", path)
1319+
content = await self.show(path, "", filename)
1320+
elif reference["special"] == "BASE":
1321+
# Special case of file in merge conflict for which we want the base (aka common ancestor) version
1322+
ref = await self._get_base_ref(path, filename)
1323+
content = await self.show(path, ref)
12901324
else:
12911325
raise tornado.web.HTTPError(
12921326
log_message="Error while retrieving plaintext content, unknown special ref '{}'.".format(
@@ -1300,7 +1334,7 @@ async def get_content_at_reference(
13001334
log_message="Error occurred while executing command to retrieve plaintext content as file is not UTF-8."
13011335
)
13021336

1303-
content = await self.show(filename, reference["git"], path)
1337+
content = await self.show(path, reference["git"], filename)
13041338
else:
13051339
content = ""
13061340

jupyterlab_git/tests/test_handlers.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,50 @@ async def test_content_index(mock_execute, jp_fetch, jp_root_dir):
723723
)
724724

725725

726+
@patch("jupyterlab_git.git.execute")
727+
async def test_content_base(mock_execute, jp_fetch, jp_root_dir):
728+
# Given
729+
local_path = jp_root_dir / "test_path"
730+
filename = "my/file"
731+
content = "dummy content file\nwith multiple lines"
732+
obj_ref = "915bb14609daab65e5304e59d89c626283ae49fc"
733+
734+
mock_execute.side_effect = [
735+
maybe_future(
736+
(
737+
0,
738+
"100644 {1} 1 {0}\x00100644 285bdbc14e499b85ec407512a3bb3992fa3d4082 2 {0}\x00100644 66ac842dfb0b5c20f757111d6b3edd56d80622b4 3 {0}\x00".format(
739+
filename, obj_ref
740+
),
741+
"",
742+
)
743+
),
744+
maybe_future((0, content, "")),
745+
]
746+
747+
# When
748+
body = {
749+
"filename": filename,
750+
"reference": {"special": "BASE"},
751+
}
752+
response = await jp_fetch(
753+
NAMESPACE, local_path.name, "content", body=json.dumps(body), method="POST"
754+
)
755+
756+
# Then
757+
assert response.code == 200
758+
payload = json.loads(response.body)
759+
assert payload["content"] == content
760+
mock_execute.assert_has_calls(
761+
[
762+
call(
763+
["git", "show", obj_ref],
764+
cwd=str(local_path),
765+
),
766+
],
767+
)
768+
769+
726770
@patch("jupyterlab_git.git.execute")
727771
async def test_content_unknown_special(mock_execute, jp_fetch, jp_root_dir):
728772
# Given

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
"license": "BSD-3-Clause",
99
"author": "Jupyter Development Team",
1010
"keywords": [
11-
"jupyter",
12-
"jupyterlab",
13-
"jupyterlab-extension"
11+
"Jupyter",
12+
"JupyterLab",
13+
"JupyterLab3",
14+
"jupyterlab-extension",
15+
"Git"
1416
],
1517
"scripts": {
1618
"build": "jlpm run build:lib && jlpm run build:labextension:dev",

setup.cfg

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
[metadata]
2+
long_description = file: README.md
3+
long_description_content_type = text/markdown
4+
platforms = Linux, Mac OS X, Windows
5+
classifiers =
6+
Intended Audience :: Developers
7+
Intended Audience :: Science/Research
8+
License :: OSI Approved :: BSD License
9+
Programming Language :: Python
10+
Programming Language :: Python :: 3
11+
Programming Language :: Python :: 3.6
12+
Programming Language :: Python :: 3.7
13+
Programming Language :: Python :: 3.8
14+
Programming Language :: Python :: 3.9
15+
Framework :: Jupyter
16+
Framework :: Jupyter :: JupyterLab
17+
Framework :: Jupyter :: JupyterLab :: 3
18+
Framework :: Jupyter :: JupyterLab :: Extensions
19+
Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
20+
21+
[options]
22+
packages = find:
23+
install_requires =
24+
jupyter_server
25+
nbdime~=3.1
26+
nbformat
27+
packaging
28+
pexpect
29+
include_package_data = True
30+
zip_safe = False
31+
python_requires = >=3.6,<4
32+
33+
[options.extras_require]
34+
dev=
35+
black
36+
coverage
37+
jupyter_packaging~=0.7.9
38+
jupyterlab~=3.0
39+
pre-commit
40+
pytest
41+
pytest-asyncio
42+
pytest-cov
43+
pytest-tornasync
44+
tests=
45+
%(dev)s
46+
hybridcontents
47+

setup.py

Lines changed: 8 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
# The name of the project
2020
name = "jupyterlab_git"
2121

22-
# Get our version
2322
with (HERE / "package.json").open() as f:
24-
version = str(parse(json.load(f)["version"]))
23+
npm_data = json.load(f)
24+
# Get the version
25+
version = str(parse(npm_data["version"]))
2526

2627
lab_path = HERE / name / "labextension"
2728

@@ -64,61 +65,15 @@
6465
else:
6566
cmdclass["jsdeps"] = skip_if_exists(jstargets, js_command)
6667

67-
long_description = (HERE / "README.md").read_text(errors="ignore")
68-
6968
setup_args = dict(
7069
name=name,
7170
version=version,
72-
url="https://github.com/jupyterlab/jupyterlab-git.git",
73-
author="Jupyter Development Team",
74-
description="A JupyterLab extension for version control using git",
75-
long_description=long_description,
76-
long_description_content_type="text/markdown",
71+
url=npm_data["homepage"],
72+
author=npm_data["author"],
73+
description=npm_data["description"],
7774
cmdclass=cmdclass,
78-
packages=setuptools.find_packages(),
79-
install_requires=[
80-
"jupyter_server",
81-
"nbdime~=3.1",
82-
"nbformat",
83-
"packaging",
84-
"pexpect",
85-
],
86-
zip_safe=False,
87-
include_package_data=True,
88-
python_requires=">=3.6,<4",
89-
license="BSD-3-Clause",
90-
platforms="Linux, Mac OS X, Windows",
91-
keywords=["Jupyter", "JupyterLab", "JupyterLab3", "Git"],
92-
classifiers=[
93-
"Intended Audience :: Developers",
94-
"Intended Audience :: Science/Research",
95-
"License :: OSI Approved :: BSD License",
96-
"Programming Language :: Python",
97-
"Programming Language :: Python :: 3",
98-
"Programming Language :: Python :: 3.6",
99-
"Programming Language :: Python :: 3.7",
100-
"Programming Language :: Python :: 3.8",
101-
"Programming Language :: Python :: 3.9",
102-
"Framework :: Jupyter",
103-
"Framework :: Jupyter :: JupyterLab",
104-
"Framework :: Jupyter :: JupyterLab :: 3",
105-
"Framework :: Jupyter :: JupyterLab :: Extensions",
106-
"Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt",
107-
],
108-
extras_require={
109-
"dev": [
110-
"black",
111-
"coverage",
112-
"jupyter_packaging~=0.7.9",
113-
"jupyterlab~=3.0",
114-
"pre-commit",
115-
"pytest",
116-
"pytest-asyncio",
117-
"pytest-cov",
118-
"pytest-tornasync",
119-
],
120-
"tests": ["hybridcontents"],
121-
},
75+
license=npm_data["license"],
76+
keywords=npm_data["keywords"],
12277
)
12378

12479

0 commit comments

Comments
 (0)