Skip to content

Commit

Permalink
feat(vcs): enable proactive git authentication
Browse files Browse the repository at this point in the history
This makes Git use provided authetication even if the server doesn't ask
for that. This fixes issues with some servers such as Azure DevOps.

Requires Git 2.46 or newer.
  • Loading branch information
nijel committed Feb 27, 2025
1 parent 0a1ee21 commit 688bf58
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
7 changes: 2 additions & 5 deletions ci/apt-install
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,12 @@ chown -R 1000:1000 /run/user/1000
install -d /usr/share/postgresql-common/pgdg
curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
curl -o /etc/apt/keyrings/git-core.launchpad.net.asc --fail 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xe363c90f8f1b6217'
echo "deb [signed-by=/etc/apt/keyrings/git-core.launchpad.net.asc] https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/git.list

# Update package lists
apt-get update

# Remove non-installable git packages. There git-svn can not be installed
# because the image contains newer versions which do not have matching git-svn
# in enabled repositories.
apt-get purge git git-man

# Install dependencies
apt-get install -y \
gettext \
Expand Down
38 changes: 30 additions & 8 deletions weblate/vcs/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,37 @@ def check_config(self) -> None:
self.config_update(("push", "default", "current"))

@staticmethod
def get_depth():
def get_depth() -> Iterator[str]:
if settings.VCS_CLONE_DEPTH:
return ["--depth", str(settings.VCS_CLONE_DEPTH)]
yield "--depth"
yield str(settings.VCS_CLONE_DEPTH)

@staticmethod
def _get_auth_args(repo: str) -> Iterator[str]:
if repo.startswith("http") and "@" in repo:
# proactive HTTP authentication, needs Git 2.46
yield "-c"
yield "http.proactiveAuth=auto"

def get_auth_args(self) -> list[str]:
if self.component:
return list(self._get_auth_args(self.component.repo))
return []

@classmethod
def _clone(cls, source: str, target: str, branch: str) -> None:
"""Clone repository."""
cls._popen(
["clone", *cls.get_depth(), "--branch", branch, "--", source, target]
[
*cls._get_auth_args(source),
"clone",
*cls.get_depth(),
"--branch",
branch,
"--",
source,
target,
]
)

def get_config(self, path):
Expand Down Expand Up @@ -534,18 +555,19 @@ def list_remote_branches(self):

def update_remote(self) -> None:
"""Update remote repository."""
self.execute(["remote", "prune", "origin"])
auth_args = self.get_auth_args()
self.execute([*auth_args, "remote", "prune", "origin"])
if self.list_remote_branches():
# Updating existing fork
self.execute(["fetch", "origin"])
self.execute([*auth_args, "fetch", "origin"])
else:
# Doing initial fetch
try:
self.execute(["fetch", "origin", *self.get_depth()])
self.execute([*auth_args, "fetch", "origin", *self.get_depth()])
except RepositoryError as error:
if error.retcode == 1 and not error.args[0]:
# Fetch with --depth fails on blank repo
self.execute(["fetch", "origin"])
self.execute([*auth_args, "fetch", "origin"])
else:
raise

Expand All @@ -557,7 +579,7 @@ def push(self, branch) -> None:
self.execute([*self._cmd_push, "origin", refspec])

def unshallow(self) -> None:
self.execute(["fetch", "--unshallow"])
self.execute([*self.get_auth_args(), "fetch", "--unshallow"])

def parse_changed_files(self, lines: list[str]) -> Iterator[str]:
"""Parse output with changed files."""
Expand Down

0 comments on commit 688bf58

Please sign in to comment.