From 8e206ea0c43ee8dda14be4e823c6df6a4167a10e Mon Sep 17 00:00:00 2001 From: David Tucker Date: Mon, 11 Aug 2025 21:26:46 -0700 Subject: [PATCH 01/14] Remove --interactive --- src/git_rebase_branches.py | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 8bdad56..a60b245 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -40,12 +40,6 @@ def cli(parser: Optional[argparse.ArgumentParser] = None) -> argparse.ArgumentPa nargs="+", help="the branches to rebase", ) - parser.add_argument( - "-i", - "--interactive", - action="store_true", - help="exit instead of aborting a failed rebase", - ) parser.add_argument( "--version", action="version", @@ -62,19 +56,6 @@ def main(argv: Optional[List[str]] = None) -> None: args = cli().parse_args(argv) # Stash any changes. - if ( - args.interactive - and run(["git", "diff-index", "--exit-code", "HEAD", "--"]).returncode - ): - try: - input( - "\n" - "There are local changes that need to be stashed or committed.\n" - "Press ^C to stop here or Enter to stash them and continue.\n" - ) - except KeyboardInterrupt: - print() - sys.exit(1) result = subprocess.run( ["git", "stash", "list"], capture_output=True, @@ -151,14 +132,6 @@ def print_report() -> int: run(["git", "rebase", args.base_ref], check=True) except subprocess.CalledProcessError: statuses[branch] = FAILURE_STATUS - if args.interactive: - try: - input("\nPress ^C to stop here or Enter to continue.\n") - except KeyboardInterrupt: - print() - failures = print_report() - run(["git", "status"], check=True) - sys.exit(failures) run(["git", "rebase", "--abort"], check=True) else: statuses[branch] = "succeeded" From 670a8f45343b9639b11997d874759ae948027018 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Mon, 11 Aug 2025 19:24:16 -0700 Subject: [PATCH 02/14] Break stash_changes out of main --- src/git_rebase_branches.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index a60b245..674bdfe 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -49,13 +49,8 @@ def cli(parser: Optional[argparse.ArgumentParser] = None) -> argparse.ArgumentPa return parser -def main(argv: Optional[List[str]] = None) -> None: - """Execute CLI commands.""" - if argv is None: - argv = sys.argv[1:] - args = cli().parse_args(argv) - - # Stash any changes. +def stash_changes() -> bool: + """Stash any local changes, and return whether changes were stashed.""" result = subprocess.run( ["git", "stash", "list"], capture_output=True, @@ -70,7 +65,17 @@ def main(argv: Optional[List[str]] = None) -> None: check=True, encoding="utf-8", ) - stashed_changes = len(result.stdout.splitlines()) - stashed_changes + return bool(len(result.stdout.splitlines()) - stashed_changes) + + +def main(argv: Optional[List[str]] = None) -> None: + """Execute CLI commands.""" + if argv is None: + argv = sys.argv[1:] + args = cli().parse_args(argv) + + # Stash any changes. + stashed_changes = stash_changes() # Note where we are so we can come back. result = subprocess.run( @@ -122,7 +127,7 @@ def print_report() -> int: if stashed_changes: print() - run(["git", "stash", "list", f"-n{stashed_changes}"], check=True) + run(["git", "stash", "list", "-n1"], check=True) return failures @@ -140,7 +145,7 @@ def print_report() -> int: run(["git", "-c", "advice.detachedHead=false", "checkout", start], check=True) if stashed_changes: run(["git", "stash", "pop"], check=True) - stashed_changes -= 1 + stashed_changes = False # Report what happened. failures = print_report() From 0de6b2478c7e02e7aad0dbbc28eea4d8acf6b2b9 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Mon, 11 Aug 2025 19:28:09 -0700 Subject: [PATCH 03/14] Break current_ref out of main --- src/git_rebase_branches.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 674bdfe..5e21e5c 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -68,32 +68,38 @@ def stash_changes() -> bool: return bool(len(result.stdout.splitlines()) - stashed_changes) -def main(argv: Optional[List[str]] = None) -> None: - """Execute CLI commands.""" - if argv is None: - argv = sys.argv[1:] - args = cli().parse_args(argv) - - # Stash any changes. - stashed_changes = stash_changes() - - # Note where we are so we can come back. +def current_ref() -> str: + """Get the current Git branch, commit, etc.""" + run(["git", "log", "-n1"], check=True) result = subprocess.run( ["git", "branch", "--show-current"], capture_output=True, check=True, encoding="utf-8", ) - start = result.stdout.strip() - if not start: + ref = result.stdout.strip() + if not ref: result = subprocess.run( ["git", "rev-parse", "HEAD"], capture_output=True, check=True, encoding="utf-8", ) - start = result.stdout.strip() - run(["git", "log", "-n1"], check=True) + ref = result.stdout.strip() + return ref + + +def main(argv: Optional[List[str]] = None) -> None: + """Execute CLI commands.""" + if argv is None: + argv = sys.argv[1:] + args = cli().parse_args(argv) + + # Stash any changes. + stashed_changes = stash_changes() + + # Note where we are so we can come back. + start = current_ref() # Get all the branches that need rebasing. if args.branches is None: From 1ab817225c339d5ea3cd5b1cff124c7cf5d7a87e Mon Sep 17 00:00:00 2001 From: David Tucker Date: Mon, 11 Aug 2025 19:59:10 -0700 Subject: [PATCH 04/14] Break branches_that_do_not_contain out of main --- src/git_rebase_branches.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 5e21e5c..87db192 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -49,6 +49,18 @@ def cli(parser: Optional[argparse.ArgumentParser] = None) -> argparse.ArgumentPa return parser +def branches_that_do_not_contain(ref: str, /) -> List[str]: + """Get a list of branches that do not contain a given ref.""" + result = run( + ["git", "branch", "--no-contains", ref, "--format=%(refname:short)"], + capture_output=True, + check=True, + encoding="utf-8", + ) + print(result.stdout, end="", flush=True) + return result.stdout.splitlines() + + def stash_changes() -> bool: """Stash any local changes, and return whether changes were stashed.""" result = subprocess.run( @@ -94,6 +106,8 @@ def main(argv: Optional[List[str]] = None) -> None: if argv is None: argv = sys.argv[1:] args = cli().parse_args(argv) + if args.branches is None: + args.branches = branches_that_do_not_contain(args.base_ref) # Stash any changes. stashed_changes = stash_changes() @@ -101,22 +115,6 @@ def main(argv: Optional[List[str]] = None) -> None: # Note where we are so we can come back. start = current_ref() - # Get all the branches that need rebasing. - if args.branches is None: - # Check out to the ref to ensure it won't show up in the next command. - run( - ["git", "-c", "advice.detachedHead=false", "checkout", args.base_ref], - check=True, - ) - result = run( - ["git", "branch", "--no-contains", "HEAD", "--format=%(refname:short)"], - capture_output=True, - check=True, - encoding="utf-8", - ) - print(result.stdout, end="", flush=True) - args.branches = result.stdout.splitlines() - # Rebase each branch. statuses: Dict[str, str] = {} From 96ecf6e62c8d6d716481594a737fe57d0ea5f7af Mon Sep 17 00:00:00 2001 From: David Tucker Date: Mon, 11 Aug 2025 20:22:18 -0700 Subject: [PATCH 05/14] Create original_state_preserved --- src/git_rebase_branches.py | 50 ++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 87db192..34c5889 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -9,8 +9,9 @@ import shlex import subprocess import sys +from contextlib import contextmanager from importlib.metadata import version -from typing import Any, Dict, List, Optional +from typing import Any, Dict, Iterator, List, Optional, Tuple FAILURE_STATUS = "failed" @@ -101,6 +102,18 @@ def current_ref() -> str: return ref +@contextmanager +def original_state_preserved() -> Iterator[Tuple[bool, str]]: + """Stash any local changes and note the current ref, then restore both.""" + stashed_changes = stash_changes() + og_ref = current_ref() + yield stashed_changes, og_ref + # Return to the original state. + run(["git", "-c", "advice.detachedHead=false", "checkout", og_ref], check=True) + if stashed_changes: + run(["git", "stash", "pop"], check=True) + + def main(argv: Optional[List[str]] = None) -> None: """Execute CLI commands.""" if argv is None: @@ -109,12 +122,6 @@ def main(argv: Optional[List[str]] = None) -> None: if args.branches is None: args.branches = branches_that_do_not_contain(args.base_ref) - # Stash any changes. - stashed_changes = stash_changes() - - # Note where we are so we can come back. - start = current_ref() - # Rebase each branch. statuses: Dict[str, str] = {} @@ -129,27 +136,18 @@ def print_report() -> int: failures += 1 print("-", branch, f"({status})") - if stashed_changes: - print() - run(["git", "stash", "list", "-n1"], check=True) - return failures - for branch in args.branches: - run(["git", "switch", branch], check=True) - try: - run(["git", "rebase", args.base_ref], check=True) - except subprocess.CalledProcessError: - statuses[branch] = FAILURE_STATUS - run(["git", "rebase", "--abort"], check=True) - else: - statuses[branch] = "succeeded" - - # Return to the original state. - run(["git", "-c", "advice.detachedHead=false", "checkout", start], check=True) - if stashed_changes: - run(["git", "stash", "pop"], check=True) - stashed_changes = False + with original_state_preserved(): + for branch in args.branches: + run(["git", "switch", branch], check=True) + try: + run(["git", "rebase", args.base_ref], check=True) + except subprocess.CalledProcessError: + statuses[branch] = FAILURE_STATUS + run(["git", "rebase", "--abort"], check=True) + else: + statuses[branch] = "succeeded" # Report what happened. failures = print_report() From 91a4feb7cd8428c25465fef76554ce0c57f12318 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Mon, 11 Aug 2025 20:26:30 -0700 Subject: [PATCH 06/14] Create changes_stashed --- src/git_rebase_branches.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 34c5889..2866a46 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -81,6 +81,17 @@ def stash_changes() -> bool: return bool(len(result.stdout.splitlines()) - stashed_changes) +@contextmanager +def changes_stashed() -> Iterator[bool]: + """Stash any local changes, then un-stash them.""" + stashed_changes = stash_changes() + try: + yield stashed_changes + finally: + if stashed_changes: + run(["git", "stash", "pop"], check=True) + + def current_ref() -> str: """Get the current Git branch, commit, etc.""" run(["git", "log", "-n1"], check=True) @@ -105,13 +116,10 @@ def current_ref() -> str: @contextmanager def original_state_preserved() -> Iterator[Tuple[bool, str]]: """Stash any local changes and note the current ref, then restore both.""" - stashed_changes = stash_changes() - og_ref = current_ref() - yield stashed_changes, og_ref - # Return to the original state. - run(["git", "-c", "advice.detachedHead=false", "checkout", og_ref], check=True) - if stashed_changes: - run(["git", "stash", "pop"], check=True) + with changes_stashed() as stashed_changes: + og_ref = current_ref() + yield stashed_changes, og_ref + run(["git", "-c", "advice.detachedHead=false", "checkout", og_ref], check=True) def main(argv: Optional[List[str]] = None) -> None: From f946cc6c0a1ff66e7c17ea8d4fa87236d57d08cc Mon Sep 17 00:00:00 2001 From: David Tucker Date: Mon, 11 Aug 2025 20:31:56 -0700 Subject: [PATCH 07/14] Create original_ref_preserved --- src/git_rebase_branches.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 2866a46..63c33d4 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -113,13 +113,22 @@ def current_ref() -> str: return ref +@contextmanager +def original_ref_preserved() -> Iterator[str]: + """Note the current ref, then restore it.""" + og_ref = current_ref() + try: + yield og_ref + finally: + run(["git", "-c", "advice.detachedHead=false", "checkout", og_ref], check=True) + + @contextmanager def original_state_preserved() -> Iterator[Tuple[bool, str]]: """Stash any local changes and note the current ref, then restore both.""" with changes_stashed() as stashed_changes: - og_ref = current_ref() - yield stashed_changes, og_ref - run(["git", "-c", "advice.detachedHead=false", "checkout", og_ref], check=True) + with original_ref_preserved() as og_ref: + yield stashed_changes, og_ref def main(argv: Optional[List[str]] = None) -> None: From 2c33f5a29bdd57424536925f4e36f2a8a60bc5f8 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Mon, 11 Aug 2025 21:12:59 -0700 Subject: [PATCH 08/14] Stop calling `git switch` explicitly --- src/git_rebase_branches.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 63c33d4..1631ff5 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -157,9 +157,8 @@ def print_report() -> int: with original_state_preserved(): for branch in args.branches: - run(["git", "switch", branch], check=True) try: - run(["git", "rebase", args.base_ref], check=True) + run(["git", "rebase", args.base_ref, branch], check=True) except subprocess.CalledProcessError: statuses[branch] = FAILURE_STATUS run(["git", "rebase", "--abort"], check=True) From 355382e1f45e9803aebceed227fc64662d4e459d Mon Sep 17 00:00:00 2001 From: David Tucker Date: Mon, 11 Aug 2025 22:18:11 -0700 Subject: [PATCH 09/14] Refactor print_report --- src/git_rebase_branches.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 1631ff5..f91f6c9 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -139,22 +139,9 @@ def main(argv: Optional[List[str]] = None) -> None: if args.branches is None: args.branches = branches_that_do_not_contain(args.base_ref) - # Rebase each branch. statuses: Dict[str, str] = {} - def print_report() -> int: - failures = 0 - for i, branch in enumerate(sorted(args.branches)): - if i == 0: - print() - print("=" * 36, "SUMMARY", "=" * 36) - status = statuses.get(branch, "not attempted") - if status == FAILURE_STATUS: - failures += 1 - print("-", branch, f"({status})") - - return failures - + # Rebase each branch. with original_state_preserved(): for branch in args.branches: try: @@ -166,8 +153,13 @@ def print_report() -> int: statuses[branch] = "succeeded" # Report what happened. - failures = print_report() - sys.exit(failures) + for i, branch in enumerate(args.branches): + if i == 0: + print() + print("=" * 36, "SUMMARY", "=" * 36) + print("-", branch, f"({statuses[branch]})") + + sys.exit(FAILURE_STATUS in statuses.values()) def run(command: List[str], **kwargs: Any) -> "subprocess.CompletedProcess[str]": From f8bf0e1b2bac1ef4d7b0e00203df342b6a46b1f3 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Tue, 12 Aug 2025 00:29:07 -0700 Subject: [PATCH 10/14] Use PEP 585 type hints --- src/git_rebase_branches.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index f91f6c9..2ef9bec 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -11,7 +11,7 @@ import sys from contextlib import contextmanager from importlib.metadata import version -from typing import Any, Dict, Iterator, List, Optional, Tuple +from typing import Any, Iterator, Optional FAILURE_STATUS = "failed" @@ -50,7 +50,7 @@ def cli(parser: Optional[argparse.ArgumentParser] = None) -> argparse.ArgumentPa return parser -def branches_that_do_not_contain(ref: str, /) -> List[str]: +def branches_that_do_not_contain(ref: str, /) -> list[str]: """Get a list of branches that do not contain a given ref.""" result = run( ["git", "branch", "--no-contains", ref, "--format=%(refname:short)"], @@ -124,14 +124,14 @@ def original_ref_preserved() -> Iterator[str]: @contextmanager -def original_state_preserved() -> Iterator[Tuple[bool, str]]: +def original_state_preserved() -> Iterator[tuple[bool, str]]: """Stash any local changes and note the current ref, then restore both.""" with changes_stashed() as stashed_changes: with original_ref_preserved() as og_ref: yield stashed_changes, og_ref -def main(argv: Optional[List[str]] = None) -> None: +def main(argv: Optional[list[str]] = None) -> None: """Execute CLI commands.""" if argv is None: argv = sys.argv[1:] @@ -139,7 +139,7 @@ def main(argv: Optional[List[str]] = None) -> None: if args.branches is None: args.branches = branches_that_do_not_contain(args.base_ref) - statuses: Dict[str, str] = {} + statuses: dict[str, str] = {} # Rebase each branch. with original_state_preserved(): @@ -162,7 +162,7 @@ def main(argv: Optional[List[str]] = None) -> None: sys.exit(FAILURE_STATUS in statuses.values()) -def run(command: List[str], **kwargs: Any) -> "subprocess.CompletedProcess[str]": +def run(command: list[str], **kwargs: Any) -> "subprocess.CompletedProcess[str]": """Print a command before running it.""" print("$", shlex.join(str(token) for token in command), flush=True) return subprocess.run(command, **kwargs) From fe746feb28e7523bcc79dea709bdcc6be28d4f9b Mon Sep 17 00:00:00 2001 From: David Tucker Date: Tue, 12 Aug 2025 00:40:33 -0700 Subject: [PATCH 11/14] Resolve pylint W1510 --- src/git_rebase_branches.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 2ef9bec..6749c19 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -165,7 +165,7 @@ def main(argv: Optional[list[str]] = None) -> None: def run(command: list[str], **kwargs: Any) -> "subprocess.CompletedProcess[str]": """Print a command before running it.""" print("$", shlex.join(str(token) for token in command), flush=True) - return subprocess.run(command, **kwargs) + return subprocess.run(command, check=kwargs.pop("check", True), **kwargs) if __name__ == "__main__": From 5d6bbbe6c01fd264343c44526a535fccba29889b Mon Sep 17 00:00:00 2001 From: David Tucker Date: Tue, 12 Aug 2025 01:16:28 -0700 Subject: [PATCH 12/14] Break ref_commit out of current_ref --- src/git_rebase_branches.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/git_rebase_branches.py b/src/git_rebase_branches.py index 6749c19..e7d42c0 100755 --- a/src/git_rebase_branches.py +++ b/src/git_rebase_branches.py @@ -92,6 +92,17 @@ def changes_stashed() -> Iterator[bool]: run(["git", "stash", "pop"], check=True) +def ref_commit(ref: str, /) -> str: + """Get the commit for a given ref.""" + result = subprocess.run( + ["git", "rev-parse", ref], + capture_output=True, + check=True, + encoding="utf-8", + ) + return result.stdout.strip() + + def current_ref() -> str: """Get the current Git branch, commit, etc.""" run(["git", "log", "-n1"], check=True) @@ -101,16 +112,7 @@ def current_ref() -> str: check=True, encoding="utf-8", ) - ref = result.stdout.strip() - if not ref: - result = subprocess.run( - ["git", "rev-parse", "HEAD"], - capture_output=True, - check=True, - encoding="utf-8", - ) - ref = result.stdout.strip() - return ref + return result.stdout.strip() or ref_commit("HEAD") @contextmanager From e7e019a9d5a486f853d1768d206f2ce5f4768368 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Tue, 12 Aug 2025 01:58:54 -0700 Subject: [PATCH 13/14] Create test_git_rebase_branches --- tests/test_git_rebase_branches.py | 57 +++++++++++++++++++++++++++++++ tox.ini | 2 +- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/tests/test_git_rebase_branches.py b/tests/test_git_rebase_branches.py index 9b05bca..734801d 100644 --- a/tests/test_git_rebase_branches.py +++ b/tests/test_git_rebase_branches.py @@ -1,5 +1,7 @@ """Test git_rebase_branches.""" +import subprocess + import pytest import git_rebase_branches @@ -10,3 +12,58 @@ def test_main_version(): with pytest.raises(SystemExit) as excinfo: git_rebase_branches.main(["--version"]) assert excinfo.value.code == 0 + + +def branch_commit(): + """Get a mapping of branches to commits.""" + result = subprocess.run( + [ + "git", + "for-each-ref", + "--format=%(refname:short) %(objectname)", + "refs/heads", + ], + capture_output=True, + check=True, + encoding="utf-8", + ) + return { + branch: commit + for line in result.stdout.splitlines() + for branch, _, commit in [line.partition(" ")] + } + + +def test_git_rebase_branches(tmp_path, monkeypatch): + """Test a basic example.""" + base_ref = "main" + branch_no_contains = "init" + branch_contains = "latest" + + monkeypatch.chdir(tmp_path) + commit_opts = ["--allow-empty"] + for git_command in [ + ["init", "-b", base_ref], + ["config", "commit.gpgsign", "false"], + ["config", "user.name", "Coder Joe"], + ["config", "user.email", "Coder@Joe.com"], + ["commit"] + commit_opts + ["-m", "Initial Commit"], + ["branch", branch_no_contains], + ["commit"] + commit_opts + ["-m", "New Commit on main"], + ["branch", branch_contains], + ]: + subprocess.run(["git"] + git_command, check=True) + + head = git_rebase_branches.ref_commit("HEAD") + target_state = { + base_ref: head, + branch_no_contains: head, + branch_contains: head, + } + assert branch_commit() != target_state + + with pytest.raises(SystemExit) as excinfo: + git_rebase_branches.main([base_ref]) + assert excinfo.value.code == 0 + + assert branch_commit() == target_state diff --git a/tox.ini b/tox.ini index 211c0d8..8d7c913 100644 --- a/tox.ini +++ b/tox.ini @@ -25,7 +25,7 @@ deps = pytest-randomly ~= 3.16.0 pytest-xdist ~= 3.8.0 commands = - pytest --cov git_rebase_branches --cov-branch --cov-fail-under 20 --cov-report term-missing {posargs:-n auto} + pytest --cov git_rebase_branches --cov-branch --cov-fail-under 80 --cov-report term-missing {posargs:-n auto} [pytest] testpaths = tests From 448736d26322e915b68962f24627e5651bdf0f76 Mon Sep 17 00:00:00 2001 From: David Tucker Date: Tue, 12 Aug 2025 02:13:15 -0700 Subject: [PATCH 14/14] Use an SPDX expression for the license --- pyproject.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 54754f2..8e18903 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,11 +2,11 @@ name = "git-rebase-branches" description = "Rebase multiple branches at once" readme = "README.md" +license = "LGPL-2.0-or-later" requires-python = ">= 3.9" classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: End Users/Desktop", - "License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)", ] dynamic = ["version"] dependencies = [ @@ -16,9 +16,6 @@ dependencies = [ name = "David Tucker" email = "david@tucker.name" -[project.license] -file = "LICENSE.txt" - [project.scripts] git-rebase-branches = "git_rebase_branches:main"