11.6 - Version Control with Git
Version control is an essential tool for any software development project, including game development. It allows you to track changes, collaborate with others, and maintain a history of your project. Git is one of the most popular version control systems, and in this section, we'll explore how to use it effectively with Unity projects.
Introduction to Version Control
What is Version Control?
Version control is a system that records changes to files over time, allowing you to:
- Track History: See what changes were made, who made them, and when
- Revert to Previous States: Return to earlier versions of your project
- Branch and Merge: Work on different features simultaneously
- Collaborate: Work with others without overwriting each other's changes
- Back Up: Maintain copies of your project on remote servers
Why Use Version Control for Game Development?
Game development presents unique challenges that make version control particularly valuable:
- Complex Projects: Games involve code, assets, scenes, and configurations
- Iterative Development: Game features often require multiple iterations
- Team Collaboration: Different team members work on different aspects
- Experimentation: You need the freedom to try ideas without fear of breaking things
- Asset Management: Tracking changes to large binary files
Git Basics
Git is a distributed version control system designed for speed, data integrity, and support for distributed workflows.
Key Git Concepts
- Repository (Repo): A collection of files and their history
- Commit: A snapshot of your project at a specific point in time
- Branch: A separate line of development
- Merge: Combining changes from different branches
- Remote: A repository stored on another server (like GitHub, GitLab, or Bitbucket)
- Clone: Creating a local copy of a remote repository
- Push: Sending commits to a remote repository
- Pull: Getting commits from a remote repository
- Staging Area: A place to prepare changes before committing
Basic Git Commands
Here are some essential Git commands you'll use frequently:
# Initialize a new Git repository
git init
# Clone an existing repository
git clone https://github.com/username/repository.git
# Check the status of your repository
git status
# Add files to the staging area
git add filename.cs
git add . # Add all changes
# Commit changes
git commit -m "Add player movement system"
# Push changes to a remote repository
git push origin main
# Pull changes from a remote repository
git pull origin main
# Create a new branch
git branch feature-inventory-system
# Switch to a branch
git checkout feature-inventory-system
# Or with newer Git versions
git switch feature-inventory-system
# Create and switch to a new branch in one command
git checkout -b feature-combat-system
# Or with newer Git versions
git switch -c feature-combat-system
# Merge a branch into the current branch
git merge feature-inventory-system
# View commit history
git log
Setting Up Git for Unity Projects
Unity projects have specific requirements for version control due to their structure and the types of files they contain.
Initial Setup
-
Install Git:
- Download and install Git from git-scm.com
- Configure your name and email:
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
-
Create a .gitignore File: A
.gitignore
file tells Git which files to ignore. Unity projects contain many generated files that shouldn't be tracked.Create a file named
.gitignore
in your project root with the following content:# Unity generated files
[Ll]ibrary/
[Tt]emp/
[Oo]bj/
[Bb]uild/
[Bb]uilds/
[Ll]ogs/
[Uu]ser[Ss]ettings/
# Visual Studio / VS Code files
.vs/
.vscode/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Builds
*.apk
*.aab
*.unitypackage
# Crashlytics generated file
crashlytics-build.properties
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db -
Configure Unity for Version Control:
- Open your Unity project
- Go to Edit > Project Settings > Editor
- Set "Version Control Mode" to "Visible Meta Files"
- Set "Asset Serialization Mode" to "Force Text"
- This ensures that Unity generates text-based asset files and meta files that work well with Git
-
Initialize the Repository:
# Navigate to your Unity project folder
cd path/to/your/unity/project
# Initialize a new Git repository
git init
# Add the .gitignore file
git add .gitignore
# Commit the .gitignore file
git commit -m "Add .gitignore for Unity project"
# Add all project files
git add .
# Commit the initial project state
git commit -m "Initial commit of Unity project" -
Connect to a Remote Repository (optional but recommended):
# Add a remote repository (replace with your repository URL)
git remote add origin https://github.com/username/repository.git
# Push your local repository to the remote
git push -u origin main
Unity-Specific Git Considerations
Meta Files
Unity uses .meta
files to track assets and their import settings. These files are crucial for version control:
- Each asset file has a corresponding
.meta
file - Meta files contain GUIDs that Unity uses to reference assets
- Always commit meta files along with their assets
- Never manually edit meta files unless you know what you're doing
Large File Storage (LFS)
Game projects often include large binary files like textures, audio, and models. Git LFS (Large File Storage) is an extension that helps manage these files:
-
Install Git LFS:
# Install Git LFS
git lfs install -
Configure LFS for your project:
# Track common large file types
git lfs track "*.psd"
git lfs track "*.png"
git lfs track "*.jpg"
git lfs track "*.mp3"
git lfs track "*.wav"
git lfs track "*.fbx"
git lfs track "*.tga"
git lfs track "*.tif"
git lfs track "*.tiff"
git lfs track "*.obj"
git lfs track "*.mp4"
git lfs track "*.mov"
# Add the .gitattributes file that LFS creates
git add .gitattributes
git commit -m "Configure Git LFS"
Git Workflows for Unity Development
Solo Developer Workflow
Even when working alone, a structured Git workflow can help you manage your project:
- Main Branch: Keep a stable version of your game
- Feature Branches: Develop new features in separate branches
- Regular Commits: Make small, focused commits with clear messages
- Merge When Complete: Merge feature branches back to main when they're stable
Example workflow:
# Start from the main branch
git checkout main
# Create a new feature branch
git checkout -b feature-player-movement
# Make changes and commit them
git add .
git commit -m "Add basic player movement controller"
# Make more changes
git add .
git commit -m "Add jump functionality to player movement"
# When the feature is complete, merge it back to main
git checkout main
git merge feature-player-movement
# Delete the feature branch (optional)
git branch -d feature-player-movement
# Push changes to remote repository
git push origin main
Team Workflow
When working with a team, you need a more structured approach:
- Protected Main Branch: Keep main branch stable and protected
- Feature Branches: Each team member works on features in separate branches
- Pull Requests: Use pull requests for code review before merging
- Regular Pulls: Keep your local repository updated with others' changes
- Conflict Resolution: Learn to resolve merge conflicts effectively
Example team workflow:
# Clone the repository
git clone https://github.com/team/game-project.git
cd game-project
# Create a feature branch
git checkout -b feature-enemy-ai
# Make changes and commit them
git add .
git commit -m "Add basic enemy pathfinding"
# Push your branch to the remote repository
git push origin feature-enemy-ai
# Create a pull request (through GitHub/GitLab/Bitbucket web interface)
# Meanwhile, update your main branch
git checkout main
git pull origin main
# If needed, rebase your feature branch on the updated main
git checkout feature-enemy-ai
git rebase main
# After your pull request is approved and merged, update your local main
git checkout main
git pull origin main
# Delete your local feature branch
git branch -d feature-enemy-ai
Git-Flow
For larger teams or more complex projects, consider using Git-Flow, a branching model with specific branch types:
- main: Production-ready code
- develop: Integration branch for features
- feature/*: New features
- release/*: Preparing for a release
- hotfix/*: Quick fixes for production issues
Best Practices for Unity and Git
Commit Practices
- Commit Frequently: Make small, focused commits rather than large, sweeping changes
- Write Clear Commit Messages: Use descriptive messages that explain what and why
- Commit Related Changes Together: Keep logically related changes in the same commit
- Commit Working Code: Try to commit code that compiles and doesn't break existing functionality
Example of good commit messages:
Add player movement controller
- Implement basic WASD movement
- Add sprint functionality with shift key
- Include smooth acceleration and deceleration
Scene Management
Unity scenes can be challenging to merge when multiple people make changes:
- Scene Division: Divide your game into multiple scenes when possible
- Prefab Everything: Use prefabs for complex objects instead of modifying them directly in scenes
- Scene Ownership: Assign "ownership" of scenes to specific team members
- Unity Scene Merging Tools: Consider using tools like Unity Smart Merge or commercial solutions
Asset Organization
Organize your assets to minimize merge conflicts:
- Folder Structure: Create a clear, logical folder structure
- Asset Naming: Use consistent naming conventions
- Separation of Concerns: Keep different types of assets in different folders
Example folder structure:
Assets/
├── Animations/
├── Audio/
│ ├── Music/
│ └── SFX/
├── Materials/
├── Models/
├── Prefabs/
├── Scenes/
├── Scripts/
│ ├── AI/
│ ├── Player/
│ ├── UI/
│ └── Utilities/
├── Shaders/
├── Textures/
└── UI/
Handling Large Files
- Use Git LFS: Track large binary files with Git LFS
- Asset Optimization: Compress textures and audio when possible
- External Asset Storage: Consider keeping very large assets outside the repository
Resolving Merge Conflicts
Merge conflicts occur when Git can't automatically merge changes:
- Text-Based Assets: For scripts and text-based assets, use standard Git merge tools
- Unity Assets: For Unity-specific assets, use Unity's Smart Merge utility
- Binary Files: For binary files, usually one version must be chosen over the other
- Communication: Coordinate with team members to avoid conflicts in the first place
Basic conflict resolution:
# When a merge conflict occurs
git status # See which files have conflicts
# Open the conflicted files in your editor and resolve the conflicts
# Look for markers like:
# <<<<<<< HEAD
# your changes
# =======
# their changes
# >>>>>>> branch-name
# After resolving, mark the files as resolved
git add resolved-file.cs
# Complete the merge
git commit
Unity Collaboration Tools
In addition to Git, Unity offers its own collaboration tools:
Unity Collaborate / Unity Teams
Unity's built-in version control solution:
- Integrated directly into the Unity Editor
- Simplified workflow for non-technical team members
- Automatic large file handling
- Limited branching capabilities compared to Git
Unity Asset Server (Legacy)
An older version control solution that has been deprecated in favor of Unity Collaborate.
Plastic SCM
Plastic SCM is a version control system acquired by Unity:
- Designed for handling binary files and large projects
- Strong branching and merging capabilities
- Visual tools for conflict resolution
- Integration with Unity Editor
Practical Example: Setting Up a Unity Project with Git
Let's walk through a complete example of setting up a new Unity project with Git:
1. Create a New Unity Project
- Open Unity Hub
- Click "New Project"
- Select a template (e.g., 3D Core)
- Name your project (e.g., "AdventureGame")
- Choose a location
- Click "Create Project"
2. Configure Unity for Version Control
- In Unity, go to Edit > Project Settings > Editor
- Set "Version Control Mode" to "Visible Meta Files"
- Set "Asset Serialization Mode" to "Force Text"
- Save the project (File > Save Project)
3. Initialize Git Repository
Open a terminal/command prompt and navigate to your project folder:
cd path/to/AdventureGame
# Initialize Git repository
git init
# Create a .gitignore file
# (Copy the Unity .gitignore content from earlier in this section)
# Save it as .gitignore in your project folder
# Add .gitignore to the repository
git add .gitignore
git commit -m "Add .gitignore for Unity project"
4. Set Up Git LFS (Optional but Recommended)
# Install Git LFS if you haven't already
git lfs install
# Track common large file types
git lfs track "*.psd"
git lfs track "*.png"
git lfs track "*.jpg"
git lfs track "*.mp3"
git lfs track "*.wav"
git lfs track "*.fbx"
# Add the .gitattributes file
git add .gitattributes
git commit -m "Configure Git LFS for large assets"
5. Make Your First Commit
# Add all project files
git add .
# Commit the initial project state
git commit -m "Initial commit of Unity project"
6. Create a Remote Repository (GitHub Example)
- Go to GitHub and sign in
- Click the "+" icon in the top-right corner and select "New repository"
- Name your repository (e.g., "AdventureGame")
- Leave "Initialize this repository with a README" unchecked
- Click "Create repository"
7. Connect and Push to Remote Repository
# Add the remote repository
git remote add origin https://github.com/yourusername/AdventureGame.git
# Push your local repository to GitHub
git push -u origin main
8. Create a Development Branch
# Create and switch to a development branch
git checkout -b develop
# Push the develop branch to GitHub
git push -u origin develop
9. Start Working on a Feature
# Create a feature branch from develop
git checkout -b feature-player-controller develop
# Make changes in Unity...
# Commit your changes
git add .
git commit -m "Add basic player controller script"
# Push the feature branch to GitHub
git push -u origin feature-player-controller
10. Merge the Feature
When your feature is complete:
# Switch to the develop branch
git checkout develop
# Merge the feature branch
git merge feature-player-controller
# Push the updated develop branch to GitHub
git push origin develop
# Delete the feature branch (optional)
git branch -d feature-player-controller
git push origin --delete feature-player-controller
Troubleshooting Common Git Issues in Unity
Issue: Large File Rejection
Problem: GitHub or other Git hosts reject pushes with large files.
Solution:
- Set up Git LFS
- Track the large file types
- Remove the large files from Git history if they were committed before setting up LFS
# Remove large files from Git history (use with caution!)
git filter-branch --force --tree-filter 'rm -f path/to/large/file.psd' HEAD
git push --force origin main
Issue: Meta File Conflicts
Problem: Conflicts in .meta
files.
Solution:
- Be careful when resolving meta file conflicts
- When in doubt, keep the newer version of the meta file
- If assets are missing references after a merge, check the meta files
Issue: Scene Merge Conflicts
Problem: Multiple people modified the same scene, causing conflicts.
Solution:
- Use Unity's Smart Merge utility
- Consider scene ownership policies
- Break down scenes into smaller, more manageable scenes
- Use prefabs for complex objects
Issue: Missing References After Pull
Problem: After pulling changes, some assets have missing references.
Solution:
- Ensure all meta files were properly committed and pulled
- Check if the referenced assets exist in the project
- Rebuild the Library folder by closing Unity and deleting the Library folder, then reopening the project
# Close Unity first!
rm -rf Library
# Then reopen the project in Unity
Advanced Git Techniques for Unity
Git Hooks
Git hooks are scripts that run automatically when certain Git events occur:
# Example pre-commit hook to check for large files
# Save as .git/hooks/pre-commit and make executable
#!/bin/sh
# Check for files larger than 100MB
large_files=$(find . -type f -size +100M -not -path "./.git/*")
if [ -n "$large_files" ]; then
echo "Error: Attempting to commit large files:"
echo "$large_files"
echo "Please use Git LFS for large files."
exit 1
fi
exit 0
Git Submodules
Submodules allow you to include other Git repositories within your project:
# Add a submodule for a shared asset library
git submodule add https://github.com/team/shared-assets.git Assets/SharedAssets
# Update submodules after cloning
git submodule update --init --recursive
Automated Build Systems
Integrate Git with CI/CD systems for automated builds:
- GitHub Actions: Set up workflows to build your Unity project on push
- Jenkins: Configure build jobs triggered by Git commits
- Unity Cloud Build: Connect your Git repository for automatic builds
Example GitHub Actions workflow for Unity:
name: Build Unity Project
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
lfs: true
- uses: game-ci/unity-builder@v2
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
with:
targetPlatform: WebGL
- uses: actions/upload-artifact@v2
with:
name: Build
path: build
Conclusion
Version control with Git is an essential skill for Unity developers. It provides a safety net for your code, facilitates collaboration, and helps maintain a history of your project's development. By following the best practices outlined in this section, you can effectively manage your Unity projects with Git, whether you're working alone or as part of a team.
Remember these key points:
- Configure Unity properly for version control
- Use a good .gitignore file
- Commit frequently with clear messages
- Use branches for features and experiments
- Handle large files with Git LFS
- Organize your project to minimize merge conflicts
- Learn to resolve conflicts effectively
As you continue your journey in Unity development, your Git skills will become increasingly valuable, allowing you to work more efficiently and collaborate more effectively.
Unity Technologies recognizes the importance of version control and has been improving Unity's compatibility with Git over the years. The "Force Text" serialization mode and Smart Merge utility are examples of features designed specifically to work better with version control systems.
For larger teams or studios, Unity also offers Unity Teams (formerly Collaborate) as an integrated solution, and has acquired Plastic SCM as a more powerful alternative to Git for game development.
Regardless of which system you choose, version control should be an integral part of your Unity development workflow from the beginning of your project.
In the next section, we'll wrap up this module with a comprehensive preparation guide for your Unity journey, bringing together everything you've learned about C# and preparing you for the exciting world of Unity game development.