The python wrapper for the GitLab REST and GraphQL APIs.
—
Git repository operations, branch management, commit handling, file operations, and version control workflows. Comprehensive coverage of repository-level operations including files, branches, tags, commits, and repository configuration.
class ProjectFile(SaveMixin, ObjectDeleteMixin, RESTObject):
"""
Repository file object with content management.
Key Attributes:
- file_name: File name
- file_path: Full file path
- size: File size in bytes
- encoding: File encoding
- content: File content (base64 encoded for binary files)
- content_sha256: Content SHA256 hash
- ref: Git reference
- blob_id: Git blob ID
- commit_id: Last commit ID
- last_commit_id: Last commit affecting this file
"""
def save(self) -> None:
"""Save file changes (commit to repository)."""
def delete(self) -> None:
"""Delete file from repository."""
def decode(self) -> bytes:
"""Decode file content from base64."""
class ProjectFileManager(GetWithoutIdMixin[ProjectFile], CreateMixin[ProjectFile], UpdateMixin[ProjectFile], DeleteMixin[ProjectFile]):
"""Manager for repository files."""
def get(
self,
file_path: str,
ref: str = "main",
**kwargs
) -> ProjectFile:
"""
Get file content.
Parameters:
- file_path: Path to file in repository
- ref: Git reference (branch, tag, commit)
Returns:
ProjectFile object with content
"""
def create(self, data: dict, **kwargs) -> ProjectFile:
"""
Create new file.
Required fields:
- file_path: File path in repository
- branch: Target branch
- content: File content
- commit_message: Commit message
Optional fields:
- author_email: Author email
- author_name: Author name
- encoding: Content encoding ("text" or "base64")
- execute_filemode: Executable file mode
- start_branch: Start branch for new branch creation
"""
def update(self, file_path: str, data: dict, **kwargs) -> ProjectFile:
"""
Update existing file.
Parameters:
- file_path: File path in repository
- data: Update data
Required fields in data:
- branch: Target branch
- content: New file content
- commit_message: Commit message
Optional fields:
- author_email: Author email
- author_name: Author name
- encoding: Content encoding
- last_commit_id: Last known commit ID (for conflict detection)
- start_branch: Start branch for new branch creation
"""
def delete(self, file_path: str, data: dict, **kwargs) -> None:
"""
Delete file.
Parameters:
- file_path: File path to delete
- data: Deletion data
Required fields:
- branch: Target branch
- commit_message: Commit message
Optional fields:
- author_email: Author email
- author_name: Author name
- start_branch: Start branch for new branch creation
"""
def raw(self, file_path: str, ref: str = "main", **kwargs) -> bytes:
"""
Get raw file content.
Parameters:
- file_path: File path in repository
- ref: Git reference
Returns:
Raw file content as bytes
"""
def blame(self, file_path: str, ref: str = "main", **kwargs) -> list[dict]:
"""
Get file blame information.
Parameters:
- file_path: File path in repository
- ref: Git reference
Returns:
List of blame information for each line
"""class ProjectBranch(ObjectDeleteMixin, RESTObject):
"""
Git branch object with protection and merge capabilities.
Key Attributes:
- name: Branch name
- merged: Merged status
- protected: Protected status
- default: Default branch flag
- developers_can_push: Developer push permission
- developers_can_merge: Developer merge permission
- can_push: Current user can push
- web_url: Branch web URL
- commit: Latest commit information
"""
def delete(self) -> None:
"""Delete branch."""
def protect(
self,
push_access_level: int = 40,
merge_access_level: int = 40,
unprotect_access_level: int = 40,
**kwargs
) -> dict:
"""
Protect branch.
Parameters:
- push_access_level: Push access level (30=Developer, 40=Maintainer)
- merge_access_level: Merge access level
- unprotect_access_level: Unprotect access level
Optional parameters:
- code_owner_approval_required: Require code owner approval
- allow_force_push: Allow force push
- allowed_to_push: List of users/groups allowed to push
- allowed_to_merge: List of users/groups allowed to merge
- allowed_to_unprotect: List of users/groups allowed to unprotect
Returns:
Dictionary with protection result
Raises:
GitlabProtectError: If protection fails
"""
def unprotect(self) -> dict:
"""
Unprotect branch.
Returns:
Dictionary with unprotection result
Raises:
GitlabProtectError: If unprotection fails
"""
class ProjectBranchManager(ListMixin[ProjectBranch], CreateMixin[ProjectBranch], DeleteMixin[ProjectBranch]):
"""Manager for project branches."""
def list(
self,
search: str | None = None,
regex: str | None = None,
**kwargs
) -> list[ProjectBranch]:
"""
List repository branches.
Parameters:
- search: Search pattern for branch names
- regex: Regex pattern for branch names
Returns:
List of ProjectBranch objects
"""
def create(self, data: dict, **kwargs) -> ProjectBranch:
"""
Create new branch.
Required fields:
- branch: New branch name
- ref: Source reference (branch, tag, commit)
Returns:
New ProjectBranch object
"""
class ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):
"""
Protected branch configuration object.
Attributes:
- id: Protection rule ID
- name: Branch name pattern
- push_access_levels: Push access level rules
- merge_access_levels: Merge access level rules
- unprotect_access_levels: Unprotect access level rules
- code_owner_approval_required: Code owner approval requirement
- inherited: Inherited protection flag
- allow_force_push: Force push permission
"""
def delete(self) -> None:
"""Remove branch protection."""
class ProjectProtectedBranchManager(ListMixin[ProjectProtectedBranch], CreateMixin[ProjectProtectedBranch], DeleteMixin[ProjectProtectedBranch]):
"""Manager for protected branches."""class ProjectTag(ObjectDeleteMixin, RESTObject):
"""
Git tag object with release information.
Key Attributes:
- name: Tag name
- message: Tag message
- target: Target commit SHA
- commit: Commit information
- release: Release information
- protected: Protected status
"""
def delete(self) -> None:
"""Delete tag."""
def set_release_description(self, description: str) -> dict:
"""
Set or update release description for tag.
Parameters:
- description: Release description
Returns:
Dictionary with release information
"""
class ProjectTagManager(ListMixin[ProjectTag], CreateMixin[ProjectTag], DeleteMixin[ProjectTag]):
"""Manager for project tags."""
def create(self, data: dict, **kwargs) -> ProjectTag:
"""
Create new tag.
Required fields:
- tag_name: Tag name
- ref: Source reference (branch, tag, commit)
Optional fields:
- message: Tag message
- release_description: Release description
Returns:
New ProjectTag object
"""
class ProjectProtectedTag(ObjectDeleteMixin, RESTObject):
"""Protected tag configuration."""
class ProjectProtectedTagManager(ListMixin[ProjectProtectedTag], CreateMixin[ProjectProtectedTag], DeleteMixin[ProjectProtectedTag]):
"""Manager for protected tags."""class ProjectCommit(RESTObject):
"""
Git commit object with comprehensive information.
Key Attributes:
- id: Commit SHA
- short_id: Short commit SHA
- title: Commit title (first line of message)
- message: Full commit message
- author_name: Author name
- author_email: Author email
- authored_date: Author date
- committer_name: Committer name
- committer_email: Committer email
- committed_date: Commit date
- created_at: Creation timestamp
- parent_ids: Parent commit SHAs
- stats: Commit statistics (additions, deletions, total)
- status: Commit status
- last_pipeline: Last pipeline information
- web_url: Commit web URL
"""
def diff(self, **kwargs) -> list[dict]:
"""
Get commit diff.
Returns:
List of file diffs
"""
def comments(self, **kwargs) -> list[dict]:
"""Get commit comments."""
def comment(self, note: str, **kwargs) -> dict:
"""
Add comment to commit.
Parameters:
- note: Comment text
Optional parameters:
- path: File path for inline comment
- line: Line number for inline comment
- line_type: Line type ("new" or "old")
Returns:
Dictionary with comment information
"""
def cherry_pick(self, branch: str, **kwargs) -> dict:
"""
Cherry-pick commit to another branch.
Parameters:
- branch: Target branch name
Returns:
Dictionary with cherry-pick result
Raises:
GitlabCherryPickError: If cherry-pick fails
"""
def revert(self, branch: str, **kwargs) -> dict:
"""
Revert commit on specified branch.
Parameters:
- branch: Target branch name
Returns:
Dictionary with revert result
Raises:
GitlabRevertError: If revert fails
"""
class ProjectCommitManager(ListMixin[ProjectCommit], RetrieveMixin[ProjectCommit]):
"""Manager for project commits."""
def list(
self,
ref_name: str | None = None,
since: str | None = None,
until: str | None = None,
path: str | None = None,
author: str | None = None,
all: bool | None = None,
with_stats: bool | None = None,
first_parent: bool | None = None,
order: str | None = None,
trailers: bool | None = None,
**kwargs
) -> list[ProjectCommit]:
"""
List repository commits.
Parameters:
- ref_name: Branch or tag name
- since: Start date (ISO format)
- until: End date (ISO format)
- path: File path filter
- author: Author filter
- all: Include all branches
- with_stats: Include commit statistics
- first_parent: Only first parent commits
- order: Commit order ("default" or "topo")
- trailers: Include Git trailers
Returns:
List of ProjectCommit objects
"""# Repository mixin provides repository-level operations
class RepositoryMixin:
"""Mixin providing repository operations."""
def repository_tree(
self,
path: str = "",
ref: str = "main",
recursive: bool = False,
get_all: bool = False,
**kwargs
) -> list[dict]:
"""
Get repository file tree.
Parameters:
- path: Directory path
- ref: Git reference
- recursive: Recursive listing
- get_all: Get all items (ignore pagination)
Returns:
List of tree items (files and directories)
"""
def repository_blob(self, sha: str, **kwargs) -> dict:
"""
Get blob content by SHA.
Parameters:
- sha: Blob SHA
Returns:
Dictionary with blob information and content
"""
def repository_archive(
self,
sha: str | None = None,
format: str = "tar.gz",
**kwargs
) -> bytes:
"""
Get repository archive.
Parameters:
- sha: Commit SHA (default: default branch)
- format: Archive format ("tar.gz", "tar.bz2", "tbz", "tbz2", "tb2", "bz2", "tar", "zip")
Returns:
Archive content as bytes
"""
def repository_compare(
self,
from_ref: str,
to_ref: str,
straight: bool = False,
**kwargs
) -> dict:
"""
Compare two references.
Parameters:
- from_ref: Source reference
- to_ref: Target reference
- straight: Straight comparison (no merge base)
Returns:
Dictionary with comparison information
"""
def repository_contributors(self, **kwargs) -> list[dict]:
"""
Get repository contributors.
Returns:
List of contributor information
"""import gitlab
gl = gitlab.Gitlab("https://gitlab.example.com", private_token="your-token")
project = gl.projects.get(123)
# File operations
# Get file content
try:
file = project.files.get("README.md", ref="main")
content = file.decode().decode('utf-8')
print(content)
except gitlab.GitlabGetError:
print("File not found")
# Create new file
file_data = {
"file_path": "new_file.py",
"branch": "main",
"content": "# New Python file\nprint('Hello World')",
"commit_message": "Add new Python file",
"author_name": "Developer",
"author_email": "dev@example.com"
}
new_file = project.files.create(file_data)
# Update file
update_data = {
"branch": "main",
"content": "# Updated content\nprint('Hello Updated World')",
"commit_message": "Update Python file"
}
project.files.update("new_file.py", update_data)
# Delete file
delete_data = {
"branch": "main",
"commit_message": "Remove Python file"
}
project.files.delete("new_file.py", delete_data)
# Get raw file content
raw_content = project.files.raw("README.md", ref="main")
# Get file blame
blame = project.files.blame("src/main.py", ref="main")
# Branch management
branches = project.branches.list(search="feature")
# Create branch
branch_data = {
"branch": "new-feature",
"ref": "main"
}
new_branch = project.branches.create(branch_data)
# Protect branch
branch = project.branches.get("main")
branch.protect(
push_access_level=40, # Maintainer
merge_access_level=30, # Developer
code_owner_approval_required=True,
allow_force_push=False
)
# Tag management
tags = project.tags.list()
# Create tag
tag_data = {
"tag_name": "v1.0.0",
"ref": "main",
"message": "Version 1.0.0 release",
"release_description": "First stable release"
}
new_tag = project.tags.create(tag_data)
# Commit operations
commits = project.commits.list(
ref_name="main",
since="2024-01-01T00:00:00Z",
with_stats=True
)
commit = project.commits.get("abc123")
diff = commit.diff()
commit.comment("Great commit!")
# Cherry-pick commit
commit.cherry_pick("develop")
# Repository operations
# Get repository tree
tree = project.repository_tree(path="src", recursive=True)
# Get repository archive
archive = project.repository_archive(format="zip")
with open("repo.zip", "wb") as f:
f.write(archive)
# Compare references
comparison = project.repository_compare("v1.0.0", "main")
print(f"Commits ahead: {len(comparison['commits'])}")
# Get contributors
contributors = project.repository_contributors()
for contributor in contributors:
print(f"{contributor['name']}: {contributor['commits']} commits")class GitlabProtectError(GitlabOperationError):
"""Raised when branch/tag protection operation fails."""
pass
class GitlabCherryPickError(GitlabOperationError):
"""Raised when cherry-pick operation fails."""
pass
class GitlabRevertError(GitlabOperationError):
"""Raised when revert operation fails."""
passExample error handling:
try:
file = project.files.get("nonexistent.txt")
except gitlab.GitlabGetError as e:
if e.response_code == 404:
print("File not found")
try:
branch.protect(push_access_level=30)
except gitlab.GitlabProtectError as e:
print(f"Cannot protect branch: {e}")
try:
commit.cherry_pick("target-branch")
except gitlab.GitlabCherryPickError as e:
print(f"Cherry-pick failed: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-python-gitlab