Basic File Version Control System
Abstract
Basic File Version Control System is a Python project that tracks changes to files and allows users to revert to previous versions. It demonstrates file management, hashing, and simple CLI interaction. This project is ideal for learning about versioning, backups, and automation in Python.
Prerequisites
- Python 3.6 or above
- os, shutil, hashlib (built-in)
- datetime (built-in)
Before you Start
Ensure Python is installed. No external packages are required.
Getting Started
- Create a folder named
file-version-control
file-version-control
. - Create a file named
basic_file_version_control_system.py
basic_file_version_control_system.py
. - Copy the code below into your file.
⚙️ Basic File Version Control System
Basic File Version Control System
"""
Basic File Version Control System
A Python-based version control system with the following features:
- Track changes to files
- Commit changes with messages
- Revert to previous versions
"""
import os
import hashlib
import pickle
from datetime import datetime
class BasicFileVersionControl:
def __init__(self, repo_path):
self.repo_path = repo_path
self.version_file = os.path.join(repo_path, ".versions.pkl")
self.versions = {}
if not os.path.exists(repo_path):
os.makedirs(repo_path)
if os.path.exists(self.version_file):
with open(self.version_file, "rb") as f:
self.versions = pickle.load(f)
def hash_file(self, file_path):
"""Generate a hash for the given file."""
hasher = hashlib.sha256()
with open(file_path, "rb") as f:
while chunk := f.read(8192):
hasher.update(chunk)
return hasher.hexdigest()
def commit(self, file_path, message):
"""Commit changes to the file."""
if not os.path.exists(file_path):
print("File does not exist.")
return
file_hash = self.hash_file(file_path)
file_name = os.path.basename(file_path)
if file_name in self.versions and self.versions[file_name]["hash"] == file_hash:
print("No changes detected.")
return
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
version_data = {
"hash": file_hash,
"timestamp": timestamp,
"message": message,
"content": open(file_path, "rb").read(),
}
self.versions[file_name] = version_data
with open(self.version_file, "wb") as f:
pickle.dump(self.versions, f)
print(f"Committed {file_name} at {timestamp} with message: {message}")
def revert(self, file_name):
"""Revert the file to the last committed version."""
if file_name not in self.versions:
print("No version history found for this file.")
return
with open(os.path.join(self.repo_path, file_name), "wb") as f:
f.write(self.versions[file_name]["content"])
print(f"Reverted {file_name} to the last committed version.")
def log(self, file_name):
"""Display the commit history for the file."""
if file_name not in self.versions:
print("No version history found for this file.")
return
version_data = self.versions[file_name]
print(f"File: {file_name}")
print(f"Last Commit: {version_data['timestamp']}")
print(f"Message: {version_data['message']}")
def main():
repo_path = "./repo"
vcs = BasicFileVersionControl(repo_path)
while True:
print("\nBasic File Version Control System")
print("1. Commit File")
print("2. Revert File")
print("3. View Log")
print("4. Exit")
choice = input("Enter your choice: ")
if choice == "1":
file_path = input("Enter the file path to commit: ")
message = input("Enter commit message: ")
vcs.commit(file_path, message)
elif choice == "2":
file_name = input("Enter the file name to revert: ")
vcs.revert(file_name)
elif choice == "3":
file_name = input("Enter the file name to view log: ")
vcs.log(file_name)
elif choice == "4":
break
else:
print("Invalid choice. Please try again.")
if __name__ == "__main__":
main()
Basic File Version Control System
"""
Basic File Version Control System
A Python-based version control system with the following features:
- Track changes to files
- Commit changes with messages
- Revert to previous versions
"""
import os
import hashlib
import pickle
from datetime import datetime
class BasicFileVersionControl:
def __init__(self, repo_path):
self.repo_path = repo_path
self.version_file = os.path.join(repo_path, ".versions.pkl")
self.versions = {}
if not os.path.exists(repo_path):
os.makedirs(repo_path)
if os.path.exists(self.version_file):
with open(self.version_file, "rb") as f:
self.versions = pickle.load(f)
def hash_file(self, file_path):
"""Generate a hash for the given file."""
hasher = hashlib.sha256()
with open(file_path, "rb") as f:
while chunk := f.read(8192):
hasher.update(chunk)
return hasher.hexdigest()
def commit(self, file_path, message):
"""Commit changes to the file."""
if not os.path.exists(file_path):
print("File does not exist.")
return
file_hash = self.hash_file(file_path)
file_name = os.path.basename(file_path)
if file_name in self.versions and self.versions[file_name]["hash"] == file_hash:
print("No changes detected.")
return
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
version_data = {
"hash": file_hash,
"timestamp": timestamp,
"message": message,
"content": open(file_path, "rb").read(),
}
self.versions[file_name] = version_data
with open(self.version_file, "wb") as f:
pickle.dump(self.versions, f)
print(f"Committed {file_name} at {timestamp} with message: {message}")
def revert(self, file_name):
"""Revert the file to the last committed version."""
if file_name not in self.versions:
print("No version history found for this file.")
return
with open(os.path.join(self.repo_path, file_name), "wb") as f:
f.write(self.versions[file_name]["content"])
print(f"Reverted {file_name} to the last committed version.")
def log(self, file_name):
"""Display the commit history for the file."""
if file_name not in self.versions:
print("No version history found for this file.")
return
version_data = self.versions[file_name]
print(f"File: {file_name}")
print(f"Last Commit: {version_data['timestamp']}")
print(f"Message: {version_data['message']}")
def main():
repo_path = "./repo"
vcs = BasicFileVersionControl(repo_path)
while True:
print("\nBasic File Version Control System")
print("1. Commit File")
print("2. Revert File")
print("3. View Log")
print("4. Exit")
choice = input("Enter your choice: ")
if choice == "1":
file_path = input("Enter the file path to commit: ")
message = input("Enter commit message: ")
vcs.commit(file_path, message)
elif choice == "2":
file_name = input("Enter the file name to revert: ")
vcs.revert(file_name)
elif choice == "3":
file_name = input("Enter the file name to view log: ")
vcs.log(file_name)
elif choice == "4":
break
else:
print("Invalid choice. Please try again.")
if __name__ == "__main__":
main()
- Run the script:
python basic_file_version_control_system.py
python basic_file_version_control_system.py
Explanation
Code Breakdown
- Import modules
import os
import shutil
import hashlib
import datetime
import os
import shutil
import hashlib
import datetime
- Save file versions
def save_version(file_path):
# Save copy with timestamp
pass
def save_version(file_path):
# Save copy with timestamp
pass
- List and restore versions
def list_versions():
# Show available versions
pass
def restore_version(version):
# Restore selected version
pass
def list_versions():
# Show available versions
pass
def restore_version(version):
# Restore selected version
pass
Features
- Tracks file changes
- Saves versions with timestamps
- Allows restoring previous versions
- Simple CLI usage
How It Works
- Copies file to versioned folder on change
- Lists available versions
- Restores selected version
Use Cases
- Backup important files
- Track document changes
- Learn version control basics
Next Steps
You can enhance this project by:
- Adding logging
- Supporting multiple files
- Adding a GUI
- Integrating with cloud storage
- Conflict resolution
Enhanced Version Ideas
def add_logging():
# Log all version actions
pass
def cloud_backup():
# Sync versions to cloud
pass
def add_logging():
# Log all version actions
pass
def cloud_backup():
# Sync versions to cloud
pass
Troubleshooting Tips
- File not saved: Check file path
- Restore not working: Check version folder
- Permission errors: Check file access
Conclusion
This project teaches file management, versioning, and automation. Extend it for more robust version control and features.
Was this page helpful?
Let us know how we did