# Git Add, Stage, and Ignore Files (faq5)

This document explains how to:

- Add a specific list of files to the next commit.
- Ignore files and folders using `.gitignore`.
- Stop tracking files that are already in the repo but should be ignored.

It assumes your proj1 setup with macOS and Linux working copies pointing to the same central bare repo.

---

## 1. Add a list of files

To stage specific files for the next commit:

```bash
git add file1.txt file2.txt src/index.php README.md
```

Examples:

```bash
# Stage only these files
git add README.md VERSION src/main.php

# Stage all files in a directory
git add src/

# Stage all changes (including deletions)
git add -A

# Stage only modified/deleted tracked files (not new untracked)
git add -u

# Interactively choose files/hunks to stage
git add -p
```

Then commit:

```bash
git commit -m "Update README, VERSION, and main.php"
```

Only the staged files are included in the commit.

---

## 2. Ignore files and folders with `.gitignore`

Create a `.gitignore` file in the repo root:

```bash
touch .gitignore
vi .gitignore
```

Example `.gitignore` for a typical project:

```gitignore
# Logs
*.log
logs/

# Temp / build
tmp/
build/
dist/

# OS / editor
.DS_Store
Thumbs.db
*.swp
*.swo

# Local config / secrets
.env
config.local.php

# Project-specific junk
junk
old/
```

Commit it:

```bash
git add .gitignore
git commit -m "Add .gitignore"
```

From then on, Git will ignore matching untracked files.

### Ignore a folder but keep it in the repo

If you need the folder to exist (e.g., for logs) but want it empty in Git:

```gitignore
# Ignore contents of tmp/ but keep the folder
tmp/*
!tmp/.gitkeep
```

Then create a placeholder:

```bash
mkdir -p tmp
touch tmp/.gitkeep
git add tmp/.gitkeep
git commit -m "Keep tmp folder but ignore contents"
```

---

## 3. Ignore files that are already tracked

`.gitignore` only affects **untracked** files. If a file is already in Git, you must first untrack it.

### Stop tracking a single file but keep it locally

```bash
git rm --cached junk
git commit -m "Stop tracking junk"

# Now add rule to .gitignore
echo "junk" >> .gitignore
git add .gitignore
git commit -m "Ignore junk going forward"
```

### Stop tracking a whole folder

```bash
git rm -r --cached old
git commit -m "Stop tracking old folder"

echo "old/" >> .gitignore
git add .gitignore
git commit -m "Ignore old folder"
```

The files remain on disk but are no longer in the repository.

---

## 4. Practical recipes for proj1

### Stage a specific list of files

```bash
git add README.md VERSION git1.md faq1.md
git commit -m "Update docs and version"
```

### Add a basic `.gitignore`

```bash
cat > .gitignore << 'EOF'
# Logs
*.log
logs/

# Temp / build
tmp/
build/
dist/

# OS / editor
.DS_Store
Thumbs.db
*.swp
*.swo

# Local config / secrets
.env
config.local.php

# Project-specific junk
junk
old/
EOF

git add .gitignore
git commit -m "Add .gitignore"
```

### Untrack existing junk/old and then ignore them

```bash
# If junk and old/ are already tracked
git rm -r --cached junk old
git commit -m "Untrack junk and old"

# Ensure .gitignore has these lines
cat >> .gitignore << 'EOF'

# Untracked junk
junk
old/
EOF

git add .gitignore
git commit -m "Ignore junk and old going forward"
```

---

## 5. Tips

- Use `git status` frequently to see what is staged, modified, or untracked.
- Keep `.gitignore` under version control so all developers share the same rules.
- When in doubt, stage only specific files instead of `git add -A` to avoid committing unwanted changes.

Use this together with `git.cheatsheet.md`, `tasks.md`, and `faq1.md`–`faq4.md` for your full workflow.
