2. Setup Git Repository and Push to GitHub
Goal
Initialize a local Git repository for your project and connect it to a remote GitHub repository for version control and collaboration.
What you’ll learn:
- How to initialize a Git repository locally
- How to use GitHub CLI to create remote repositories
- How to connect local and remote repositories
- Best practices for initial commits and .gitignore files
Table of Contents
Prerequisites
Before starting, ensure you have:
- ✓ Git installed on your system
- ✓ A GitHub account at https://github.com
- ✓ GitHub CLI (gh) installed from https://cli.github.com
- ✓ Basic understanding of version control concepts
- ✓ A project directory to initialize (e.g.,
my-ecs-php-app)
Exercise Steps
Overview
- Initialize Local Git Repository
- Authenticate with GitHub CLI
- Create GitHub Repository
- Create Initial Commit
- Push to GitHub
Step 1: Initialize Local Git Repository
Set up version control in your project by initializing a Git repository. This creates a .git directory that tracks all changes to your project files.
Navigate to your project directory:
cd my-ecs-php-appCheck if Git is already initialized:
git statusInitialize Git repository (if not already initialized):
git initVerify the repository was created:
ls -la .git
ℹ Concept Deep Dive
The
git initcommand creates a hidden.gitdirectory containing all the metadata and object database for your repository. This includes configuration files, commit history, branches, and staging information. The repository starts with no commits and typically on amainormasterbranch.⚠ Common Mistakes
- Running
git initin the wrong directory creates a repository in an unintended location- Initializing Git inside another Git repository creates nested repositories (usually undesired)
- The
.gitdirectory should never be manually edited✓ Quick check: You should see a
.gitdirectory andgit statusshould work without errors
Step 2: Authenticate with GitHub CLI
Authenticate with GitHub using the GitHub CLI tool to enable repository creation and management from the command line.
Check if GitHub CLI is installed:
gh --versionCheck authentication status:
gh auth statusLogin to GitHub (if not authenticated):
gh auth loginFollow the interactive prompts:
- Choose “GitHub.com”
- Choose “HTTPS” as the protocol
- Authenticate with “Login with a web browser”
- Copy the one-time code shown
- Press Enter to open browser
- Paste the code and authorize
Verify authentication:
gh auth status
ℹ Concept Deep Dive
GitHub CLI provides a command-line interface to GitHub’s features including repositories, pull requests, issues, and workflows. Authentication uses OAuth tokens stored securely in your system’s credential manager. The CLI can use either HTTPS (recommended) or SSH protocol for Git operations.
⚠ Common Mistakes
- Choosing SSH protocol without having SSH keys configured will cause connection errors
- Not completing the browser authentication step leaves the CLI unauthenticated
- Multiple GitHub accounts require explicit account switching with
gh auth switch✓ Quick check:
gh auth statusshows your GitHub username and “Logged in” status
Step 3: Create GitHub Repository
Create a remote repository on GitHub and connect it to your local repository using the GitHub CLI.
Create a remote repository:
gh repo create my-ecs-php-app --private --source=. --remote=originVerify the remote was added:
git remote -vCheck repository details:
gh repo view
ℹ Concept Deep Dive
The
gh repo createcommand creates a repository on GitHub and configures your local Git to use it as theoriginremote:
--privatemakes the repository only visible to you and collaborators you invite--source=.connects the current directory to the new remote repository--remote=originnames the remote connection “origin” (Git convention)A remote is a reference to a repository hosted elsewhere. The
originname is conventional for the primary remote repository. Private repositories keep your code confidential, while public repositories (using--public) are visible to everyone.⚠ Common Mistakes
- Repository names with spaces or special characters may cause issues
- Creating a repository that already exists results in an error
- Forgetting
--source=.requires manualgit remote addlater✓ Quick check:
git remote -vshows both fetch and push URLs for origin
Step 4: Create Initial Commit
Create a .gitignore file to exclude unnecessary files, then stage and commit your project files to establish the initial commit.
Create a
.gitignorefile:cat > .gitignore << 'EOF' # IDE .vscode/ .idea/ # OS .DS_Store Thumbs.db # Docker .dockerignore # Logs *.log EOFCheck which files will be tracked:
git statusStage all files:
git add .Verify staged files:
git statusCreate the initial commit:
git commit -m "Initial commit: Docker multi-architecture PHP application"View commit history:
git log --oneline
ℹ Concept Deep Dive
The
.gitignorefile tells Git which files and directories to ignore. Patterns can use wildcards:
*.logignores all files ending with .logfolder/ignores entire directory!important.lognegates a previous ignore patternStaging with
git addprepares files for commit. The staging area (index) lets you carefully choose what changes to include in each commit. Commits create snapshots of your staged changes with a descriptive message.⚠ Common Mistakes
- Committing sensitive files (passwords, API keys,
.envfiles) exposes secrets- Adding
.gitignoreafter committing files doesn’t untrack them (requiresgit rm --cached)- Vague commit messages like “updates” or “fixes” make history hard to understand
- Not staging all necessary files results in incomplete commits
✓ Quick check:
git logshows your initial commit andgit statusshows “working tree clean”
Step 5: Push to GitHub
Push your local commits to the remote GitHub repository to back up your code and make it accessible for collaboration.
Check current branch name:
git branch --show-currentPush to GitHub with upstream tracking:
git push -u origin mainOr if your branch is named
master:git push -u origin masterVerify the push succeeded:
git statusView repository on GitHub:
gh repo view --web
ℹ Concept Deep Dive
The
git pushcommand uploads local commits to the remote repository:
-u(or--set-upstream) configures the local branch to track the remote branchoriginis the remote name (where to push)mainis the branch name (what to push)After setting upstream, future pushes only need
git push. The tracking relationship enablesgit pullto fetch and merge changes from the correct remote branch.Default branch names have shifted from
mastertomainin recent Git versions and GitHub. Your local Git configuration determines which is used.⚠ Common Mistakes
- Pushing to the wrong branch overwrites unrelated code
- Forgetting
-uon first push means futuregit pushcommands need full syntax- Branch name mismatch (pushing
masterwhen remote expectsmain) creates confusion- Not pulling before pushing can cause rejected pushes if remote has new commits
✓ Quick check: GitHub web interface shows your repository with all committed files
✓ Success indicators:
- Local Git repository initialized with
.gitdirectory- GitHub CLI authenticated with your account
- Remote repository created and visible on GitHub
- Initial commit created with descriptive message
- Code pushed to GitHub and visible in web interface
git statusshows “Your branch is up to date with ‘origin/main’”✓ Final verification checklist:
- ☐
.gitdirectory exists in project root- ☐
gh auth statusshows authenticated- ☐
git remote -vshows origin URL- ☐
.gitignorefile excludes unwanted files- ☐ At least one commit exists (
git logshows it)- ☐ Repository visible on GitHub with all files
Common Issues
If you encounter problems:
“fatal: not a git repository”: Run
git initin the correct project directory“gh: command not found”: Install GitHub CLI from https://cli.github.com
“authentication failed”: Run
gh auth loginand complete the browser authentication“remote origin already exists”: Remove it with
git remote remove originbefore creating new one“failed to push some refs”: Pull remote changes first with
git pull origin mainthen push“repository name already exists”: Choose a different name or delete the existing GitHub repository
Still stuck? Check GitHub CLI documentation at https://cli.github.com/manual/
Summary
You’ve successfully set up version control for your project which:
- ✓ Tracks all changes to your code with Git
- ✓ Backs up your code to GitHub’s cloud infrastructure
- ✓ Enables collaboration with other developers
- ✓ Provides history and ability to revert changes
Key takeaway: Git provides local version control while GitHub adds remote hosting, collaboration, and backup. The GitHub CLI streamlines repository creation and management from the command line. Using
.gitignoreproperly prevents committing sensitive or unnecessary files.
Going Deeper (Optional)
Want to explore more?
- Learn branching and merging with
git branchandgit merge- Explore GitHub pull requests for code review workflows
- Set up branch protection rules for main branch
- Configure SSH keys for passwordless authentication
- Try interactive rebase with
git rebase -ifor cleaning history- Set up GitHub Actions for CI/CD automation
Done! 🎉
Excellent work! You’ve learned how to initialize Git repositories and push them to GitHub. This foundational skill enables version control, collaboration, and professional software development workflows.
Appendix: Automation Script
Advanced: Automated Git and GitHub setup script
For projects that need frequent repository initialization, you can automate the entire process with a shell script. This script handles all five steps automatically.
scripts/init-github-repo.sh
#!/bin/bash
# ============================================================================
# CONFIGURATION
# ============================================================================
APP_NAME="my-ecs-php-app"
# Determine project root - check if running from scripts dir or project root
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [ -f "${SCRIPT_DIR}/Dockerfile" ]; then
# Running from project root
PROJECT_ROOT="${SCRIPT_DIR}"
elif [ -f "${SCRIPT_DIR}/../Dockerfile" ]; then
# Running from scripts directory
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
else
echo "Error: Dockerfile not found. Please run from project root or scripts directory"
exit 1
fi
echo "Project root: ${PROJECT_ROOT}"
# ============================================================================
# PHASE 1: GIT INITIALIZATION
# ============================================================================
echo "Phase 1: Initializing Git repository..."
# Change to project root
cd "${PROJECT_ROOT}"
# Check if already a git repository
if [ -d ".git" ]; then
echo "Git repository already exists"
else
echo "Initializing new Git repository"
git init
echo "Git repository initialized"
fi
# ============================================================================
# PHASE 2: GITHUB CLI AUTHENTICATION
# ============================================================================
echo "Phase 2: Checking GitHub CLI authentication..."
# Check if gh CLI is installed
if ! command -v gh &> /dev/null; then
echo "Error: GitHub CLI (gh) is not installed"
echo "Install it from: https://cli.github.com/"
exit 1
fi
# Check if authenticated with GitHub
if ! gh auth status &> /dev/null; then
echo "Not authenticated with GitHub"
echo "Authenticating with GitHub CLI..."
gh auth login
else
echo "Already authenticated with GitHub"
fi
# ============================================================================
# PHASE 3: CREATE GITHUB REPOSITORY
# ============================================================================
echo "Phase 3: Creating GitHub repository..."
# Check if remote already exists
if git remote get-url origin &> /dev/null; then
REMOTE_URL=$(git remote get-url origin)
echo "Remote origin already exists: ${REMOTE_URL}"
read -p "Do you want to remove and recreate? (y/n): " RECREATE
if [ "$RECREATE" = "y" ] || [ "$RECREATE" = "Y" ]; then
git remote remove origin
echo "Removed existing remote"
else
echo "Keeping existing remote"
exit 0
fi
fi
# Create GitHub repository
echo "Creating GitHub repository: ${APP_NAME}"
gh repo create "${APP_NAME}" --private --source=. --remote=origin
# Verify remote was added
if git remote get-url origin &> /dev/null; then
REMOTE_URL=$(git remote get-url origin)
echo "Remote origin added: ${REMOTE_URL}"
else
echo "Warning: Failed to add remote origin"
exit 1
fi
# ============================================================================
# PHASE 4: INITIAL COMMIT
# ============================================================================
echo "Phase 4: Creating initial commit..."
# Check if there are any commits
if git rev-parse HEAD &> /dev/null 2>&1; then
echo "Repository already has commits"
else
echo "Creating .gitignore file"
cat > .gitignore << 'EOF'
# IDE
.vscode/
.idea/
# OS
.DS_Store
Thumbs.db
# Docker
.dockerignore
# Logs
*.log
EOF
echo "Staging all files"
git add .
echo "Creating initial commit"
git commit -m "Initial commit: Docker multi-architecture PHP application"
echo "Initial commit created"
fi
# ============================================================================
# PHASE 5: PUSH TO GITHUB
# ============================================================================
echo "Phase 5: Pushing to GitHub..."
# Get current branch name
BRANCH=$(git branch --show-current)
# Push to GitHub
echo "Pushing ${BRANCH} branch to GitHub"
git push -u origin "${BRANCH}"
# ============================================================================
# COMPLETE
# ============================================================================
echo ""
echo "GitHub repository setup completed successfully!"
echo ""
echo "Repository URL: ${REMOTE_URL}"
echo "Branch: ${BRANCH}"
echo ""
echo "You can view your repository at:"
gh repo view --web
ℹ Script Features:
- Automatic project root detection
- Git repository initialization check
- GitHub CLI authentication verification
- Existing remote handling with user prompt
- Automatic
.gitignorecreation- Initial commit and push automation
Usage:
- Save the script to
scripts/init-github-repo.sh- Make it executable:
chmod +x scripts/init-github-repo.sh- Run it:
./scripts/init-github-repo.sh