From 4966a6604e2f2eac9686d19616404750d27b6c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Thu, 30 Jul 2020 18:00:48 +0200 Subject: [PATCH] Set receive.denyDeleteCurrent=ignore for old and newly created repositories By default, git disallows removing the current default branch, with a large error notice like this: -- >8 -- remote: error: By default, deleting the current branch is denied, because the next remote: 'git clone' won't result in any file checked out, causing confusion. remote: remote: You can set 'receive.denyDeleteCurrent' configuration variable to remote: 'warn' or 'ignore' in the remote repository to allow deleting the remote: current branch, with or without a warning message. remote: remote: To squelch this message, you can set it to 'refuse'. -- >8 -- However, we handle this ourselves in the post-update hook, and will only let the default branch dangle if there are no branches (the repository is empty), which is equivalent to the "fresh repository" state. This also means that *all current repositories need to be migrated* to the new config to be able to take advantage of the new semantics. --- gitsrht-shell/main.go | 5 +++ ...285bb23e2_allow_deleting_default_branch.py | 42 +++++++++++++++++++ gitsrht/repos.py | 5 +++ 3 files changed, 52 insertions(+) create mode 100644 gitsrht/alembic/versions/3c1285bb23e2_allow_deleting_default_branch.py diff --git a/gitsrht-shell/main.go b/gitsrht-shell/main.go index 967b9c1..c29dc89 100644 --- a/gitsrht-shell/main.go +++ b/gitsrht-shell/main.go @@ -299,6 +299,11 @@ func main() { notFound("git init", err) } + if err = exec.Command("git", "-C", path, "config", + "receive.denyDeleteCurrent", "ignore").Run(); err != nil { + + notFound("git config", err) + } if err = exec.Command("ln", "-s", postUpdate, gopath.Join(path, "hooks", "update")).Run(); err != nil { diff --git a/gitsrht/alembic/versions/3c1285bb23e2_allow_deleting_default_branch.py b/gitsrht/alembic/versions/3c1285bb23e2_allow_deleting_default_branch.py new file mode 100644 index 0000000..bdfd3dc --- /dev/null +++ b/gitsrht/alembic/versions/3c1285bb23e2_allow_deleting_default_branch.py @@ -0,0 +1,42 @@ +"""Allow deleting default branch + +Revision ID: 3c1285bb23e2 +Revises: 163fc2d2a2ea +Create Date: 2020-07-28 12:04:39.751225 + +""" + +# revision identifiers, used by Alembic. +revision = '3c1285bb23e2' +down_revision = '163fc2d2a2ea' + +import subprocess +from alembic import op +from sqlalchemy.orm import sessionmaker +from gitsrht.types import Repository +try: + from tqdm import tqdm +except ImportError: + def tqdm(iterable): + yield from iterable + +Session = sessionmaker() + + +def upgrade(): + bind = op.get_bind() + session = Session(bind=bind) + print("Setting receive.denyDeleteCurrent=ignore") + for repo in tqdm(session.query(Repository).all()): + subprocess.run(["git", "config", "receive.denyDeleteCurrent", "ignore"], + check=True, cwd=repo.path, + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + +def downgrade(): + bind = op.get_bind() + session = Session(bind=bind) + for repo in tqdm(session.query(Repository).all()): + subprocess.run(["git", "config", "--unset", "receive.denyDeleteCurrent"], + check=True, cwd=repo.path, + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) diff --git a/gitsrht/repos.py b/gitsrht/repos.py index 1bf7b40..2ab6e46 100644 --- a/gitsrht/repos.py +++ b/gitsrht/repos.py @@ -90,6 +90,11 @@ class GitRepoApi(SimpleRepoApi): stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.run(["git", "config", "srht.repo-id", str(repo.id)], check=True, cwd=repo.path, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + # We handle this ourselves in the post-update hook, and git's + # default behaviour is to print a large notice and reject the push entirely + subprocess.run(["git", "config", "receive.denyDeleteCurrent", "ignore"], + check=True, cwd=repo.path, + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.run(["ln", "-s", post_update, os.path.join(repo.path, "hooks", "pre-receive") -- 2.38.4