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

  1. Initialize Local Git Repository
  2. Authenticate with GitHub CLI
  3. Create GitHub Repository
  4. Create Initial Commit
  5. 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.

  1. Navigate to your project directory:

    cd my-ecs-php-app
    
  2. Check if Git is already initialized:

    git status
    
  3. Initialize Git repository (if not already initialized):

    git init
    
  4. Verify the repository was created:

    ls -la .git
    

Concept Deep Dive

The git init command creates a hidden .git directory 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 a main or master branch.

Common Mistakes

  • Running git init in the wrong directory creates a repository in an unintended location
  • Initializing Git inside another Git repository creates nested repositories (usually undesired)
  • The .git directory should never be manually edited

Quick check: You should see a .git directory and git status should 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.

  1. Check if GitHub CLI is installed:

    gh --version
    
  2. Check authentication status:

    gh auth status
    
  3. Login to GitHub (if not authenticated):

    gh auth login
    
  4. Follow 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
  5. 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 status shows 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.

  1. Create a remote repository:

    gh repo create my-ecs-php-app --private --source=. --remote=origin
    
  2. Verify the remote was added:

    git remote -v
    
  3. Check repository details:

    gh repo view
    

Concept Deep Dive

The gh repo create command creates a repository on GitHub and configures your local Git to use it as the origin remote:

  • --private makes the repository only visible to you and collaborators you invite
  • --source=. connects the current directory to the new remote repository
  • --remote=origin names the remote connection “origin” (Git convention)

A remote is a reference to a repository hosted elsewhere. The origin name 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 manual git remote add later

Quick check: git remote -v shows 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.

  1. Create a .gitignore file:

    cat > .gitignore << 'EOF'
    # IDE
    .vscode/
    .idea/
    
    # OS
    .DS_Store
    Thumbs.db
    
    # Docker
    .dockerignore
    
    # Logs
    *.log
    EOF
    
  2. Check which files will be tracked:

    git status
    
  3. Stage all files:

    git add .
    
  4. Verify staged files:

    git status
    
  5. Create the initial commit:

    git commit -m "Initial commit: Docker multi-architecture PHP application"
    
  6. View commit history:

    git log --oneline
    

Concept Deep Dive

The .gitignore file tells Git which files and directories to ignore. Patterns can use wildcards:

  • *.log ignores all files ending with .log
  • folder/ ignores entire directory
  • !important.log negates a previous ignore pattern

Staging with git add prepares 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, .env files) exposes secrets
  • Adding .gitignore after committing files doesn’t untrack them (requires git 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 log shows your initial commit and git status shows “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.

  1. Check current branch name:

    git branch --show-current
    
  2. Push to GitHub with upstream tracking:

    git push -u origin main
    

    Or if your branch is named master:

    git push -u origin master
    
  3. Verify the push succeeded:

    git status
    
  4. View repository on GitHub:

    gh repo view --web
    

Concept Deep Dive

The git push command uploads local commits to the remote repository:

  • -u (or --set-upstream) configures the local branch to track the remote branch
  • origin is the remote name (where to push)
  • main is the branch name (what to push)

After setting upstream, future pushes only need git push. The tracking relationship enables git pull to fetch and merge changes from the correct remote branch.

Default branch names have shifted from master to main in recent Git versions and GitHub. Your local Git configuration determines which is used.

Common Mistakes

  • Pushing to the wrong branch overwrites unrelated code
  • Forgetting -u on first push means future git push commands need full syntax
  • Branch name mismatch (pushing master when remote expects main) 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 .git directory
  • 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 status shows “Your branch is up to date with ‘origin/main’”

Final verification checklist:

  • .git directory exists in project root
  • gh auth status shows authenticated
  • git remote -v shows origin URL
  • .gitignore file excludes unwanted files
  • ☐ At least one commit exists (git log shows it)
  • ☐ Repository visible on GitHub with all files

Common Issues

If you encounter problems:

“fatal: not a git repository”: Run git init in the correct project directory

“gh: command not found”: Install GitHub CLI from https://cli.github.com

“authentication failed”: Run gh auth login and complete the browser authentication

“remote origin already exists”: Remove it with git remote remove origin before creating new one

“failed to push some refs”: Pull remote changes first with git pull origin main then 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:

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 .gitignore properly prevents committing sensitive or unnecessary files.

Going Deeper (Optional)

Want to explore more?

  • Learn branching and merging with git branch and git 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 -i for 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 .gitignore creation
  • Initial commit and push automation

Usage:

  1. Save the script to scripts/init-github-repo.sh
  2. Make it executable: chmod +x scripts/init-github-repo.sh
  3. Run it: ./scripts/init-github-repo.sh