# Git Setup Guide: macOS Dev → Remote Linux Server

## Overview

This guide covers setting up Git across a macOS development machine and a remote Linux server, with per-app repositories, SSH-based authentication, and versioning for system configs and dotfiles.

---

## 1. Prerequisites

### On macOS

```bash
# Install Git (if not already)
brew install git

# Configure your identity (global, applies to all repos)
git config --global user.name "Your Name"
git config --global user.email "ricklakehouse@gmail.com"

# Helpful defaults
git config --global init.defaultBranch main
git config --global pull.rebase true
git config --global core.editor "nano"   # or code, vim, etc.
```

### On the Linux Server

```bash
sudo apt install git   # or: sudo dnf install git
git config --global user.name "Your Name"
git config --global user.email "ricklakehouse@gmail.com"
git config --global init.defaultBranch main
```

---

## 2. Set Up the Remote (Bare Repositories on the Linux Server)

The cleanest pattern is one **bare repository per app** on the server. Bare repos have no working tree — they exist purely to receive pushes.

```bash
# On the Linux server, create a directory to hold all repos
sudo mkdir -p /srv/git
sudo chown -R $USER:$USER /srv/git

# Create a bare repo per app
git init --bare /srv/git/app1.git
git init --bare /srv/git/app2.git
git init --bare /srv/git/system-configs.git
```

---

## 3. Set Up SSH Access (macOS → Linux Server)

Generate an SSH key on your Mac (if you don't have one) and add it to the server:

```bash
# On macOS
ssh-keygen -t ed25519 -C "ricklakehouse@gmail.com"
# Press Enter for defaults

# Copy the public key to the server
ssh-copy-id user@your-server-ip

# Test
ssh user@your-server-ip
# Should log in without password
```

---

## 4. Create and Push a New App Repo from macOS

For each app, create a local repo and connect it to the remote:

```bash
# On macOS — navigate to your app folder
cd ~/dev/myapp

# Initialize
git init
git branch -M main

# Add the remote (SSH URL to the bare repo on your server)
git remote add origin ssh://user@your-server-ip/srv/git/myapp.git

# Stage and commit
echo "# My App" > README.md
git add .
git commit -m "Initial commit"

# Push
git push -u origin main
```

---

## 5. Clone on the Server (for Deployments / File Access)

When you need the app files on the server itself:

```bash
# On the Linux server
git clone /srv/git/myapp.git ~/apps/myapp
# Or via SSH from the server to itself:
git clone ssh://user@localhost/srv/git/myapp.git ~/apps/myapp

# To pull updates later:
cd ~/apps/myapp
git pull
```

---

## 6. Recommended Folder Structure

### On macOS (dev machine)

```
~/dev/
  ├── app1/
  ├── app2/
  ├── system-configs/    # dotfiles, scripts, server configs
  └── dotfiles/          # .bashrc, .gitconfig, etc.
```

### On the Linux server (bare repos + working clones)

```
/srv/git/                # Bare repos (the "remote")
  ├── app1.git/
  ├── app2.git/
  └── system-configs.git/

~/apps/                   # Working clones (for deployment)
  ├── app1/
  └── app2/
```

---

## 7. Versioning System Configs and Dotfiles

Use a bare repo trick for dotfiles — this lets you track config files in place without moving them:

```bash
# On macOS
git init --bare ~/.dotfiles
alias dotfiles='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'

# Add files in place
dotfiles add ~/.gitconfig ~/.bashrc ~/.ssh/config
dotfiles commit -m "Add dotfiles"
dotfiles remote add origin ssh://user@your-server-ip/srv/git/dotfiles.git
dotfiles push -u origin main

# On the Linux server (restore)
git clone --bare ssh://user@your-server-ip/srv/git/dotfiles.git ~/.dotfiles
alias dotfiles='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'
dotfiles checkout
```

---

## 8. Daily Workflow Summary

| Action | Command |
|---|---|
| Start work | `cd ~/dev/myapp` |
| Check status | `git status` |
| Stage changes | `git add .` |
| Commit | `git commit -m "Describe change"` |
| Push to server | `git push` |
| Pull on server | `cd ~/apps/myapp && git pull` |
| View history | `git log --oneline --graph` |
| Tag a release | `git tag -a v1.0.0 -m "Release 1.0"` |
| Push tags | `git push --tags` |
| Create feature branch | `git checkout -b feature/new-ui` |
| Merge to main | `git checkout main && git merge feature/new-ui` |

---

## 9. Key Principles

- **One repo per app** — keeps history clean and isolated; you can version, branch, and roll back independently
- **Bare repos on the server** act as your private GitHub replacement — no working files, just the Git database
- **SSH keys** handle auth securely without passwords
- **Tag releases** with `git tag -a v1.0.0 -m "Release 1.0"` and `git push --tags` for version milestones
- **`.gitignore` per app** — exclude `node_modules/`, `.env`, build artifacts, secrets
- **Branch per feature** — `git checkout -b feature/new-ui`, then merge to `main`

---

## 10. Optional: Add a Web UI (Gitea / Forgejo)

If you want a GitHub-like interface on your server, install **Gitea** or **Forgejo** — both are lightweight, self-hosted Git servers with web UI, issue tracking, and pull requests:

```bash
# Quick Gitea install on Linux
wget https://dl.gitea.com/gitea/1.21/gitea-1.21-linux-amd64
chmod +x gitea-1.21-linux-amd64
./gitea-1.21-linux-amd64 web   # runs on port 3000
```

Access the web dashboard at `http://your-server-ip:3000` where you can view repos, commits, diffs, and manage users.

---

## Quick Reference: TL;DR

1. `git init` locally on macOS
2. `git init --bare` on the Linux server for each app
3. `git remote add origin ssh://user@server-ip/srv/git/myapp.git`
4. `git push -u origin main`
5. One bare repo per app
6. SSH keys for authentication
7. Tag releases for version milestones
8. Optionally add Gitea/Forgejo for a web UI
