This is a collection of notes covering Git version control fundamentals and advanced techniques.
Git-SVN Workflow
For teams transitioning from SVN to Git, git-svn provides a bridge:
Initial Setup
# Clone SVN repository
$ git svn clone http://svn-repo -T trunk -b branches -t tags
$ cd svn-repo
Development Workflow
# Update from SVN
$ git svn rebase
# Create and switch to development branch
$ git branch -f development
$ git checkout development
# Make changes
$ gvim hello-world.mkd
$ gvim goodbye-world.mkd
# Commit changes locally
$ git add .
$ git commit -am "added hello world, and good bye"
# Switch back to master and update
$ git checkout master
$ git svn rebase
# Squash merge development changes
$ git merge --squash development
$ git commit # Add squash commit message
# Push to SVN
$ git svn dcommit
# Reset development branch
$ git branch -f development
$ git checkout development
Cleanup Workflow
# Remove files
$ rm goodbye-world.mkd
$ git add -A
$ git commit -am "removed goodbye."
# Update master
$ git checkout master
$ git svn rebase
Repository Management
Merging Git Repositories
When you need to combine multiple repositories while preserving history:
Reference: GitHub Gist
Filter Repository to Specific Directory
# Clone the source repository
$ git clone git@github.com:mokhan/repo1.git
$ cd repo1
# Filter commits to specific directory
$ git filter-branch --subdirectory-filter path/to/subdir -- --all
# Or use git-filter-repo (modern approach)
$ git filter-repo --path path/to/subdir
Merge Repositories
# In target repository
$ git remote add source-repo ../repo1
$ git fetch source-repo
# Merge with history
$ git merge source-repo/main --allow-unrelated-histories
# Clean up
$ git remote remove source-repo
Advanced Filtering
Preserve directory structure during merge:
# Move all files to subdirectory
$ git filter-branch --tree-filter 'mkdir -p new-subdir && git ls-tree --name-only $GIT_COMMIT | xargs -I {} mv {} new-subdir/' HEAD
Core Git Commands
Repository Setup
# Initialize new repository
$ git init
# Clone existing repository
$ git clone <url>
$ git clone --depth 1 <url> # Shallow clone
# Add remote
$ git remote add origin <url>
$ git remote -v # List remotes
Basic Workflow
# Check status
$ git status
$ git status -s # Short format
# Stage changes
$ git add file.txt
$ git add .
$ git add -A # All changes including deletions
# Commit changes
$ git commit -m "commit message"
$ git commit -am "stage and commit"
# Push changes
$ git push origin main
$ git push -u origin feature-branch # Set upstream
Branching and Merging
# List branches
$ git branch
$ git branch -a # Include remote branches
$ git branch -r # Remote branches only
# Create and switch to branch
$ git checkout -b feature-branch
$ git switch -c feature-branch # Modern syntax
# Switch branches
$ git checkout main
$ git switch main # Modern syntax
# Merge branches
$ git merge feature-branch
$ git merge --no-ff feature-branch # Force merge commit
# Delete branch
$ git branch -d feature-branch
$ git push origin --delete feature-branch # Delete remote
History and Inspection
# View commit history
$ git log
$ git log --oneline
$ git log --graph --oneline --all
# View changes
$ git diff
$ git diff --staged
$ git diff HEAD~1
# Show specific commit
$ git show <commit-hash>
# Find changes
$ git blame file.txt
$ git log -p file.txt
Advanced Git Techniques
Rebasing
# Rebase current branch onto main
$ git rebase main
# Interactive rebase for last 3 commits
$ git rebase -i HEAD~3
# Continue after resolving conflicts
$ git rebase --continue
$ git rebase --abort # Cancel rebase
Stashing
# Stash current changes
$ git stash
$ git stash push -m "work in progress"
# List stashes
$ git stash list
# Apply stash
$ git stash pop
$ git stash apply stash@{0}
# Clear stashes
$ git stash clear
Cherry-picking
# Apply specific commit to current branch
$ git cherry-pick <commit-hash>
# Cherry-pick range of commits
$ git cherry-pick A..B
Resetting and Reverting
# Soft reset (keep changes staged)
$ git reset --soft HEAD~1
# Mixed reset (unstage changes)
$ git reset HEAD~1
# Hard reset (discard changes)
$ git reset --hard HEAD~1
# Revert commit (create new commit that undoes changes)
$ git revert <commit-hash>
Git Configuration
Global Configuration
# Set user information
$ git config --global user.name "Your Name"
$ git config --global user.email "your.email@example.com"
# Set default editor
$ git config --global core.editor vim
# Set default branch name
$ git config --global init.defaultBranch main
# List configuration
$ git config --list
Aliases
# Create useful aliases
$ git config --global alias.st status
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.lg "log --graph --oneline --all"
.gitignore
Common patterns for .gitignore:
# Dependencies
node_modules/
vendor/
# Build outputs
dist/
build/
*.min.js
# IDE files
.vscode/
.idea/
*.swp
# OS files
.DS_Store
Thumbs.db
# Environment files
.env
.env.local
# Logs
*.log
logs/
Branching Strategies
Git Flow
Long-running branches:
main- Production codedevelop- Integration branch
Supporting branches:
feature/*- New featuresrelease/*- Release preparationhotfix/*- Production fixes
GitHub Flow
Simplified workflow:
- Create feature branch from
main - Make changes and commit
- Open pull request
- Review and merge to
main - Deploy from
main
GitLab Flow
Environment-based branches:
main- Developmentpre-production- Stagingproduction- Production
Collaboration Workflows
Fork and Pull Request
# Fork repository on GitHub/GitLab
# Clone your fork
$ git clone git@github.com:yourusername/repo.git
# Add upstream remote
$ git remote add upstream git@github.com:original/repo.git
# Keep fork updated
$ git fetch upstream
$ git checkout main
$ git merge upstream/main
Code Review Process
- Create feature branch
- Make changes and commit
- Push branch to remote
- Open pull/merge request
- Address review feedback
- Merge when approved
Git Hooks
Pre-commit Hook Example
.git/hooks/pre-commit:
#!/bin/sh
# Run tests before commit
npm test
if [ $? -ne 0 ]; then
echo "Tests failed, commit aborted"
exit 1
fi
Post-receive Hook Example
#!/bin/sh
# Deploy after push
cd /var/www/app
git pull origin main
npm install
npm run build
sudo systemctl restart app
Troubleshooting
Common Issues
Merge Conflicts:
# View conflicts
$ git status
# Edit conflicted files
$ vim conflicted-file.txt
# Mark as resolved
$ git add conflicted-file.txt
$ git commit
Detached HEAD:
# Create branch from detached HEAD
$ git checkout -b new-branch-name
# Or discard changes and return to branch
$ git checkout main
Undo Last Commit:
# Keep changes
$ git reset --soft HEAD~1
# Discard changes
$ git reset --hard HEAD~1
Repository Maintenance
# Cleanup unnecessary files
$ git gc
# Verify repository integrity
$ git fsck
# Prune remote tracking branches
$ git remote prune origin
# Squash commits interactively
$ git rebase -i HEAD~n
Best Practices
Commit Messages
Follow conventional commit format:
type(scope): subject
body
footer
Types: feat, fix, docs, style, refactor, test, chore
Example:
feat(auth): add OAuth2 integration
Implement OAuth2 authentication flow with Google provider.
Includes login, logout, and token refresh functionality.
Closes #123
Repository Structure
project/
├── .git/
├── .gitignore
├── README.md
├── CHANGELOG.md
├── LICENSE
├── src/
├── tests/
├── docs/
└── scripts/
Security
- Never commit secrets (use .gitignore and environment variables)
- Sign commits with GPG for verification
- Use SSH keys for authentication
- Enable two-factor authentication on Git hosting services
- Regularly audit repository access and permissions
Performance
- Use shallow clones for CI/CD
- Enable Git LFS for large files
- Keep repositories focused (single responsibility)
- Regular maintenance (gc, prune)
- Use .gitignore to exclude unnecessary files