simple-vcs 1.0.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 SimpleVCS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ include README.md
2
+ include LICENSE
3
+ include requirements.txt
4
+ recursive-include simple_vcs *.py
@@ -0,0 +1,278 @@
1
+ Metadata-Version: 2.4
2
+ Name: simple-vcs
3
+ Version: 1.0.0
4
+ Summary: A simple version control system written in Python
5
+ Home-page: https://github.com/yourusername/simple-vcs
6
+ Author: Your Name
7
+ Author-email: your.email@example.com
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.7
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Requires-Python: >=3.7
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: click>=7.0
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: home-page
27
+ Dynamic: license-file
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
31
+
32
+ # README.md
33
+ # SimpleVCS
34
+
35
+ A simple version control system written in Python that provides basic VCS functionality similar to Git.
36
+
37
+ ## Features
38
+
39
+ - Initialize repositories
40
+ - Add files to staging area
41
+ - Commit changes with messages or timestamps
42
+ - View commit history with detailed information
43
+ - Show differences between commits
44
+ - Repository status tracking
45
+ - Cross-platform compatibility
46
+ - Both CLI and Python API support
47
+
48
+ ## Installation
49
+
50
+ ### From PyPI (when published)
51
+ ```bash
52
+ pip install simple-vcs
53
+ ```
54
+
55
+ ### From Source
56
+ ```bash
57
+ # Clone the repository
58
+ git clone https://github.com/muhammadsufiyanbaig/simple_vcs.git
59
+ cd simple-vcs
60
+
61
+ # Install in development mode
62
+ pip install -e .
63
+
64
+ # Or install normally
65
+ pip install .
66
+ ```
67
+
68
+ ## Quick Start
69
+
70
+ ```bash
71
+ # Initialize a new repository
72
+ svcs init
73
+
74
+ # Create a sample file
75
+ echo "Hello World" > hello.txt
76
+
77
+ # Add file to staging area
78
+ svcs add hello.txt
79
+
80
+ # Commit the changes
81
+ svcs commit -m "Add hello.txt"
82
+
83
+ # View commit history
84
+ svcs log
85
+ ```
86
+
87
+ ## Usage
88
+
89
+ ### Command Line Interface
90
+
91
+ #### Repository Management
92
+ ```bash
93
+ # Initialize a new repository in current directory
94
+ svcs init
95
+
96
+ # Initialize in specific directory
97
+ svcs init --path /path/to/project
98
+ ```
99
+
100
+ #### File Operations
101
+ ```bash
102
+ # Add single file
103
+ svcs add filename.txt
104
+
105
+ # Add multiple files
106
+ svcs add file1.txt file2.py file3.md
107
+
108
+ # Check repository status
109
+ svcs status
110
+ ```
111
+
112
+ #### Commit Operations
113
+ ```bash
114
+ # Commit with message
115
+ svcs commit -m "Your commit message"
116
+
117
+ # Commit with auto-generated timestamp
118
+ svcs commit
119
+
120
+ # View commit history
121
+ svcs log
122
+
123
+ # View limited commit history
124
+ svcs log --limit 5
125
+ ```
126
+
127
+ #### Viewing Differences
128
+ ```bash
129
+ # Show diff between last two commits
130
+ svcs diff
131
+
132
+ # Show diff between specific commits
133
+ svcs diff --c1 1 --c2 3
134
+
135
+ # Show diff between commit 2 and latest
136
+ svcs diff --c1 2
137
+ ```
138
+
139
+ ### Python API
140
+
141
+ ```python
142
+ from simple_vcs import SimpleVCS
143
+
144
+ # Create VCS instance
145
+ vcs = SimpleVCS("./my_project")
146
+
147
+ # Initialize repository
148
+ vcs.init_repo()
149
+
150
+ # Add files
151
+ vcs.add_file("example.txt")
152
+ vcs.add_file("script.py")
153
+
154
+ # Commit changes
155
+ vcs.commit("Initial commit with example files")
156
+
157
+ # Show commit history
158
+ vcs.show_log()
159
+
160
+ # Show differences between commits
161
+ vcs.show_diff(1, 2)
162
+
163
+ # Check repository status
164
+ vcs.status()
165
+ ```
166
+
167
+ ## Advanced Usage
168
+
169
+ ### Working with Multiple Files
170
+ ```python
171
+ from simple_vcs import SimpleVCS
172
+ from simple_vcs.utils import get_all_files
173
+
174
+ vcs = SimpleVCS()
175
+ vcs.init_repo()
176
+
177
+ # Add all Python files in current directory
178
+ python_files = [f for f in get_all_files(".") if f.endswith('.py')]
179
+ for file in python_files:
180
+ vcs.add_file(file)
181
+
182
+ vcs.commit("Add all Python files")
183
+ ```
184
+
185
+ ### Repository Structure
186
+ When initialized, SimpleVCS creates a `.svcs` directory containing:
187
+ ```
188
+ .svcs/
189
+ ├── objects/ # File content storage (hashed)
190
+ ├── commits.json # Commit history and metadata
191
+ ├── staging.json # Currently staged files
192
+ └── HEAD # Current commit reference
193
+ ```
194
+
195
+ ## Requirements
196
+
197
+ - Python 3.7 or higher
198
+ - click>=7.0 (for CLI functionality)
199
+
200
+ ## Development
201
+
202
+ ### Setting up Development Environment
203
+ ```bash
204
+ # Clone the repository
205
+ git clone https://github.com/yourusername/simple-vcs.git
206
+ cd simple-vcs
207
+
208
+ # Create virtual environment
209
+ python -m venv venv
210
+ source venv/bin/activate # On Windows: venv\Scripts\activate
211
+
212
+ # Install in development mode
213
+ pip install -e .
214
+
215
+ # Install development dependencies
216
+ pip install pytest pytest-cov black flake8
217
+ ```
218
+
219
+ ### Running Tests
220
+ ```bash
221
+ # Run all tests
222
+ pytest
223
+
224
+ # Run with coverage
225
+ pytest --cov=simple_vcs
226
+
227
+ # Run specific test file
228
+ pytest tests/test_core.py
229
+ ```
230
+
231
+ ## Contributing
232
+
233
+ 1. Fork the repository
234
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
235
+ 3. Make your changes
236
+ 4. Add tests for your changes
237
+ 5. Ensure tests pass (`pytest`)
238
+ 6. Commit your changes (`git commit -m 'Add amazing feature'`)
239
+ 7. Push to the branch (`git push origin feature/amazing-feature`)
240
+ 8. Open a Pull Request
241
+
242
+ ## Publishing to PyPI
243
+
244
+ ```bash
245
+ # Install build tools
246
+ pip install build twine
247
+
248
+ # Build the package
249
+ python -m build
250
+
251
+ # Upload to PyPI (requires PyPI account)
252
+ twine upload dist/*
253
+ ```
254
+
255
+ ## Limitations
256
+
257
+ This is a simple implementation for educational purposes. It lacks advanced features like:
258
+ - Branching and merging
259
+ - Remote repositories
260
+ - File conflict resolution
261
+ - Large file handling
262
+ - Advanced diff algorithms
263
+
264
+ ## License
265
+
266
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
267
+
268
+ ## Author
269
+
270
+ Your Name - your.email@example.com
271
+
272
+ ## Changelog
273
+
274
+ ### Version 1.0.0
275
+ - Initial release
276
+ - Basic VCS functionality (init, add, commit, log, diff, status)
277
+ - CLI and Python API support
278
+ - Cross-platform compatibility
@@ -0,0 +1,247 @@
1
+ # README.md
2
+ # SimpleVCS
3
+
4
+ A simple version control system written in Python that provides basic VCS functionality similar to Git.
5
+
6
+ ## Features
7
+
8
+ - Initialize repositories
9
+ - Add files to staging area
10
+ - Commit changes with messages or timestamps
11
+ - View commit history with detailed information
12
+ - Show differences between commits
13
+ - Repository status tracking
14
+ - Cross-platform compatibility
15
+ - Both CLI and Python API support
16
+
17
+ ## Installation
18
+
19
+ ### From PyPI (when published)
20
+ ```bash
21
+ pip install simple-vcs
22
+ ```
23
+
24
+ ### From Source
25
+ ```bash
26
+ # Clone the repository
27
+ git clone https://github.com/muhammadsufiyanbaig/simple_vcs.git
28
+ cd simple-vcs
29
+
30
+ # Install in development mode
31
+ pip install -e .
32
+
33
+ # Or install normally
34
+ pip install .
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ```bash
40
+ # Initialize a new repository
41
+ svcs init
42
+
43
+ # Create a sample file
44
+ echo "Hello World" > hello.txt
45
+
46
+ # Add file to staging area
47
+ svcs add hello.txt
48
+
49
+ # Commit the changes
50
+ svcs commit -m "Add hello.txt"
51
+
52
+ # View commit history
53
+ svcs log
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ### Command Line Interface
59
+
60
+ #### Repository Management
61
+ ```bash
62
+ # Initialize a new repository in current directory
63
+ svcs init
64
+
65
+ # Initialize in specific directory
66
+ svcs init --path /path/to/project
67
+ ```
68
+
69
+ #### File Operations
70
+ ```bash
71
+ # Add single file
72
+ svcs add filename.txt
73
+
74
+ # Add multiple files
75
+ svcs add file1.txt file2.py file3.md
76
+
77
+ # Check repository status
78
+ svcs status
79
+ ```
80
+
81
+ #### Commit Operations
82
+ ```bash
83
+ # Commit with message
84
+ svcs commit -m "Your commit message"
85
+
86
+ # Commit with auto-generated timestamp
87
+ svcs commit
88
+
89
+ # View commit history
90
+ svcs log
91
+
92
+ # View limited commit history
93
+ svcs log --limit 5
94
+ ```
95
+
96
+ #### Viewing Differences
97
+ ```bash
98
+ # Show diff between last two commits
99
+ svcs diff
100
+
101
+ # Show diff between specific commits
102
+ svcs diff --c1 1 --c2 3
103
+
104
+ # Show diff between commit 2 and latest
105
+ svcs diff --c1 2
106
+ ```
107
+
108
+ ### Python API
109
+
110
+ ```python
111
+ from simple_vcs import SimpleVCS
112
+
113
+ # Create VCS instance
114
+ vcs = SimpleVCS("./my_project")
115
+
116
+ # Initialize repository
117
+ vcs.init_repo()
118
+
119
+ # Add files
120
+ vcs.add_file("example.txt")
121
+ vcs.add_file("script.py")
122
+
123
+ # Commit changes
124
+ vcs.commit("Initial commit with example files")
125
+
126
+ # Show commit history
127
+ vcs.show_log()
128
+
129
+ # Show differences between commits
130
+ vcs.show_diff(1, 2)
131
+
132
+ # Check repository status
133
+ vcs.status()
134
+ ```
135
+
136
+ ## Advanced Usage
137
+
138
+ ### Working with Multiple Files
139
+ ```python
140
+ from simple_vcs import SimpleVCS
141
+ from simple_vcs.utils import get_all_files
142
+
143
+ vcs = SimpleVCS()
144
+ vcs.init_repo()
145
+
146
+ # Add all Python files in current directory
147
+ python_files = [f for f in get_all_files(".") if f.endswith('.py')]
148
+ for file in python_files:
149
+ vcs.add_file(file)
150
+
151
+ vcs.commit("Add all Python files")
152
+ ```
153
+
154
+ ### Repository Structure
155
+ When initialized, SimpleVCS creates a `.svcs` directory containing:
156
+ ```
157
+ .svcs/
158
+ ├── objects/ # File content storage (hashed)
159
+ ├── commits.json # Commit history and metadata
160
+ ├── staging.json # Currently staged files
161
+ └── HEAD # Current commit reference
162
+ ```
163
+
164
+ ## Requirements
165
+
166
+ - Python 3.7 or higher
167
+ - click>=7.0 (for CLI functionality)
168
+
169
+ ## Development
170
+
171
+ ### Setting up Development Environment
172
+ ```bash
173
+ # Clone the repository
174
+ git clone https://github.com/yourusername/simple-vcs.git
175
+ cd simple-vcs
176
+
177
+ # Create virtual environment
178
+ python -m venv venv
179
+ source venv/bin/activate # On Windows: venv\Scripts\activate
180
+
181
+ # Install in development mode
182
+ pip install -e .
183
+
184
+ # Install development dependencies
185
+ pip install pytest pytest-cov black flake8
186
+ ```
187
+
188
+ ### Running Tests
189
+ ```bash
190
+ # Run all tests
191
+ pytest
192
+
193
+ # Run with coverage
194
+ pytest --cov=simple_vcs
195
+
196
+ # Run specific test file
197
+ pytest tests/test_core.py
198
+ ```
199
+
200
+ ## Contributing
201
+
202
+ 1. Fork the repository
203
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
204
+ 3. Make your changes
205
+ 4. Add tests for your changes
206
+ 5. Ensure tests pass (`pytest`)
207
+ 6. Commit your changes (`git commit -m 'Add amazing feature'`)
208
+ 7. Push to the branch (`git push origin feature/amazing-feature`)
209
+ 8. Open a Pull Request
210
+
211
+ ## Publishing to PyPI
212
+
213
+ ```bash
214
+ # Install build tools
215
+ pip install build twine
216
+
217
+ # Build the package
218
+ python -m build
219
+
220
+ # Upload to PyPI (requires PyPI account)
221
+ twine upload dist/*
222
+ ```
223
+
224
+ ## Limitations
225
+
226
+ This is a simple implementation for educational purposes. It lacks advanced features like:
227
+ - Branching and merging
228
+ - Remote repositories
229
+ - File conflict resolution
230
+ - Large file handling
231
+ - Advanced diff algorithms
232
+
233
+ ## License
234
+
235
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
236
+
237
+ ## Author
238
+
239
+ Your Name - your.email@example.com
240
+
241
+ ## Changelog
242
+
243
+ ### Version 1.0.0
244
+ - Initial release
245
+ - Basic VCS functionality (init, add, commit, log, diff, status)
246
+ - CLI and Python API support
247
+ - Cross-platform compatibility
@@ -0,0 +1 @@
1
+ click>=7.0
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,36 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r", encoding="utf-8") as fh:
4
+ long_description = fh.read()
5
+
6
+ setup(
7
+ name="simple-vcs",
8
+ version="1.0.0",
9
+ author="Your Name",
10
+ author_email="your.email@example.com",
11
+ description="A simple version control system written in Python",
12
+ long_description=long_description,
13
+ long_description_content_type="text/markdown",
14
+ url="https://github.com/yourusername/simple-vcs",
15
+ packages=find_packages(),
16
+ classifiers=[
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.7",
23
+ "Programming Language :: Python :: 3.8",
24
+ "Programming Language :: Python :: 3.9",
25
+ "Programming Language :: Python :: 3.10",
26
+ ],
27
+ python_requires=">=3.7",
28
+ install_requires=[
29
+ "click>=7.0",
30
+ ],
31
+ entry_points={
32
+ "console_scripts": [
33
+ "svcs=simple_vcs.cli:main",
34
+ ],
35
+ },
36
+ )
@@ -0,0 +1,10 @@
1
+ """
2
+ SimpleVCS - A simple version control system
3
+ """
4
+
5
+ __version__ = "1.0.0"
6
+ __author__ = "Your Name"
7
+
8
+ from .core import SimpleVCS
9
+
10
+ __all__ = ["SimpleVCS"]
@@ -0,0 +1,54 @@
1
+ import click
2
+ from .core import SimpleVCS
3
+
4
+ @click.group()
5
+ @click.version_option()
6
+ def main():
7
+ """SimpleVCS - A simple version control system"""
8
+ pass
9
+
10
+ @main.command()
11
+ @click.option('--path', default='.', help='Repository path')
12
+ def init(path):
13
+ """Initialize a new repository"""
14
+ vcs = SimpleVCS(path)
15
+ vcs.init_repo()
16
+
17
+ @main.command()
18
+ @click.argument('files', nargs=-1, required=True)
19
+ def add(files):
20
+ """Add files to staging area"""
21
+ vcs = SimpleVCS()
22
+ for file in files:
23
+ vcs.add_file(file)
24
+
25
+ @main.command()
26
+ @click.option('-m', '--message', help='Commit message')
27
+ def commit(message):
28
+ """Commit staged changes"""
29
+ vcs = SimpleVCS()
30
+ vcs.commit(message)
31
+
32
+ @main.command()
33
+ @click.option('--c1', type=int, help='First commit ID')
34
+ @click.option('--c2', type=int, help='Second commit ID')
35
+ def diff(c1, c2):
36
+ """Show differences between commits"""
37
+ vcs = SimpleVCS()
38
+ vcs.show_diff(c1, c2)
39
+
40
+ @main.command()
41
+ @click.option('--limit', type=int, help='Limit number of commits to show')
42
+ def log(limit):
43
+ """Show commit history"""
44
+ vcs = SimpleVCS()
45
+ vcs.show_log(limit)
46
+
47
+ @main.command()
48
+ def status():
49
+ """Show repository status"""
50
+ vcs = SimpleVCS()
51
+ vcs.status()
52
+
53
+ if __name__ == '__main__':
54
+ main()
@@ -0,0 +1,276 @@
1
+ import os
2
+ import json
3
+ import hashlib
4
+ import shutil
5
+ import time
6
+ from datetime import datetime
7
+ from pathlib import Path
8
+ from typing import Dict, List, Optional, Tuple
9
+
10
+ class SimpleVCS:
11
+ """Simple Version Control System core functionality"""
12
+
13
+ def __init__(self, repo_path: str = "."):
14
+ self.repo_path = Path(repo_path).resolve()
15
+ self.svcs_dir = self.repo_path / ".svcs"
16
+ self.objects_dir = self.svcs_dir / "objects"
17
+ self.commits_file = self.svcs_dir / "commits.json"
18
+ self.staging_file = self.svcs_dir / "staging.json"
19
+ self.head_file = self.svcs_dir / "HEAD"
20
+
21
+ def init_repo(self) -> bool:
22
+ """Initialize a new repository"""
23
+ if self.svcs_dir.exists():
24
+ print(f"Repository already exists at {self.repo_path}")
25
+ return False
26
+
27
+ # Create directory structure
28
+ self.svcs_dir.mkdir()
29
+ self.objects_dir.mkdir()
30
+
31
+ # Initialize files
32
+ self._write_json(self.commits_file, [])
33
+ self._write_json(self.staging_file, {})
34
+ self.head_file.write_text("0") # Start with commit 0
35
+
36
+ print(f"Initialized empty SimpleVCS repository at {self.repo_path}")
37
+ return True
38
+
39
+ def add_file(self, file_path: str) -> bool:
40
+ """Add a file to staging area"""
41
+ if not self._check_repo():
42
+ return False
43
+
44
+ file_path = Path(file_path).resolve() # Convert to absolute path
45
+ if not file_path.exists():
46
+ print(f"File {file_path} does not exist")
47
+ return False
48
+
49
+ if not file_path.is_file():
50
+ print(f"{file_path} is not a file")
51
+ return False
52
+
53
+ # Check if file is within repository
54
+ try:
55
+ relative_path = file_path.relative_to(self.repo_path)
56
+ except ValueError:
57
+ print(f"File {file_path} is not within the repository")
58
+ return False
59
+
60
+ # Calculate file hash
61
+ file_hash = self._calculate_file_hash(file_path)
62
+
63
+ # Store file content in objects
64
+ self._store_object(file_hash, file_path.read_bytes())
65
+
66
+ # Add to staging
67
+ staging = self._read_json(self.staging_file)
68
+ staging[str(relative_path)] = {
69
+ "hash": file_hash,
70
+ "size": file_path.stat().st_size,
71
+ "modified": file_path.stat().st_mtime
72
+ }
73
+ self._write_json(self.staging_file, staging)
74
+
75
+ print(f"Added {file_path.name} to staging area")
76
+ return True
77
+
78
+ def commit(self, message: Optional[str] = None) -> bool:
79
+ """Commit staged changes"""
80
+ if not self._check_repo():
81
+ return False
82
+
83
+ staging = self._read_json(self.staging_file)
84
+ if not staging:
85
+ print("No changes to commit")
86
+ return False
87
+
88
+ # Create commit object
89
+ commit = {
90
+ "id": len(self._read_json(self.commits_file)) + 1,
91
+ "message": message or f"Commit at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
92
+ "timestamp": time.time(),
93
+ "files": staging.copy(),
94
+ "parent": self._get_current_commit_id()
95
+ }
96
+
97
+ # Save commit
98
+ commits = self._read_json(self.commits_file)
99
+ commits.append(commit)
100
+ self._write_json(self.commits_file, commits)
101
+
102
+ # Update HEAD
103
+ self.head_file.write_text(str(commit["id"]))
104
+
105
+ # Clear staging
106
+ self._write_json(self.staging_file, {})
107
+
108
+ print(f"Committed changes with ID: {commit['id']}")
109
+ print(f"Message: {commit['message']}")
110
+ return True
111
+
112
+ def show_diff(self, commit_id1: Optional[int] = None, commit_id2: Optional[int] = None) -> bool:
113
+ """Show differences between commits"""
114
+ if not self._check_repo():
115
+ return False
116
+
117
+ commits = self._read_json(self.commits_file)
118
+ if not commits:
119
+ print("No commits found")
120
+ return False
121
+
122
+ # Default to comparing last two commits
123
+ if commit_id1 is None and commit_id2 is None:
124
+ if len(commits) < 2:
125
+ print("Need at least 2 commits to show diff")
126
+ return False
127
+ commit1 = commits[-2]
128
+ commit2 = commits[-1]
129
+ else:
130
+ commit1 = self._get_commit_by_id(commit_id1 or (len(commits) - 1))
131
+ commit2 = self._get_commit_by_id(commit_id2 or len(commits))
132
+
133
+ if not commit1 or not commit2:
134
+ print("Invalid commit IDs")
135
+ return False
136
+
137
+ print(f"\nDifferences between commit {commit1['id']} and {commit2['id']}:")
138
+ print("-" * 50)
139
+
140
+ files1 = set(commit1["files"].keys())
141
+ files2 = set(commit2["files"].keys())
142
+
143
+ # New files
144
+ new_files = files2 - files1
145
+ if new_files:
146
+ print("New files:")
147
+ for file in new_files:
148
+ print(f" + {file}")
149
+
150
+ # Deleted files
151
+ deleted_files = files1 - files2
152
+ if deleted_files:
153
+ print("Deleted files:")
154
+ for file in deleted_files:
155
+ print(f" - {file}")
156
+
157
+ # Modified files
158
+ common_files = files1 & files2
159
+ modified_files = []
160
+ for file in common_files:
161
+ if commit1["files"][file]["hash"] != commit2["files"][file]["hash"]:
162
+ modified_files.append(file)
163
+
164
+ if modified_files:
165
+ print("Modified files:")
166
+ for file in modified_files:
167
+ print(f" M {file}")
168
+
169
+ if not new_files and not deleted_files and not modified_files:
170
+ print("No differences found")
171
+
172
+ return True
173
+
174
+ def show_log(self, limit: Optional[int] = None) -> bool:
175
+ """Show commit history"""
176
+ if not self._check_repo():
177
+ return False
178
+
179
+ commits = self._read_json(self.commits_file)
180
+ if not commits:
181
+ print("No commits found")
182
+ return False
183
+
184
+ commits_to_show = commits[-limit:] if limit else commits
185
+ commits_to_show.reverse() # Show newest first
186
+
187
+ print("\nCommit History:")
188
+ print("=" * 50)
189
+
190
+ for commit in commits_to_show:
191
+ print(f"Commit ID: {commit['id']}")
192
+ print(f"Date: {datetime.fromtimestamp(commit['timestamp']).strftime('%Y-%m-%d %H:%M:%S')}")
193
+ print(f"Message: {commit['message']}")
194
+ print(f"Files: {len(commit['files'])} file(s)")
195
+ if commit.get('parent'):
196
+ print(f"Parent: {commit['parent']}")
197
+ print("-" * 30)
198
+
199
+ return True
200
+
201
+ def status(self) -> bool:
202
+ """Show repository status"""
203
+ if not self._check_repo():
204
+ return False
205
+
206
+ staging = self._read_json(self.staging_file)
207
+ current_commit = self._get_current_commit()
208
+
209
+ print(f"\nRepository: {self.repo_path}")
210
+ print(f"Current commit: {current_commit['id'] if current_commit else 'None'}")
211
+
212
+ if staging:
213
+ print("\nStaged files:")
214
+ for file, info in staging.items():
215
+ print(f" {file}")
216
+ else:
217
+ print("\nNo files staged")
218
+
219
+ return True
220
+
221
+ # Helper methods
222
+ def _check_repo(self) -> bool:
223
+ """Check if repository is initialized"""
224
+ if not self.svcs_dir.exists():
225
+ print("Not a SimpleVCS repository. Run 'svcs init' first.")
226
+ return False
227
+ return True
228
+
229
+ def _calculate_file_hash(self, file_path: Path) -> str:
230
+ """Calculate SHA-256 hash of file"""
231
+ hasher = hashlib.sha256()
232
+ with open(file_path, 'rb') as f:
233
+ for chunk in iter(lambda: f.read(4096), b""):
234
+ hasher.update(chunk)
235
+ return hasher.hexdigest()
236
+
237
+ def _store_object(self, obj_hash: str, content: bytes):
238
+ """Store object in objects directory"""
239
+ obj_path = self.objects_dir / obj_hash
240
+ if not obj_path.exists():
241
+ obj_path.write_bytes(content)
242
+
243
+ def _read_json(self, file_path: Path) -> Dict:
244
+ """Read JSON file"""
245
+ if not file_path.exists():
246
+ return {}
247
+ return json.loads(file_path.read_text())
248
+
249
+ def _write_json(self, file_path: Path, data: Dict):
250
+ """Write JSON file"""
251
+ file_path.write_text(json.dumps(data, indent=2))
252
+
253
+ def _get_current_commit_id(self) -> Optional[int]:
254
+ """Get current commit ID"""
255
+ if not self.head_file.exists():
256
+ return None
257
+ try:
258
+ commit_id = int(self.head_file.read_text().strip())
259
+ return commit_id if commit_id > 0 else None
260
+ except:
261
+ return None
262
+
263
+ def _get_current_commit(self) -> Optional[Dict]:
264
+ """Get current commit object"""
265
+ commit_id = self._get_current_commit_id()
266
+ if not commit_id:
267
+ return None
268
+ return self._get_commit_by_id(commit_id)
269
+
270
+ def _get_commit_by_id(self, commit_id: int) -> Optional[Dict]:
271
+ """Get commit by ID"""
272
+ commits = self._read_json(self.commits_file)
273
+ for commit in commits:
274
+ if commit["id"] == commit_id:
275
+ return commit
276
+ return None
@@ -0,0 +1,36 @@
1
+ import os
2
+ from pathlib import Path
3
+ from typing import List
4
+
5
+ def get_all_files(directory: str, ignore_patterns: List[str] = None) -> List[str]:
6
+ """Get all files in directory, excluding ignored patterns"""
7
+ if ignore_patterns is None:
8
+ ignore_patterns = ['.svcs', '__pycache__', '.git', '.DS_Store']
9
+
10
+ files = []
11
+ for root, dirs, filenames in os.walk(directory):
12
+ # Remove ignored directories
13
+ dirs[:] = [d for d in dirs if not any(pattern in d for pattern in ignore_patterns)]
14
+
15
+ for filename in filenames:
16
+ # Skip ignored files
17
+ if any(pattern in filename for pattern in ignore_patterns):
18
+ continue
19
+
20
+ file_path = os.path.join(root, filename)
21
+ files.append(file_path)
22
+
23
+ return files
24
+
25
+ def format_file_size(size_bytes: int) -> str:
26
+ """Format file size in human readable format"""
27
+ if size_bytes == 0:
28
+ return "0B"
29
+
30
+ size_names = ["B", "KB", "MB", "GB"]
31
+ i = 0
32
+ while size_bytes >= 1024 and i < len(size_names) - 1:
33
+ size_bytes /= 1024.0
34
+ i += 1
35
+
36
+ return f"{size_bytes:.1f}{size_names[i]}"
@@ -0,0 +1,278 @@
1
+ Metadata-Version: 2.4
2
+ Name: simple-vcs
3
+ Version: 1.0.0
4
+ Summary: A simple version control system written in Python
5
+ Home-page: https://github.com/yourusername/simple-vcs
6
+ Author: Your Name
7
+ Author-email: your.email@example.com
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.7
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Requires-Python: >=3.7
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: click>=7.0
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: home-page
27
+ Dynamic: license-file
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
31
+
32
+ # README.md
33
+ # SimpleVCS
34
+
35
+ A simple version control system written in Python that provides basic VCS functionality similar to Git.
36
+
37
+ ## Features
38
+
39
+ - Initialize repositories
40
+ - Add files to staging area
41
+ - Commit changes with messages or timestamps
42
+ - View commit history with detailed information
43
+ - Show differences between commits
44
+ - Repository status tracking
45
+ - Cross-platform compatibility
46
+ - Both CLI and Python API support
47
+
48
+ ## Installation
49
+
50
+ ### From PyPI (when published)
51
+ ```bash
52
+ pip install simple-vcs
53
+ ```
54
+
55
+ ### From Source
56
+ ```bash
57
+ # Clone the repository
58
+ git clone https://github.com/muhammadsufiyanbaig/simple_vcs.git
59
+ cd simple-vcs
60
+
61
+ # Install in development mode
62
+ pip install -e .
63
+
64
+ # Or install normally
65
+ pip install .
66
+ ```
67
+
68
+ ## Quick Start
69
+
70
+ ```bash
71
+ # Initialize a new repository
72
+ svcs init
73
+
74
+ # Create a sample file
75
+ echo "Hello World" > hello.txt
76
+
77
+ # Add file to staging area
78
+ svcs add hello.txt
79
+
80
+ # Commit the changes
81
+ svcs commit -m "Add hello.txt"
82
+
83
+ # View commit history
84
+ svcs log
85
+ ```
86
+
87
+ ## Usage
88
+
89
+ ### Command Line Interface
90
+
91
+ #### Repository Management
92
+ ```bash
93
+ # Initialize a new repository in current directory
94
+ svcs init
95
+
96
+ # Initialize in specific directory
97
+ svcs init --path /path/to/project
98
+ ```
99
+
100
+ #### File Operations
101
+ ```bash
102
+ # Add single file
103
+ svcs add filename.txt
104
+
105
+ # Add multiple files
106
+ svcs add file1.txt file2.py file3.md
107
+
108
+ # Check repository status
109
+ svcs status
110
+ ```
111
+
112
+ #### Commit Operations
113
+ ```bash
114
+ # Commit with message
115
+ svcs commit -m "Your commit message"
116
+
117
+ # Commit with auto-generated timestamp
118
+ svcs commit
119
+
120
+ # View commit history
121
+ svcs log
122
+
123
+ # View limited commit history
124
+ svcs log --limit 5
125
+ ```
126
+
127
+ #### Viewing Differences
128
+ ```bash
129
+ # Show diff between last two commits
130
+ svcs diff
131
+
132
+ # Show diff between specific commits
133
+ svcs diff --c1 1 --c2 3
134
+
135
+ # Show diff between commit 2 and latest
136
+ svcs diff --c1 2
137
+ ```
138
+
139
+ ### Python API
140
+
141
+ ```python
142
+ from simple_vcs import SimpleVCS
143
+
144
+ # Create VCS instance
145
+ vcs = SimpleVCS("./my_project")
146
+
147
+ # Initialize repository
148
+ vcs.init_repo()
149
+
150
+ # Add files
151
+ vcs.add_file("example.txt")
152
+ vcs.add_file("script.py")
153
+
154
+ # Commit changes
155
+ vcs.commit("Initial commit with example files")
156
+
157
+ # Show commit history
158
+ vcs.show_log()
159
+
160
+ # Show differences between commits
161
+ vcs.show_diff(1, 2)
162
+
163
+ # Check repository status
164
+ vcs.status()
165
+ ```
166
+
167
+ ## Advanced Usage
168
+
169
+ ### Working with Multiple Files
170
+ ```python
171
+ from simple_vcs import SimpleVCS
172
+ from simple_vcs.utils import get_all_files
173
+
174
+ vcs = SimpleVCS()
175
+ vcs.init_repo()
176
+
177
+ # Add all Python files in current directory
178
+ python_files = [f for f in get_all_files(".") if f.endswith('.py')]
179
+ for file in python_files:
180
+ vcs.add_file(file)
181
+
182
+ vcs.commit("Add all Python files")
183
+ ```
184
+
185
+ ### Repository Structure
186
+ When initialized, SimpleVCS creates a `.svcs` directory containing:
187
+ ```
188
+ .svcs/
189
+ ├── objects/ # File content storage (hashed)
190
+ ├── commits.json # Commit history and metadata
191
+ ├── staging.json # Currently staged files
192
+ └── HEAD # Current commit reference
193
+ ```
194
+
195
+ ## Requirements
196
+
197
+ - Python 3.7 or higher
198
+ - click>=7.0 (for CLI functionality)
199
+
200
+ ## Development
201
+
202
+ ### Setting up Development Environment
203
+ ```bash
204
+ # Clone the repository
205
+ git clone https://github.com/yourusername/simple-vcs.git
206
+ cd simple-vcs
207
+
208
+ # Create virtual environment
209
+ python -m venv venv
210
+ source venv/bin/activate # On Windows: venv\Scripts\activate
211
+
212
+ # Install in development mode
213
+ pip install -e .
214
+
215
+ # Install development dependencies
216
+ pip install pytest pytest-cov black flake8
217
+ ```
218
+
219
+ ### Running Tests
220
+ ```bash
221
+ # Run all tests
222
+ pytest
223
+
224
+ # Run with coverage
225
+ pytest --cov=simple_vcs
226
+
227
+ # Run specific test file
228
+ pytest tests/test_core.py
229
+ ```
230
+
231
+ ## Contributing
232
+
233
+ 1. Fork the repository
234
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
235
+ 3. Make your changes
236
+ 4. Add tests for your changes
237
+ 5. Ensure tests pass (`pytest`)
238
+ 6. Commit your changes (`git commit -m 'Add amazing feature'`)
239
+ 7. Push to the branch (`git push origin feature/amazing-feature`)
240
+ 8. Open a Pull Request
241
+
242
+ ## Publishing to PyPI
243
+
244
+ ```bash
245
+ # Install build tools
246
+ pip install build twine
247
+
248
+ # Build the package
249
+ python -m build
250
+
251
+ # Upload to PyPI (requires PyPI account)
252
+ twine upload dist/*
253
+ ```
254
+
255
+ ## Limitations
256
+
257
+ This is a simple implementation for educational purposes. It lacks advanced features like:
258
+ - Branching and merging
259
+ - Remote repositories
260
+ - File conflict resolution
261
+ - Large file handling
262
+ - Advanced diff algorithms
263
+
264
+ ## License
265
+
266
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
267
+
268
+ ## Author
269
+
270
+ Your Name - your.email@example.com
271
+
272
+ ## Changelog
273
+
274
+ ### Version 1.0.0
275
+ - Initial release
276
+ - Basic VCS functionality (init, add, commit, log, diff, status)
277
+ - CLI and Python API support
278
+ - Cross-platform compatibility
@@ -0,0 +1,15 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ requirements.txt
5
+ setup.py
6
+ simple_vcs/__init__.py
7
+ simple_vcs/cli.py
8
+ simple_vcs/core.py
9
+ simple_vcs/utils.py
10
+ simple_vcs.egg-info/PKG-INFO
11
+ simple_vcs.egg-info/SOURCES.txt
12
+ simple_vcs.egg-info/dependency_links.txt
13
+ simple_vcs.egg-info/entry_points.txt
14
+ simple_vcs.egg-info/requires.txt
15
+ simple_vcs.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ svcs = simple_vcs.cli:main
@@ -0,0 +1 @@
1
+ click>=7.0
@@ -0,0 +1 @@
1
+ simple_vcs