git-llm-tool 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of git-llm-tool might be problematic. Click here for more details.
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/PKG-INFO +97 -1
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/README.md +96 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/cli.py +3 -7
- git_llm_tool-0.1.2/git_llm_tool/commands/changelog_cmd.py +189 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/pyproject.toml +1 -1
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/LICENSE +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/__init__.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/__main__.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/commands/__init__.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/commands/commit_cmd.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/core/__init__.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/core/config.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/core/exceptions.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/core/git_helper.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/core/jira_helper.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/providers/__init__.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/providers/anthropic.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/providers/azure_openai.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/providers/base.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/providers/factory.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/providers/gemini.py +0 -0
- {git_llm_tool-0.1.0 → git_llm_tool-0.1.2}/git_llm_tool/providers/openai.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: git-llm-tool
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: AI-powered git commit message and changelog generator
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: git,commit,llm,ai,automation,jira,conventional-commits
|
|
@@ -47,6 +47,7 @@ AI-powered git commit message and changelog generator using LLM APIs.
|
|
|
47
47
|
- [Supported Models](#supported-models)
|
|
48
48
|
- [Development](#development)
|
|
49
49
|
- [Contributing](#contributing)
|
|
50
|
+
- [Git Custom Command Integration](#git-custom-command-integration)
|
|
50
51
|
- [Troubleshooting](#troubleshooting)
|
|
51
52
|
- [License](#license)
|
|
52
53
|
|
|
@@ -385,6 +386,101 @@ poetry publish
|
|
|
385
386
|
8. Push to the branch (`git push origin feature/amazing-feature`)
|
|
386
387
|
9. Open a Pull Request
|
|
387
388
|
|
|
389
|
+
## Git Custom Command Integration
|
|
390
|
+
|
|
391
|
+
You can integrate git-llm as a native git subcommand, allowing you to use `git llm` instead of `git-llm`.
|
|
392
|
+
|
|
393
|
+
### Method 1: Git Aliases (Recommended)
|
|
394
|
+
|
|
395
|
+
Add aliases to your git configuration:
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
# Add git aliases for all commands
|
|
399
|
+
git config --global alias.llm-commit '!git-llm commit'
|
|
400
|
+
git config --global alias.llm-changelog '!git-llm changelog'
|
|
401
|
+
git config --global alias.llm-config '!git-llm config'
|
|
402
|
+
|
|
403
|
+
# Or create a general alias
|
|
404
|
+
git config --global alias.llm '!git-llm'
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Now you can use:
|
|
408
|
+
```bash
|
|
409
|
+
git llm commit # Instead of git-llm commit
|
|
410
|
+
git llm changelog # Instead of git-llm changelog
|
|
411
|
+
git llm config get # Instead of git-llm config get
|
|
412
|
+
|
|
413
|
+
# Or with specific aliases
|
|
414
|
+
git llm-commit # Direct alias to git-llm commit
|
|
415
|
+
git llm-changelog # Direct alias to git-llm changelog
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Method 2: Shell Aliases
|
|
419
|
+
|
|
420
|
+
Add to your shell profile (`.bashrc`, `.zshrc`, etc.):
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
# Simple alias
|
|
424
|
+
alias gllm='git-llm'
|
|
425
|
+
|
|
426
|
+
# Or git-style aliases
|
|
427
|
+
alias gllmc='git-llm commit'
|
|
428
|
+
alias gllmcl='git-llm changelog'
|
|
429
|
+
alias gllmcfg='git-llm config'
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Usage:
|
|
433
|
+
```bash
|
|
434
|
+
gllm commit # git-llm commit
|
|
435
|
+
gllmc # git-llm commit
|
|
436
|
+
gllmcl # git-llm changelog
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Method 3: Custom Git Script
|
|
440
|
+
|
|
441
|
+
Create a custom git command script:
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
# Create git-llm script in your PATH
|
|
445
|
+
sudo tee /usr/local/bin/git-llm > /dev/null << 'EOF'
|
|
446
|
+
#!/bin/bash
|
|
447
|
+
# Git-LLM integration script
|
|
448
|
+
exec git-llm "$@"
|
|
449
|
+
EOF
|
|
450
|
+
|
|
451
|
+
sudo chmod +x /usr/local/bin/git-llm
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
Now you can use:
|
|
455
|
+
```bash
|
|
456
|
+
git llm commit # Calls git-llm commit
|
|
457
|
+
git llm changelog # Calls git-llm changelog
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Recommended Git Workflow
|
|
461
|
+
|
|
462
|
+
With git aliases configured, your workflow becomes:
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
# Make changes
|
|
466
|
+
echo "console.log('Hello');" > app.js
|
|
467
|
+
|
|
468
|
+
# Stage changes
|
|
469
|
+
git add .
|
|
470
|
+
|
|
471
|
+
# Generate AI commit message (opens editor)
|
|
472
|
+
git llm commit
|
|
473
|
+
|
|
474
|
+
# Or commit directly
|
|
475
|
+
git llm commit --apply
|
|
476
|
+
|
|
477
|
+
# Generate changelog
|
|
478
|
+
git llm changelog
|
|
479
|
+
|
|
480
|
+
# Check configuration
|
|
481
|
+
git llm config get
|
|
482
|
+
```
|
|
483
|
+
|
|
388
484
|
## Requirements
|
|
389
485
|
|
|
390
486
|
- Python 3.12+
|
|
@@ -18,6 +18,7 @@ AI-powered git commit message and changelog generator using LLM APIs.
|
|
|
18
18
|
- [Supported Models](#supported-models)
|
|
19
19
|
- [Development](#development)
|
|
20
20
|
- [Contributing](#contributing)
|
|
21
|
+
- [Git Custom Command Integration](#git-custom-command-integration)
|
|
21
22
|
- [Troubleshooting](#troubleshooting)
|
|
22
23
|
- [License](#license)
|
|
23
24
|
|
|
@@ -356,6 +357,101 @@ poetry publish
|
|
|
356
357
|
8. Push to the branch (`git push origin feature/amazing-feature`)
|
|
357
358
|
9. Open a Pull Request
|
|
358
359
|
|
|
360
|
+
## Git Custom Command Integration
|
|
361
|
+
|
|
362
|
+
You can integrate git-llm as a native git subcommand, allowing you to use `git llm` instead of `git-llm`.
|
|
363
|
+
|
|
364
|
+
### Method 1: Git Aliases (Recommended)
|
|
365
|
+
|
|
366
|
+
Add aliases to your git configuration:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
# Add git aliases for all commands
|
|
370
|
+
git config --global alias.llm-commit '!git-llm commit'
|
|
371
|
+
git config --global alias.llm-changelog '!git-llm changelog'
|
|
372
|
+
git config --global alias.llm-config '!git-llm config'
|
|
373
|
+
|
|
374
|
+
# Or create a general alias
|
|
375
|
+
git config --global alias.llm '!git-llm'
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Now you can use:
|
|
379
|
+
```bash
|
|
380
|
+
git llm commit # Instead of git-llm commit
|
|
381
|
+
git llm changelog # Instead of git-llm changelog
|
|
382
|
+
git llm config get # Instead of git-llm config get
|
|
383
|
+
|
|
384
|
+
# Or with specific aliases
|
|
385
|
+
git llm-commit # Direct alias to git-llm commit
|
|
386
|
+
git llm-changelog # Direct alias to git-llm changelog
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Method 2: Shell Aliases
|
|
390
|
+
|
|
391
|
+
Add to your shell profile (`.bashrc`, `.zshrc`, etc.):
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
# Simple alias
|
|
395
|
+
alias gllm='git-llm'
|
|
396
|
+
|
|
397
|
+
# Or git-style aliases
|
|
398
|
+
alias gllmc='git-llm commit'
|
|
399
|
+
alias gllmcl='git-llm changelog'
|
|
400
|
+
alias gllmcfg='git-llm config'
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Usage:
|
|
404
|
+
```bash
|
|
405
|
+
gllm commit # git-llm commit
|
|
406
|
+
gllmc # git-llm commit
|
|
407
|
+
gllmcl # git-llm changelog
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Method 3: Custom Git Script
|
|
411
|
+
|
|
412
|
+
Create a custom git command script:
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
# Create git-llm script in your PATH
|
|
416
|
+
sudo tee /usr/local/bin/git-llm > /dev/null << 'EOF'
|
|
417
|
+
#!/bin/bash
|
|
418
|
+
# Git-LLM integration script
|
|
419
|
+
exec git-llm "$@"
|
|
420
|
+
EOF
|
|
421
|
+
|
|
422
|
+
sudo chmod +x /usr/local/bin/git-llm
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Now you can use:
|
|
426
|
+
```bash
|
|
427
|
+
git llm commit # Calls git-llm commit
|
|
428
|
+
git llm changelog # Calls git-llm changelog
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Recommended Git Workflow
|
|
432
|
+
|
|
433
|
+
With git aliases configured, your workflow becomes:
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
# Make changes
|
|
437
|
+
echo "console.log('Hello');" > app.js
|
|
438
|
+
|
|
439
|
+
# Stage changes
|
|
440
|
+
git add .
|
|
441
|
+
|
|
442
|
+
# Generate AI commit message (opens editor)
|
|
443
|
+
git llm commit
|
|
444
|
+
|
|
445
|
+
# Or commit directly
|
|
446
|
+
git llm commit --apply
|
|
447
|
+
|
|
448
|
+
# Generate changelog
|
|
449
|
+
git llm changelog
|
|
450
|
+
|
|
451
|
+
# Check configuration
|
|
452
|
+
git llm config get
|
|
453
|
+
```
|
|
454
|
+
|
|
359
455
|
## Requirements
|
|
360
456
|
|
|
361
457
|
- Python 3.12+
|
|
@@ -7,6 +7,7 @@ from git_llm_tool import __version__
|
|
|
7
7
|
from git_llm_tool.core.config import ConfigLoader, get_config
|
|
8
8
|
from git_llm_tool.core.exceptions import ConfigError
|
|
9
9
|
from git_llm_tool.commands.commit_cmd import execute_commit
|
|
10
|
+
from git_llm_tool.commands.changelog_cmd import execute_changelog
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
@click.group()
|
|
@@ -61,13 +62,8 @@ def commit(ctx, apply, model, language):
|
|
|
61
62
|
@click.pass_context
|
|
62
63
|
def changelog(ctx, from_ref, to_ref, output, force):
|
|
63
64
|
"""Generate changelog from git history."""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
# This will be implemented in subsequent tasks
|
|
67
|
-
if output:
|
|
68
|
-
click.echo(f"📄 Changelog saved to {output}")
|
|
69
|
-
else:
|
|
70
|
-
click.echo("📄 Changelog output to stdout")
|
|
65
|
+
verbose = ctx.obj.get('verbose', False) if ctx.obj else False
|
|
66
|
+
execute_changelog(from_ref=from_ref, to_ref=to_ref, output=output, force=force, verbose=verbose)
|
|
71
67
|
|
|
72
68
|
|
|
73
69
|
@main.group()
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"""Changelog command implementation."""
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
import os
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from git_llm_tool.core.config import get_config
|
|
9
|
+
from git_llm_tool.core.git_helper import GitHelper
|
|
10
|
+
from git_llm_tool.core.exceptions import GitError, ApiError, ConfigError
|
|
11
|
+
from git_llm_tool.providers import get_provider
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _manage_changelog_file(new_content: str, verbose: bool = False) -> str:
|
|
15
|
+
"""Manage the changelog.md file in the repository root.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
new_content: New changelog content to add
|
|
19
|
+
verbose: Enable verbose output
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Path to the changelog file
|
|
23
|
+
"""
|
|
24
|
+
# Get repository root
|
|
25
|
+
git_helper = GitHelper()
|
|
26
|
+
repo_info = git_helper.get_repository_info()
|
|
27
|
+
repo_root = repo_info.get('repository_root', os.getcwd())
|
|
28
|
+
|
|
29
|
+
changelog_path = os.path.join(repo_root, 'changelog.md')
|
|
30
|
+
|
|
31
|
+
# Get current date
|
|
32
|
+
current_date = datetime.now().strftime('%Y-%m-%d')
|
|
33
|
+
|
|
34
|
+
# Create header with date
|
|
35
|
+
header = f"\n## {current_date}\n\n"
|
|
36
|
+
|
|
37
|
+
# Clean the new content (remove any duplicate titles)
|
|
38
|
+
cleaned_content = new_content.strip()
|
|
39
|
+
if cleaned_content.startswith('# Changelog'):
|
|
40
|
+
# Remove the duplicate title line
|
|
41
|
+
lines = cleaned_content.split('\n')
|
|
42
|
+
lines = [line for line in lines[1:] if line.strip()] # Skip title and empty lines
|
|
43
|
+
cleaned_content = '\n'.join(lines)
|
|
44
|
+
|
|
45
|
+
# Prepare content to add
|
|
46
|
+
content_to_add = header + cleaned_content + "\n"
|
|
47
|
+
|
|
48
|
+
if os.path.exists(changelog_path):
|
|
49
|
+
if verbose:
|
|
50
|
+
click.echo(f"📝 Found existing changelog at {changelog_path}")
|
|
51
|
+
|
|
52
|
+
# Read existing content
|
|
53
|
+
try:
|
|
54
|
+
with open(changelog_path, 'r', encoding='utf-8') as f:
|
|
55
|
+
existing_content = f.read()
|
|
56
|
+
except IOError as e:
|
|
57
|
+
raise Exception(f"Failed to read existing changelog: {e}")
|
|
58
|
+
|
|
59
|
+
# Check if we're at the beginning of the file or need to add after title
|
|
60
|
+
if existing_content.strip().startswith('# '):
|
|
61
|
+
# Find the end of the title line
|
|
62
|
+
lines = existing_content.split('\n')
|
|
63
|
+
title_line = lines[0]
|
|
64
|
+
rest_content = '\n'.join(lines[1:])
|
|
65
|
+
|
|
66
|
+
# Insert new content after title
|
|
67
|
+
final_content = title_line + '\n' + content_to_add + rest_content
|
|
68
|
+
else:
|
|
69
|
+
# Prepend to existing content
|
|
70
|
+
final_content = content_to_add + existing_content
|
|
71
|
+
|
|
72
|
+
else:
|
|
73
|
+
if verbose:
|
|
74
|
+
click.echo(f"📄 Creating new changelog at {changelog_path}")
|
|
75
|
+
|
|
76
|
+
# Create new changelog with header
|
|
77
|
+
final_content = f"# Changelog\n{content_to_add}"
|
|
78
|
+
|
|
79
|
+
# Write the file
|
|
80
|
+
try:
|
|
81
|
+
with open(changelog_path, 'w', encoding='utf-8') as f:
|
|
82
|
+
f.write(final_content)
|
|
83
|
+
if verbose:
|
|
84
|
+
click.echo(f"✅ Updated changelog at {changelog_path}")
|
|
85
|
+
except IOError as e:
|
|
86
|
+
raise Exception(f"Failed to write changelog: {e}")
|
|
87
|
+
|
|
88
|
+
return changelog_path
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def execute_changelog(
|
|
92
|
+
from_ref: Optional[str] = None,
|
|
93
|
+
to_ref: str = "HEAD",
|
|
94
|
+
output: Optional[str] = None,
|
|
95
|
+
force: bool = False,
|
|
96
|
+
verbose: bool = False
|
|
97
|
+
) -> None:
|
|
98
|
+
"""Execute the changelog command logic.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
from_ref: Starting reference (default: last tag)
|
|
102
|
+
to_ref: Ending reference (default: HEAD)
|
|
103
|
+
output: Output file path
|
|
104
|
+
force: Force overwrite existing file
|
|
105
|
+
verbose: Enable verbose output
|
|
106
|
+
"""
|
|
107
|
+
try:
|
|
108
|
+
# Load configuration
|
|
109
|
+
config = get_config()
|
|
110
|
+
|
|
111
|
+
if verbose:
|
|
112
|
+
click.echo(f"📄 Using model: {config.llm.default_model}")
|
|
113
|
+
click.echo(f"🌐 Using language: {config.llm.language}")
|
|
114
|
+
|
|
115
|
+
# Initialize Git helper
|
|
116
|
+
git_helper = GitHelper()
|
|
117
|
+
|
|
118
|
+
# Get commit messages in range
|
|
119
|
+
if verbose:
|
|
120
|
+
click.echo("📊 Getting commit messages...")
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
commit_messages = git_helper.get_commit_messages(from_ref, to_ref)
|
|
124
|
+
except GitError as e:
|
|
125
|
+
click.echo(f"❌ {e}", err=True)
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
if verbose:
|
|
129
|
+
click.echo(f"📝 Found {len(commit_messages)} commits")
|
|
130
|
+
|
|
131
|
+
# Get LLM provider
|
|
132
|
+
try:
|
|
133
|
+
provider = get_provider(config)
|
|
134
|
+
if verbose:
|
|
135
|
+
click.echo(f"🤖 Using provider: {provider.__class__.__name__}")
|
|
136
|
+
except ApiError as e:
|
|
137
|
+
click.echo(f"❌ {e}", err=True)
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
# Generate changelog
|
|
141
|
+
click.echo("🤖 Generating changelog...")
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
changelog = provider.generate_changelog(commit_messages)
|
|
145
|
+
except ApiError as e:
|
|
146
|
+
click.echo(f"❌ API Error: {e}", err=True)
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
if verbose:
|
|
150
|
+
click.echo(f"✨ Generated changelog ({len(changelog)} characters)")
|
|
151
|
+
|
|
152
|
+
# Output changelog
|
|
153
|
+
if output:
|
|
154
|
+
# Custom output file specified
|
|
155
|
+
if os.path.exists(output) and not force:
|
|
156
|
+
if not click.confirm(f"File {output} exists. Overwrite?"):
|
|
157
|
+
click.echo("❌ Changelog generation cancelled.")
|
|
158
|
+
return
|
|
159
|
+
|
|
160
|
+
# Write to custom file
|
|
161
|
+
try:
|
|
162
|
+
with open(output, 'w', encoding='utf-8') as f:
|
|
163
|
+
f.write(changelog)
|
|
164
|
+
click.echo(f"✅ Changelog saved to {output}")
|
|
165
|
+
except IOError as e:
|
|
166
|
+
click.echo(f"❌ Failed to write to {output}: {e}", err=True)
|
|
167
|
+
else:
|
|
168
|
+
# Auto-manage changelog.md in repository root
|
|
169
|
+
try:
|
|
170
|
+
changelog_path = _manage_changelog_file(changelog, verbose)
|
|
171
|
+
click.echo(f"✅ Changelog updated in {changelog_path}")
|
|
172
|
+
|
|
173
|
+
# Also show the generated content
|
|
174
|
+
if verbose:
|
|
175
|
+
click.echo("\n" + "="*60)
|
|
176
|
+
click.echo("📋 Generated Content:")
|
|
177
|
+
click.echo("="*60)
|
|
178
|
+
click.echo(changelog)
|
|
179
|
+
click.echo("="*60)
|
|
180
|
+
except Exception as e:
|
|
181
|
+
click.echo(f"❌ Failed to update changelog.md: {e}", err=True)
|
|
182
|
+
|
|
183
|
+
except ConfigError as e:
|
|
184
|
+
click.echo(f"❌ Configuration error: {e}", err=True)
|
|
185
|
+
except Exception as e:
|
|
186
|
+
click.echo(f"❌ Unexpected error: {e}", err=True)
|
|
187
|
+
if verbose:
|
|
188
|
+
import traceback
|
|
189
|
+
click.echo(traceback.format_exc(), err=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|