๐ Git Version Control Setup on AlmaLinux: Complete Developer Guide
Ready to master the worldโs most essential development tool? ๐ Today weโll set up Git version control on AlmaLinux - the backbone of modern software development used by 95% of developers worldwide! Whether youโre building web applications, mobile apps, or enterprise software, this guide makes Git setup simple and powerful! ๐ฏ
๐ค Why is Git on AlmaLinux Important?
Git on AlmaLinux delivers incredible benefits:
- ๐ Universal version control - Track every change in your code with complete history
- ๐ง Professional collaboration - Work seamlessly with teams using GitHub, GitLab, and Bitbucket
- ๐ Essential dev skill - Required by 99% of programming jobs and development workflows
- ๐ Distributed system - Full backup and sync capabilities across multiple locations
- โญ Branching power - Experiment safely with features while maintaining stable code
๐ฏ What You Need
Before setting up Git on AlmaLinux:
- โ AlmaLinux 9 system (server or desktop)
- โ Root or sudo access
- โ Internet connection for package installation
- โ Basic command line knowledge (weโll guide you!)
- โ GitHub/GitLab account (optional but recommended)
๐ Step 1: Install Git and Essential Tools
Letโs get Git installed with all the tools you need! ๐ ๏ธ
Install Git from AlmaLinux Repository
# Update system packages first
sudo dnf update -y
# Install Git version control system
sudo dnf install -y git
# Install additional development tools
sudo dnf install -y git-all git-subtree git-lfs
# Install helpful utilities
sudo dnf install -y curl wget vim nano tree
# Verify Git installation
git --version
# git version 2.39.3
# Check available Git commands
git help -a | head -20
# Check Git installation location
which git
echo "โ
Git installed successfully!"
Install Latest Git from Source (Optional)
# Install development dependencies for compiling Git
sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y gettext-devel openssl-devel perl-CPAN perl-devel zlib-devel curl-devel
# Download latest Git source
cd /tmp
curl -L https://github.com/git/git/archive/v2.43.0.tar.gz -o git-2.43.0.tar.gz
tar -xzf git-2.43.0.tar.gz
cd git-2.43.0
# Compile and install Git
make configure
./configure --prefix=/usr/local
make all
sudo make install
# Verify latest version
/usr/local/bin/git --version
echo "โ
Latest Git compiled and installed!"
๐ง Step 2: Configure Git for Development
Set up your Git identity and preferences:
Basic Git Configuration
# Configure your identity (REQUIRED for commits)
git config --global user.name "Your Full Name"
git config --global user.email "[email protected]"
# Set default branch name to 'main'
git config --global init.defaultBranch main
# Configure default editor
git config --global core.editor "vim"
# or: git config --global core.editor "nano"
# Configure line ending handling (important for cross-platform)
git config --global core.autocrlf input
git config --global core.safecrlf true
# Configure colors for better readability
git config --global color.ui auto
git config --global color.status auto
git config --global color.branch auto
git config --global color.diff auto
# Set up credential caching (remember passwords)
git config --global credential.helper cache
git config --global credential.helper 'cache --timeout=3600'
# View all configurations
git config --global --list
echo "โ
Git configured with your identity and preferences!"
Advanced Git Configuration
# Create comprehensive Git configuration
tee ~/.gitconfig << 'EOF'
[user]
name = Your Full Name
email = [email protected]
[init]
defaultBranch = main
[core]
editor = vim
autocrlf = input
safecrlf = true
excludesfile = ~/.gitignore_global
[color]
ui = auto
status = auto
branch = auto
diff = auto
[alias]
# Shortcuts for common commands
st = status
co = checkout
br = branch
ci = commit
unstage = reset HEAD --
last = log -1 HEAD
visual = !gitk
# Advanced aliases
lg = log --oneline --decorate --graph --all
logs = log --show-signature
amend = commit --amend
uncommit = reset --soft HEAD~1
unstage = reset HEAD
# Branch management
branches = branch -a
remotes = remote -v
# Diff and merge
conflicts = diff --name-only --diff-filter=U
dt = difftool
mt = mergetool
[push]
default = simple
followTags = true
[pull]
rebase = false
[merge]
tool = vimdiff
[diff]
tool = vimdiff
[credential]
helper = cache --timeout=3600
[help]
autocorrect = 1
EOF
# Create global gitignore file
tee ~/.gitignore_global << 'EOF'
# Global .gitignore for development environments
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Editor files
*~
.*.swp
.*.swo
*.tmp
# IDE files
.vscode/
.idea/
*.sublime-workspace
*.sublime-project
# Log files
*.log
logs/
# Runtime files
*.pid
*.seed
*.pid.lock
# Dependency directories
node_modules/
bower_components/
# Build outputs
dist/
build/
*.o
*.so
*.exe
# Environment files
.env
.env.local
.env.development
.env.test
.env.production
EOF
echo "โ
Advanced Git configuration completed!"
๐ Step 3: Set Up SSH Keys for GitHub/GitLab
Configure secure authentication for remote repositories:
Generate SSH Key for Git
# Generate SSH key pair for Git authentication
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_git
# Alternative: RSA key if ed25519 not supported
# ssh-keygen -t rsa -b 4096 -C "[email protected]" -f ~/.ssh/id_rsa_git
# Start SSH agent
eval "$(ssh-agent -s)"
# Add SSH key to agent
ssh-add ~/.ssh/id_ed25519_git
# Display public key to add to GitHub/GitLab
echo "๐ Copy this public key to your GitHub/GitLab account:"
cat ~/.ssh/id_ed25519_git.pub
echo "โ
SSH key generated! Add the public key to your Git hosting service."
Configure SSH for Multiple Git Accounts
# Create SSH config for multiple Git accounts
tee ~/.ssh/config << 'EOF'
# GitHub personal account
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_git
AddKeysToAgent yes
# GitHub work account
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
AddKeysToAgent yes
# GitLab account
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_gitlab
AddKeysToAgent yes
# Custom Git server
Host git.company.com
HostName git.company.com
User git
Port 2222
IdentityFile ~/.ssh/id_ed25519_company
AddKeysToAgent yes
EOF
# Set proper permissions
chmod 600 ~/.ssh/config
# Test SSH connection to GitHub
ssh -T [email protected]
echo "โ
SSH configuration for multiple Git accounts completed!"
โ Step 4: Create Your First Git Repository
Set up a complete project with best practices:
Initialize Local Repository
# Create new project directory
mkdir my-awesome-project
cd my-awesome-project
# Initialize Git repository
git init
# Create initial project structure
mkdir -p src tests docs scripts
mkdir -p .github/workflows
# Create README.md
tee README.md << 'EOF'
# My Awesome Project
๐ A fantastic software project built on AlmaLinux!
## Description
This project demonstrates modern development practices with Git version control.
## Features
- โ
Modern Git workflow
- โ
Comprehensive documentation
- โ
Automated testing
- โ
CI/CD integration
## Installation
```bash
git clone https://github.com/yourusername/my-awesome-project.git
cd my-awesome-project
# Add installation steps here
Usage
# Add usage examples here
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contact
Your Name - [email protected]
Project Link: https://github.com/yourusername/my-awesome-project EOF
Create project-specific .gitignore
tee .gitignore << โEOFโ
Project-specific ignore patterns
Build outputs
/build/ /dist/ *.o *.so *.exe
Dependencies
/node_modules/ /vendor/
Environment and config
.env config.local.* *.secret
Logs
*.log /logs/
IDE and editor files
.vscode/ .idea/ *.swp *.swo
OS files
.DS_Store Thumbs.db
Test coverage
/coverage/ /.nyc_output/ EOF
Create a sample source file
tee src/main.py << โEOFโ #!/usr/bin/env python3 """ My Awesome Project - Main Application
This is a sample Python application demonstrating Git best practices. """
def main(): """Main application entry point.""" print(โ๐ Welcome to My Awesome Project!โ) print(โโ Git version control is working!โ) print(โ๐ง Built on AlmaLinux with modern development practicesโ)
if name == โmainโ: main() EOF
Create sample test
tee tests/test_main.py << โEOFโ #!/usr/bin/env python3 """ Tests for main application """
import unittest import sys import os
Add src directory to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(file), โ..โ, โsrcโ))
from main import main
class TestMain(unittest.TestCase): """Test cases for main module."""
def test_main_function_exists(self):
"""Test that main function exists and is callable."""
self.assertTrue(callable(main))
def test_main_runs_without_error(self):
"""Test that main function runs without raising exceptions."""
try:
main()
except Exception as e:
self.fail(f"main() raised {type(e).__name__} unexpectedly!")
if name == โmainโ: unittest.main() EOF
Create LICENSE file
tee LICENSE << โEOFโ MIT License
Copyright (c) 2025 Your Name
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the โSoftwareโ), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED โAS ISโ, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. EOF
Add all files to Git
git add .
Make initial commit
git commit -m โ๐ Initial commit: Set up project structure
- Add comprehensive README.md with project documentation
- Create src/ directory with sample Python application
- Add tests/ directory with basic unit tests
- Include MIT license for open source compatibility
- Configure .gitignore for Python and common development files
- Establish modern project structure for scalabilityโ
View the commit
git log โoneline git status
echo โโ First Git repository created with professional structure!โ
### Connect to Remote Repository
```bash
# Create repository on GitHub/GitLab first, then:
# Add remote origin (replace with your repository URL)
git remote add origin [email protected]:yourusername/my-awesome-project.git
# Verify remote
git remote -v
# Push to remote repository
git push -u origin main
# Clone repository (example for others)
# git clone [email protected]:yourusername/my-awesome-project.git
echo "โ
Repository connected to remote Git hosting service!"
๐ฎ Quick Examples
Example 1: Complete Git Workflow for Team Development ๐ฅ
# Professional Git workflow demonstration
echo "=== Professional Git Team Workflow ==="
cd my-awesome-project
# Create and switch to feature branch
git checkout -b feature/user-authentication
# Make changes to implement user authentication
tee src/auth.py << 'EOF'
#!/usr/bin/env python3
"""
User Authentication Module
Provides secure user authentication functionality.
"""
import hashlib
import secrets
class UserAuth:
"""Handle user authentication operations."""
def __init__(self):
"""Initialize authentication system."""
self.users = {}
def hash_password(self, password: str) -> str:
"""Securely hash a password."""
salt = secrets.token_hex(16)
pwd_hash = hashlib.pbkdf2_hmac('sha256',
password.encode('utf-8'),
salt.encode('utf-8'),
100000)
return f"{salt}:{pwd_hash.hex()}"
def verify_password(self, password: str, hashed: str) -> bool:
"""Verify password against hash."""
try:
salt, pwd_hash = hashed.split(':')
return hashlib.pbkdf2_hmac('sha256',
password.encode('utf-8'),
salt.encode('utf-8'),
100000).hex() == pwd_hash
except ValueError:
return False
def register_user(self, username: str, password: str) -> bool:
"""Register a new user."""
if username in self.users:
return False
self.users[username] = self.hash_password(password)
return True
def authenticate(self, username: str, password: str) -> bool:
"""Authenticate user credentials."""
if username not in self.users:
return False
return self.verify_password(password, self.users[username])
EOF
# Update main.py to use authentication
tee src/main.py << 'EOF'
#!/usr/bin/env python3
"""
My Awesome Project - Main Application
Enhanced version with user authentication capability.
"""
from auth import UserAuth
def main():
"""Main application entry point."""
print("๐ Welcome to My Awesome Project!")
print("โ
Git version control is working!")
print("๐ง Built on AlmaLinux with modern development practices")
print("๐ Now featuring user authentication!")
# Demo authentication
auth = UserAuth()
# Register demo user
if auth.register_user("demo", "password123"):
print("๐ค Demo user registered successfully!")
# Test authentication
if auth.authenticate("demo", "password123"):
print("๐ Authentication successful!")
else:
print("โ Authentication failed!")
if __name__ == "__main__":
main()
EOF
# Add tests for authentication
tee tests/test_auth.py << 'EOF'
#!/usr/bin/env python3
"""
Tests for authentication module
"""
import unittest
import sys
import os
# Add src directory to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from auth import UserAuth
class TestUserAuth(unittest.TestCase):
"""Test cases for UserAuth class."""
def setUp(self):
"""Set up test fixtures."""
self.auth = UserAuth()
def test_password_hashing(self):
"""Test password hashing functionality."""
password = "testpassword123"
hashed = self.auth.hash_password(password)
# Hash should not equal original password
self.assertNotEqual(password, hashed)
# Hash should contain salt and hash parts
self.assertIn(':', hashed)
# Verify password works
self.assertTrue(self.auth.verify_password(password, hashed))
def test_user_registration(self):
"""Test user registration."""
username = "testuser"
password = "testpass123"
# Registration should succeed
self.assertTrue(self.auth.register_user(username, password))
# Duplicate registration should fail
self.assertFalse(self.auth.register_user(username, password))
def test_user_authentication(self):
"""Test user authentication."""
username = "authuser"
password = "authpass123"
# Register user first
self.auth.register_user(username, password)
# Authentication should succeed with correct credentials
self.assertTrue(self.auth.authenticate(username, password))
# Authentication should fail with wrong password
self.assertFalse(self.auth.authenticate(username, "wrongpass"))
# Authentication should fail with nonexistent user
self.assertFalse(self.auth.authenticate("nonexistent", password))
if __name__ == '__main__':
unittest.main()
EOF
# Stage changes
git add src/auth.py src/main.py tests/test_auth.py
# Commit with descriptive message
git commit -m "โจ Add user authentication system
Features:
- Secure password hashing with PBKDF2 and random salt
- User registration with duplicate prevention
- Password verification and authentication
- Comprehensive unit tests with 100% coverage
- Integration with main application
Technical details:
- Uses hashlib.pbkdf2_hmac for secure password hashing
- 100,000 iterations for strong protection against brute force
- Random salt generation using secrets module
- Proper error handling and validation"
# Push feature branch to remote
git push -u origin feature/user-authentication
# Switch back to main branch
git checkout main
# Simulate code review approval and merge
git merge feature/user-authentication
# Clean up feature branch
git branch -d feature/user-authentication
git push origin --delete feature/user-authentication
# Push updated main branch
git push origin main
# View git history
git log --oneline --graph --decorate
echo "โ
Complete Git team workflow demonstrated!"
echo "๐ Feature branch created, developed, tested, and merged"
echo "๐งน Cleanup completed with branch deletion"
Example 2: Git Branching Strategies and Advanced Workflows ๐ณ
# Advanced Git branching strategies
echo "=== Advanced Git Branching Strategies ==="
cd my-awesome-project
# Create development branch for ongoing work
git checkout -b develop
# Create and work on multiple features simultaneously
echo "๐ง Working on multiple features..."
# Feature 1: Add configuration system
git checkout -b feature/config-system develop
tee src/config.py << 'EOF'
#!/usr/bin/env python3
"""
Configuration Management System
Handles application configuration with environment variable support.
"""
import os
import json
from pathlib import Path
class Config:
"""Application configuration manager."""
def __init__(self, config_file: str = "config.json"):
"""Initialize configuration system."""
self.config_file = Path(config_file)
self.config = self._load_config()
def _load_config(self) -> dict:
"""Load configuration from file and environment."""
config = {}
# Load from file if exists
if self.config_file.exists():
with open(self.config_file, 'r') as f:
config = json.load(f)
# Override with environment variables
env_mapping = {
'DATABASE_URL': 'database.url',
'DEBUG': 'app.debug',
'SECRET_KEY': 'app.secret_key',
'PORT': 'server.port'
}
for env_var, config_path in env_mapping.items():
value = os.getenv(env_var)
if value is not None:
self._set_nested_value(config, config_path, value)
return config
def _set_nested_value(self, config: dict, path: str, value: str):
"""Set nested configuration value."""
keys = path.split('.')
current = config
for key in keys[:-1]:
current = current.setdefault(key, {})
# Convert value to appropriate type
if value.lower() in ('true', 'false'):
value = value.lower() == 'true'
elif value.isdigit():
value = int(value)
current[keys[-1]] = value
def get(self, path: str, default=None):
"""Get configuration value."""
keys = path.split('.')
current = self.config
try:
for key in keys:
current = current[key]
return current
except (KeyError, TypeError):
return default
def set(self, path: str, value):
"""Set configuration value."""
self._set_nested_value(self.config, path, str(value))
def save(self):
"""Save configuration to file."""
with open(self.config_file, 'w') as f:
json.dump(self.config, f, indent=2)
EOF
# Commit feature
git add src/config.py
git commit -m "โจ Add configuration management system
- Support for JSON configuration files
- Environment variable override capability
- Nested configuration value access
- Automatic type conversion (bool, int)
- Save configuration changes to file"
# Feature 2: Add logging system (on different branch)
git checkout develop
git checkout -b feature/logging-system
tee src/logger.py << 'EOF'
#!/usr/bin/env python3
"""
Advanced Logging System
Provides structured logging with multiple output formats and levels.
"""
import logging
import logging.handlers
import json
import sys
from datetime import datetime
from pathlib import Path
class StructuredLogger:
"""Advanced logging system with structured output."""
def __init__(self, name: str = "app", level: str = "INFO"):
"""Initialize logging system."""
self.logger = logging.getLogger(name)
self.logger.setLevel(getattr(logging, level.upper()))
# Clear any existing handlers
self.logger.handlers.clear()
# Set up formatters
self._setup_formatters()
self._setup_handlers()
def _setup_formatters(self):
"""Set up different log formatters."""
# Console formatter (human readable)
self.console_formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# JSON formatter (machine readable)
self.json_formatter = self._create_json_formatter()
def _create_json_formatter(self):
"""Create JSON log formatter."""
class JSONFormatter(logging.Formatter):
def format(self, record):
log_entry = {
'timestamp': datetime.utcnow().isoformat(),
'level': record.levelname,
'logger': record.name,
'message': record.getMessage(),
'module': record.module,
'function': record.funcName,
'line': record.lineno
}
if record.exc_info:
log_entry['exception'] = self.formatException(record.exc_info)
return json.dumps(log_entry)
return JSONFormatter()
def _setup_handlers(self):
"""Set up log handlers."""
# Console handler
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(self.console_formatter)
self.logger.addHandler(console_handler)
# File handler with rotation
log_dir = Path("logs")
log_dir.mkdir(exist_ok=True)
file_handler = logging.handlers.RotatingFileHandler(
log_dir / "app.log",
maxBytes=10*1024*1024, # 10MB
backupCount=5
)
file_handler.setFormatter(self.json_formatter)
self.logger.addHandler(file_handler)
def debug(self, message, **kwargs):
"""Log debug message."""
self.logger.debug(self._format_message(message, **kwargs))
def info(self, message, **kwargs):
"""Log info message."""
self.logger.info(self._format_message(message, **kwargs))
def warning(self, message, **kwargs):
"""Log warning message."""
self.logger.warning(self._format_message(message, **kwargs))
def error(self, message, **kwargs):
"""Log error message."""
self.logger.error(self._format_message(message, **kwargs))
def critical(self, message, **kwargs):
"""Log critical message."""
self.logger.critical(self._format_message(message, **kwargs))
def _format_message(self, message, **kwargs):
"""Format message with additional context."""
if kwargs:
return f"{message} | Context: {json.dumps(kwargs)}"
return message
EOF
git add src/logger.py
git commit -m "โจ Add advanced logging system
- Structured JSON logging for machine processing
- Console logging with human-readable format
- Automatic log rotation (10MB, 5 backups)
- Multiple log levels with context support
- Exception tracking and formatting
- Configurable logger names and levels"
# Merge features into develop
git checkout develop
git merge feature/config-system
git merge feature/logging-system
# Clean up feature branches
git branch -d feature/config-system
git branch -d feature/logging-system
# Create release branch
git checkout -b release/v1.1.0
# Update version and prepare for release
tee VERSION << 'EOF'
1.1.0
EOF
# Update README for release
sed -i 's/A fantastic software project/A feature-rich software project/' README.md
git add VERSION README.md
git commit -m "๐ Prepare release v1.1.0
- Bump version to 1.1.0
- Update project description
- Prepare for production deployment
Features in this release:
- User authentication system
- Configuration management
- Advanced logging system
- Comprehensive test suite"
# Merge release into main
git checkout main
git merge release/v1.1.0
# Create release tag
git tag -a v1.1.0 -m "Release version 1.1.0
Major Features:
- User authentication with secure password hashing
- Configuration management with environment variable support
- Advanced logging system with JSON structured output
- Comprehensive test coverage
Technical Improvements:
- Modern Git workflow with feature branches
- Automated testing integration
- Professional project structure
- Comprehensive documentation"
# Merge back to develop
git checkout develop
git merge release/v1.1.0
# Clean up release branch
git branch -d release/v1.1.0
# Push everything
git push origin main develop
git push origin v1.1.0
# Show branching history
git log --oneline --graph --all --decorate
echo "โ
Advanced Git branching workflow completed!"
echo "๐ท๏ธ Release v1.1.0 created and tagged"
echo "๐ณ Clean branch structure maintained"
Example 3: Git Automation and Integration Scripts ๐ค
# Git automation and integration tools
echo "=== Git Automation and Integration Tools ==="
# Create Git hooks for automation
mkdir -p .git/hooks
# Pre-commit hook for code quality
tee .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# Pre-commit hook for code quality checks
echo "๐ Running pre-commit checks..."
# Check for Python syntax errors
python_files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.py$')
if [ -n "$python_files" ]; then
echo "๐ Checking Python syntax..."
for file in $python_files; do
python -m py_compile "$file"
if [ $? -ne 0 ]; then
echo "โ Python syntax error in $file"
exit 1
fi
done
echo "โ
Python syntax check passed"
fi
# Run tests if they exist
if [ -d "tests" ]; then
echo "๐งช Running tests..."
python -m pytest tests/ -q
if [ $? -ne 0 ]; then
echo "โ Tests failed"
exit 1
fi
echo "โ
All tests passed"
fi
# Check for large files
large_files=$(git diff --cached --name-only --diff-filter=ACM | xargs ls -la 2>/dev/null | awk '$5 > 1048576 {print $9, $5}')
if [ -n "$large_files" ]; then
echo "โ ๏ธ Large files detected (>1MB):"
echo "$large_files"
echo "Consider using Git LFS for large files"
fi
# Check commit message format (if committing)
if [ -n "$1" ]; then
commit_msg=$(cat "$1")
if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .+"; then
echo "โ ๏ธ Commit message doesn't follow conventional format"
echo "Expected: type(scope): description"
echo "Types: feat, fix, docs, style, refactor, test, chore"
fi
fi
echo "โ
Pre-commit checks completed successfully"
EOF
chmod +x .git/hooks/pre-commit
# Post-commit hook for notifications
tee .git/hooks/post-commit << 'EOF'
#!/bin/bash
# Post-commit hook for notifications and automation
commit_hash=$(git rev-parse HEAD)
commit_msg=$(git log -1 --pretty=format:"%s")
author=$(git log -1 --pretty=format:"%an")
echo "๐ Commit completed: $commit_hash"
echo "๐ค Author: $author"
echo "๐ฌ Message: $commit_msg"
# Optional: Send notification (uncomment if needed)
# curl -X POST -H 'Content-type: application/json' \
# --data "{\"text\":\"New commit by $author: $commit_msg\"}" \
# YOUR_WEBHOOK_URL
EOF
chmod +x .git/hooks/post-commit
# Create Git workflow automation script
tee git-workflow.sh << 'EOF'
#!/bin/bash
# Git Workflow Automation Script
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to create feature branch
create_feature() {
local feature_name="$1"
if [ -z "$feature_name" ]; then
print_error "Feature name is required"
echo "Usage: $0 feature <feature-name>"
exit 1
fi
print_status "Creating feature branch: $feature_name"
# Switch to develop branch and pull latest
git checkout develop
git pull origin develop
# Create and switch to feature branch
git checkout -b "feature/$feature_name"
print_success "Feature branch 'feature/$feature_name' created and checked out"
}
# Function to finish feature
finish_feature() {
local current_branch=$(git branch --show-current)
if [[ ! "$current_branch" =~ ^feature/ ]]; then
print_error "Not on a feature branch"
exit 1
fi
print_status "Finishing feature branch: $current_branch"
# Run tests before merge
if [ -d "tests" ]; then
print_status "Running tests..."
python -m pytest tests/ || {
print_error "Tests failed. Fix tests before finishing feature."
exit 1
}
fi
# Switch to develop and merge
git checkout develop
git pull origin develop
git merge --no-ff "$current_branch"
# Push develop
git push origin develop
# Delete feature branch locally and remotely
git branch -d "$current_branch"
git push origin --delete "$current_branch" 2>/dev/null || true
print_success "Feature '$current_branch' merged and cleaned up"
}
# Function to create release
create_release() {
local version="$1"
if [ -z "$version" ]; then
print_error "Version is required"
echo "Usage: $0 release <version>"
exit 1
fi
print_status "Creating release: $version"
# Switch to develop and create release branch
git checkout develop
git pull origin develop
git checkout -b "release/$version"
# Update version file
echo "$version" > VERSION
git add VERSION
git commit -m "๐ Bump version to $version"
print_success "Release branch 'release/$version' created"
print_warning "Update CHANGELOG.md and test thoroughly before finishing release"
}
# Function to finish release
finish_release() {
local current_branch=$(git branch --show-current)
if [[ ! "$current_branch" =~ ^release/ ]]; then
print_error "Not on a release branch"
exit 1
fi
local version=${current_branch#release/}
print_status "Finishing release: $version"
# Merge into main
git checkout main
git pull origin main
git merge --no-ff "$current_branch"
# Create tag
git tag -a "v$version" -m "Release version $version"
# Merge back into develop
git checkout develop
git merge --no-ff "$current_branch"
# Push everything
git push origin main develop
git push origin "v$version"
# Delete release branch
git branch -d "$current_branch"
print_success "Release v$version completed and tagged"
}
# Function to show Git status overview
status_overview() {
print_status "Git Repository Status Overview"
echo
# Current branch
current_branch=$(git branch --show-current)
print_status "Current branch: $current_branch"
# Repository status
if git diff-index --quiet HEAD --; then
print_success "Working directory is clean"
else
print_warning "Working directory has uncommitted changes"
git status --porcelain
fi
# Branch information
echo
print_status "Local branches:"
git branch
echo
print_status "Remote branches:"
git branch -r
# Recent commits
echo
print_status "Recent commits:"
git log --oneline -10
# Unmerged branches
echo
unmerged=$(git branch --no-merged main 2>/dev/null | grep -v main | grep -v develop || true)
if [ -n "$unmerged" ]; then
print_warning "Unmerged branches:"
echo "$unmerged"
else
print_success "All branches are merged"
fi
}
# Main script logic
case "${1:-status}" in
"feature")
create_feature "$2"
;;
"finish-feature")
finish_feature
;;
"release")
create_release "$2"
;;
"finish-release")
finish_release
;;
"status"|"overview")
status_overview
;;
"help"|*)
echo "Git Workflow Automation Script"
echo "=============================="
echo
echo "Usage: $0 [command] [options]"
echo
echo "Commands:"
echo " feature <name> - Create and switch to feature branch"
echo " finish-feature - Merge current feature branch to develop"
echo " release <version> - Create release branch"
echo " finish-release - Merge release to main and develop, create tag"
echo " status|overview - Show repository status overview"
echo " help - Show this help message"
echo
echo "Examples:"
echo " $0 feature user-login"
echo " $0 finish-feature"
echo " $0 release 1.2.0"
echo " $0 status"
;;
esac
EOF
chmod +x git-workflow.sh
# Create Git statistics script
tee git-stats.sh << 'EOF'
#!/bin/bash
# Git Repository Statistics
echo "๐ Git Repository Statistics"
echo "============================"
echo
# Basic repository info
echo "๐ Repository: $(basename $(git rev-parse --show-toplevel))"
echo "๐ฟ Current branch: $(git branch --show-current)"
echo "๐ Total commits: $(git rev-list --all --count)"
echo
# Commit statistics by author
echo "๐ฅ Commits by Author:"
git shortlog -sn --all | head -10
echo
# Recent activity
echo "๐
Recent Activity (last 30 days):"
git log --since="30 days ago" --pretty=format:"%ad %an: %s" --date=short | head -10
echo
# File statistics
echo "๐ Repository Statistics:"
echo "Files tracked: $(git ls-files | wc -l)"
echo "Total lines: $(git ls-files | xargs wc -l | tail -1 | awk '{print $1}')"
echo
# Language breakdown (if cloc is available)
if command -v cloc &> /dev/null; then
echo "๐ข Language Breakdown:"
cloc --git .
else
echo "๐ก Install 'cloc' for detailed language statistics"
fi
# Branch information
echo
echo "๐ณ Branch Information:"
echo "Local branches: $(git branch | wc -l)"
echo "Remote branches: $(git branch -r | wc -l)"
echo "Unmerged branches: $(git branch --no-merged main 2>/dev/null | grep -v main | wc -l)"
# Repository size
echo
echo "๐พ Repository Size:"
du -sh .git
EOF
chmod +x git-stats.sh
# Test automation scripts
./git-workflow.sh status
./git-stats.sh
echo "โ
Git automation and integration tools created!"
echo "๐ง Available tools:"
echo " - ./git-workflow.sh - Automated Git workflow management"
echo " - ./git-stats.sh - Repository statistics and analysis"
echo " - .git/hooks/pre-commit - Automated code quality checks"
echo " - .git/hooks/post-commit - Post-commit notifications"
๐จ Fix Common Problems
Problem 1: Git Authentication Issues โ
Symptoms:
- Permission denied when pushing/pulling
- Authentication failures with remote repositories
Try this:
# Check current remote URLs
git remote -v
# Update remote URL to use SSH
git remote set-url origin [email protected]:username/repository.git
# Test SSH connection
ssh -T [email protected]
# Generate new SSH key if needed
ssh-keygen -t ed25519 -C "[email protected]"
# Add SSH key to agent
ssh-add ~/.ssh/id_ed25519
# Add public key to GitHub/GitLab account
cat ~/.ssh/id_ed25519.pub
# Clear credential cache if using HTTPS
git config --global --unset credential.helper
git config --global credential.helper cache
Problem 2: Git Conflicts and Merge Issues โ
Try this:
# Check for conflicts
git status
# Resolve conflicts manually in editor, then:
git add .
git commit -m "Resolve merge conflicts"
# Use merge tool for complex conflicts
git mergetool
# Abort merge if needed
git merge --abort
# Use rebase instead of merge for cleaner history
git rebase main
# Fix conflicts, then:
git rebase --continue
# Check diff before committing
git diff --cached
Problem 3: Accidentally Committed Wrong Files โ
Check these solutions:
# Undo last commit but keep changes
git reset --soft HEAD~1
# Undo last commit and discard changes
git reset --hard HEAD~1
# Remove file from staging area
git reset HEAD filename
# Remove file from Git but keep locally
git rm --cached filename
# Amend last commit
git add forgotten-file
git commit --amend
# Remove sensitive data from history (DANGEROUS)
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch sensitive-file' \
--prune-empty --tag-name-filter cat -- --all
# Alternative: Use git filter-repo (recommended)
pip install git-filter-repo
git filter-repo --invert-paths --path sensitive-file
๐ Simple Commands Summary
Task | Command |
---|---|
๐ง Initialize repository | git init |
๐ Check status | git status |
๐ Add files | git add . |
๐ Commit changes | git commit -m "message" |
โ๏ธ Push to remote | git push origin main |
๐ Clone repository | git clone <url> |
๐ Pull changes | git pull |
๐ก Tips for Success
- Commit early and often ๐ - Make small, focused commits with clear messages
- Use descriptive commit messages ๐ - Follow conventional commit format
- Branch for features ๐ - Keep main branch stable with feature branches
- Review before committing ๐ - Use
git diff --cached
to check staged changes - Regular backups ๐ - Push to remote repositories frequently
๐ What You Learned
Congratulations! Now you can:
- โ Install and configure Git with professional settings and SSH authentication
- โ Create repositories with proper project structure and best practices
- โ Master branching workflows including feature branches and release management
- โ Set up automation tools and Git hooks for improved development workflow
- โ Troubleshoot common Git issues and resolve merge conflicts effectively
๐ฏ Why This Matters
Your Git setup on AlmaLinux provides:
- ๐ Professional development workflow essential for modern software engineering
- ๐ Secure code collaboration with teams worldwide using industry standards
- ๐ Complete project history with the ability to track every change and revert mistakes
- โก Advanced branching capabilities enabling parallel development and safe experimentation
Remember: Git is the backbone of modern software development - over 95% of developers use Git daily, and itโs required by virtually every tech company. With your professional Git setup on AlmaLinux, youโre ready for any development project, from personal repos to enterprise-scale collaboration! โญ
Youโve successfully mastered Git version control setup on AlmaLinux! Your development environment is now equipped with professional-grade version control capabilities! ๐