---
title: "A Beginner's Guide to Setting Up a Programming Environment on Windows"
url: "https://blog.101ta28.com/en/posts/windows-programming-setup/"
language: "en"
description: "Set up a development environment with Windows 11 and Ubuntu on WSL. Write HTML in VS Code, display it with PHP, and record your progress with Git and GitHub. No programming experience required."
---

# A Beginner's Guide to Setting Up a Programming Environment on Windows

> Set up a development environment with Windows 11 and Ubuntu on WSL. Write HTML in VS Code, display it with PHP, and record your progress with Git and GitHub. No programming experience required.

You want to start programming, but unfamiliar software names and lines of text on a black screen stop you in your tracks.
This guide walks you through preparing a development environment on Windows, even if you have never heard the word “terminal” before.

You will use Linux commands in Ubuntu on WSL, write HTML in VS Code, and display it with PHP's development server.
You will publish the page's source and change history to GitHub, then close your tools and reopen the same workspace.



The main instructions are for learners working through the guide on their own.
The final section gives instructors ways to explain the terminology and questions for checking understanding.

## What you will be able to do

As you prepare the environment, you will practice these operations:

1. Start Ubuntu on Windows.
2. Create a folder with commands and open it in VS Code.
3. Write and save HTML, then display it in your browser.
4. Record changes with Git and send them to GitHub.
5. Close everything and reopen the same workspace.

The exercise is an **introductory page for an equipment purchase request management app**.
You will build an HTML page that displays a heading and paragraphs. It will not include features for entering or saving purchase requests.

These instructions assume Windows 11 and Ubuntu 26.04 on WSL.
You need an internet connection and a Windows environment where you can install apps and perform administrator operations.
If your company or school restricts operations on the PC, ask its administrator whether you can use WSL.

Also check the free space on your C drive under “This PC” in File Explorer.
If space is limited and you want to use your D drive, read the [storage appendix](#wsl-storage) before installing Ubuntu.

## Install the tools you will use on Windows

### Set up Windows Terminal

You normally operate a PC by clicking icons and menus.
Development also involves typing instructions. An instruction is called a **command**, and an app for entering commands and displaying results is called a **terminal**.

First, search for “Terminal” in the Start menu. If Windows Terminal is already installed, you can use it as it is.
Otherwise, install [Windows Terminal from the Microsoft Store](https://apps.microsoft.com/detail/9n0dx20hk701?hl=en-US&gl=US).

Windows Terminal can open multiple tabs.
PowerShell or Ubuntu running inside a tab receives and processes your instructions.
In this guide, you will run **Windows setup commands in PowerShell and development commands in Ubuntu**.

You can still use the mouse to switch tabs or copy text in a terminal.
After entering a command, press `Enter` to run it.
Unless stated otherwise, run the commands in each code block one line at a time.

Use ordinary half-width letters, numbers, and symbols, and keep the spaces within commands.
It is fine to copy the code blocks at first. In Windows Terminal, use `Ctrl+Shift+V` to paste.
Some commands display nothing and simply return to the prompt. Follow the checks in the instructions to determine whether they succeeded.

### Install VS Code

To write programs, you use a **text editor**, an app for editing text.
If you think of writing on paper, the editor is like your paper and pen.
Windows Notepad can also be used, but development editors provide features that suggest what to type and help you find mistakes.

Install the Windows version from the [Visual Studio Code download page](https://code.visualstudio.com/download).
From here on, we will call it “VS Code.”

Check your system type under Windows “Settings → System → About.” Choose the x64 User Installer for an Intel or AMD PC, or the Arm64 User Installer for an Arm PC.
Keep “Add to PATH” enabled in the installer.
This setting lets you launch VS Code from Ubuntu with the `code` command later.

Install VS Code on Windows. You do not need to install another copy inside Ubuntu.
The [official VS Code setup guide for Windows](https://code.visualstudio.com/docs/setup/windows) also explains the installer types.

## Enable Ubuntu with WSL

**Linux**, like Windows, is an operating system: the basic software that runs a computer.
**Ubuntu** packages Linux in a form that is convenient to use.
To learn Linux commands, you will use **WSL**, which lets you run Ubuntu inside Windows.

### Install from PowerShell

Save any files you are working on. Then right-click “Terminal” in the Start menu and select “Run as administrator.”
Approve the Windows confirmation prompt and open a PowerShell tab.

**Where to type: PowerShell in Windows Terminal, running as administrator**

```powershell
wsl --install -d Ubuntu
```

`--install` requests installation, and `-d Ubuntu` selects Ubuntu as the Linux distribution to install.
When the process finishes, restart Windows. If a message asks you to restart, follow that instruction too.
This follows [Microsoft's WSL installation instructions](https://learn.microsoft.com/en-us/windows/wsl/install).

If Ubuntu's initial setup does not start after the restart, open Terminal normally from the Start menu and run this in PowerShell:

```powershell
wsl -d Ubuntu
```

If a message says Ubuntu's installation is incomplete, run the installation command again in an administrator PowerShell tab.
If an error code appears, make a note of it and check the relevant section of [WSL troubleshooting](https://learn.microsoft.com/en-us/windows/wsl/troubleshooting).
For example, if you are asked to enable virtualization, change the setting according to your PC manufacturer's instructions.

### Create an Ubuntu username and password

The first time Ubuntu starts, set its username and password.
These are separate from your Windows and GitHub accounts.

A username that starts with a lowercase English letter and uses lowercase letters and numbers is easy to type.
This guide uses `learner` in examples, but you can choose your own name.
If the name is rejected, adjust it to meet the displayed requirements.

**Your password will not appear on screen as you type, and you will not see symbols such as `●` either**.
Even if it looks as though nothing is being entered, continue typing and press `Enter`.
Enter the same password again to confirm it.
You will also use this password later when adding software to Ubuntu.

After setup, you will see something like this. The username and PC name will vary.

```text
learner@DESKTOP-XXXX:~$
```

This is the **prompt**, which indicates that Ubuntu is waiting for your next command.
`learner` is the username and `DESKTOP-XXXX` is the PC name. You do not type this text or the `$` at the end yourself.
The command blocks below contain only the parts you need to enter.

### Check the Ubuntu version and WSL version

**Where to type: Ubuntu**

```bash
cat /etc/os-release
```

`cat` displays the contents of a file.
Here, read the operating system information and check for `VERSION_ID="26.04"`.

The version installed under the name `Ubuntu` changes over time.
If yours is not 26.04, run `wsl --list --online` in PowerShell and check whether `Ubuntu-26.04` appears in the `NAME` column.

To use the same version as this guide, run `wsl --install -d Ubuntu-26.04` in administrator PowerShell. In the Windows commands that follow, replace `Ubuntu` with `Ubuntu-26.04`.
You do not need to delete the original Ubuntu installation. You can also check the names in [Microsoft's distribution list](https://raw.githubusercontent.com/microsoft/WSL/refs/heads/master/distributions/DistributionInfo.json).

In the PowerShell tab, also check the WSL status:

```powershell
wsl --list --verbose
```

If `VERSION` is `2` on the row for the Ubuntu installation you will use, you can continue.
This number identifies the WSL version, separate from Ubuntu's 26.04.
If it is `1`, close the Ubuntu session, run `wsl --set-version Ubuntu 2` in PowerShell, and check again after it finishes.

Once you have finished these steps, close the administrator Terminal window.
From now on, open Terminal normally and choose Ubuntu from the downward-facing menu beside the tabs.
If Ubuntu is not in the menu, you can open it from PowerShell with `wsl -d Ubuntu`.

## Check your current location in Ubuntu

### Directories and your current location

In development, a folder is often called a **directory**.
Thinking of it as a box for files can make it easier to understand at first.
Just as you can put one box inside another, you can create directories inside other directories.

A terminal also has a directory you are currently working in, called the **current directory**.
Because its location is not clear from the appearance of the screen alone, you check it with a command.

**Where to type: Ubuntu**

From this point on, run commands in Ubuntu unless the instructions explicitly say PowerShell.

```bash
cd ~
pwd
```

`cd` changes the directory you are working in.
`~` represents your **home directory**, your personal working area.
`pwd` stands for “print working directory” and displays your current location.

If your username is `learner`, the output looks like this:

```text
/home/learner
```

This is your home directory in that Ubuntu installation.
It is separate from Windows' `C:\Users\...`. In this guide, you will keep your files inside Ubuntu's home directory.

## Install PHP and the other development software

Use Ubuntu's software management command, `apt`, to install the tools together.
First, update the list of available software.

```bash
sudo apt update
```

`sudo` runs the command that follows with administrator privileges.
You use it here to install software for Ubuntu as a whole.
If prompted, enter the Ubuntu password you created earlier. The characters will not be displayed here either.

Once the update finishes without errors, run:

```bash
sudo apt install -y php-cli php-sqlite3 php-mbstring sqlite3 git gh
```

`install` installs software, and `-y` automatically answers “yes” to installation confirmations.
The names that follow identify the software to install.

| Name | Role in the development environment |
| --- | --- |
| `php-cli` | Runs PHP from the command line. You will also use it to serve pages to the browser |
| `php-sqlite3` | Adds support for using SQLite from PHP |
| `php-mbstring` | Adds support for handling strings such as Japanese text in PHP |
| `sqlite3` | A command-line tool for working with SQLite, which stores data |
| `git` | Records the history of changes to files |
| `gh` | Operates GitHub from the command line. Also called GitHub CLI |

SQLite can store data such as purchase requests.
You will not use it to display this HTML page, but you will prepare PHP to use it so you can develop apps that work with data.
For `gh`, use the [package provided by Ubuntu 26.04](https://packages.ubuntu.com/resolute/gh).

After installation, run these commands one line at a time:

```bash
php --version
sqlite3 --version
git --version
gh --version
php -m
```

For the first four, seeing the software name or version number confirms that you can invoke the command.
The last command, `php -m`, lists PHP's modules. Check that `mbstring`, `pdo_sqlite`, and `sqlite3` appear.

`command not found` means the command could not be found.
First, check that you are typing in Ubuntu, then look back for errors during installation.
If you see `Unable to locate package gh`, check the Ubuntu version and the output of `sudo apt update`. If needed, use the [official GitHub CLI installation instructions for Linux](https://raw.githubusercontent.com/cli/cli/refs/heads/trunk/docs/install_linux.md).

## Create a development directory

Create a workspace for the purchase request management app inside your home directory.
`simple-application-manager` is the directory name used in this guide.

```bash
mkdir -p ~/simple-application-manager/public
cd ~/simple-application-manager
pwd
ls
```

`mkdir` means “make directory” and creates a directory.
With `-p`, it also creates any intermediate directories that are needed.
`ls` lists the contents of your current directory.

If `pwd` shows `/home/your-username/simple-application-manager` and `ls` shows `public`, your workspace is ready.
Its structure now looks like this:

```text
/home/learner/                  ← Home directory
└── simple-application-manager/ ← Your current location
    └── public/                ← Files to serve to the browser
```

### The path symbols `.`, `~`, and `/`

A string that describes the location of a file or directory is called a **path**.
A **relative path** starts from your current location. An **absolute path** starts from the top-level `/`.

| Notation | Meaning |
| --- | --- |
| `.` | The current directory |
| `..` | The directory one level above |
| `~` | Your home directory. The mechanism that processes your input replaces it with your home path |
| `/` | The top of the directory hierarchy, called the root directory |
| `./public` | `public` inside your current directory |
| `~/simple-application-manager/public` | `public`, reached through the workspace inside your home directory |

The home directory and root directory are different locations.
`~` is shorthand for your home directory, so it points to the same home even when your current location changes.
By contrast, the location represented by `.` changes whenever you move with `cd`.

For example, while you are in `/home/learner/simple-application-manager`, `./public` and `/home/learner/simple-application-manager/public` refer to the same place.
After you enter it with `cd public`, you can refer to that same `public` directory as `.`.

Try moving between directories and check how the output changes.

```bash
cd public
pwd
cd ..
pwd
```

If you have returned to `/home/your-username/simple-application-manager`, continue to the next step.

## Create a file and open it in VS Code

### Create and move an empty file

Run the following in your workspace:

```bash
touch ./index.html
ls
```

`touch` creates an empty file if the specified file does not exist.
If a file with the same name already exists, it updates its timestamps without emptying its contents.
Check that `ls` shows both `index.html` and `public`.

Move `index.html` into `public`, the directory for files you will serve to the browser.

```bash
mv ./index.html ./public/
ls ./public
```

`mv` means “move.” Its arguments are written in the order `mv source destination`.
For this exercise, run it when there is no file with the same name in `public`.
If `ls ./public` shows `index.html`, the move succeeded.

### Connect VS Code to Ubuntu

Open VS Code on Windows and select “Extensions” on the left.
Extensions add features to VS Code.
Search for `ms-vscode-remote.remote-wsl` and install Microsoft's [WSL extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl).

Then return to the Ubuntu terminal. Check your location before opening VS Code.

```bash
cd ~/simple-application-manager
code .
```

`code` launches VS Code, and `.` means the current directory.
Together, they mean “open the current directory in VS Code.”
The first time VS Code connects to Ubuntu, it downloads what it needs. Wait for this to finish.

If asked whether you trust the workspace, confirm that you have opened the `simple-application-manager` directory you created, then allow it.
If you see something like `WSL: Ubuntu` at the bottom left and `public` in the Explorer on the left, you have opened the folder inside Ubuntu.
This Explorer is VS Code's file list, separate from Windows File Explorer. You can also refer to the [official WSL connection instructions](https://code.visualstudio.com/docs/remote/wsl).

If you see `code: command not found`, check that you enabled “Add to PATH” when installing VS Code, then reopen the terminal.
If there is no WSL indicator at the bottom left, check the WSL extension and run `code .` from Ubuntu again.

### Add PHP Intelephense

In the Extensions view of the VS Code window connected to WSL, search for `bmewburn.vscode-intelephense-client`.
Install [PHP Intelephense](https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client). If you see “Install in WSL: Ubuntu,” select that button.
Check the extension list to confirm that it is installed on the WSL side.

This extension suggests completions and helps you find mistakes when writing PHP.
Use its free features. If you already have another PHP extension installed, disable it to avoid overlapping features such as completion.

## Write and save HTML

In VS Code's Explorer, expand `public` and click `index.html` inside it.
Paste the following into the editing area on the right:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Equipment Purchase Requests | HTML Practice</title>
</head>
<body>
    <main>
        <h1>Equipment Purchase Requests</h1>
        <p>We will build a web app to manage equipment purchase requests.</p>
        <p>This page displays a heading and paragraphs using HTML.</p>
    </main>
</body>
</html>
```

**HTML** is a way to describe a page's structure, including headings and paragraphs.
The text between `<h1>` and `</h1>` becomes a large heading, while the text between `<p>` and `</p>` becomes a paragraph.
Marks such as `<...>` are called tags.

The `head` contains information such as how to handle text and the page title. The `body` contains what appears on the page.
The text in `<title>` appears in the browser tab; the text in `<h1>` appears on the page itself.
Find the heading and paragraphs, change their contents yourself, and check how they appear.

### Your first three keyboard shortcuts

A keyboard shortcut performs an operation with a combination of keys.
For `Ctrl+S`, hold down `Ctrl` and press `S`.

| Keys | Action in VS Code's editing area |
| --- | --- |
| `Ctrl+S` | Save the file |
| `Ctrl+Z` | Undo the previous edit |
| `Ctrl+Y` | Redo the edit you undid |

Save the HTML you just pasted with `Ctrl+S`.
If the file tab has a dot indicating unsaved changes, check that it disappears.

Try adding “ Practice” to the end of the heading. Undo it with `Ctrl+Z`, then check that it reappears with `Ctrl+Y`.
Finally, use `Ctrl+Z` to return to “Equipment Purchase Requests” and save.
These are the [default keyboard shortcuts in VS Code for Windows](https://code.visualstudio.com/docs/reference/default-keybindings). If you have changed your keybindings, you can also check the actions in the “Edit” menu.

## Display the page with PHP

A **web server** is a program that receives requests from a browser and returns files or other responses.
PHP includes a small web server for checking your work during development. You will use it to display the HTML.

**Where to type: the Ubuntu terminal**

```bash
cd ~/simple-application-manager
php -S 127.0.0.1:8000 -t public
```

| Argument | Meaning |
| --- | --- |
| `-S` | Starts the development web server. The `S` is uppercase |
| `127.0.0.1` | An address that refers to the computer itself |
| `8000` | A port number, which distinguishes connection endpoints |
| `-t public` | Uses `public` as the directory containing files to serve to the browser |

When output containing `Development Server` or `started` appears, the server is running.
**It is normal for the `$` prompt not to return while the server runs**.
Leave the terminal open and launch Edge or Chrome on Windows.
Enter the following in the browser's address bar:

```text
http://127.0.0.1:8000
```

If you see the heading “Equipment Purchase Requests” and two paragraphs, it worked.
See [Microsoft's networking documentation](https://learn.microsoft.com/en-us/windows/wsl/networking) for how a Windows browser connects to a web server inside WSL.

Here, PHP's server is returning an HTML file.
You have not yet written PHP code to process purchase requests.
This server is also intended for development checks. These steps are different from publishing an app on the internet. See the [official PHP documentation](https://www.php.net/manual/en/features.commandline.webserver.php).

### Save and reload the browser

In VS Code, change the second paragraph to something like “I displayed a page on my own PC.”
Save with `Ctrl+S`, then press the browser's reload button.
If the text changes, you have checked the sequence from editing to displaying the result.

In this setup, saving does not automatically update the browser.
Check your work in the order **edit → save → reload the browser**.
Some development tools provide automatic updates, but here you will reload manually.

### What to check when the page does not appear

| Situation | What to check and do next |
| --- | --- |
| `Directory public does not exist` | You may be in the wrong directory. Check `pwd` and `ls`, move with `cd ~/simple-application-manager`, then start the server again |
| The page is not found, or you see 404 | Use `ls ./public` to check for `index.html`. If its name is `.index.html`, correct it using the hidden-files appendix below |
| The browser cannot connect | Check that the terminal running PHP is open, that no startup error appeared, and that the URL is `http://127.0.0.1:8000` |
| `Address already in use` | Another server is using that port. If it is your own server from an earlier session, stop it with `Ctrl+C` in its terminal |
| The text does not change | Check that you are editing `public/index.html` in VS Code, save it, then reload the browser |

If you do not know what is using port 8000, start the server with `php -S 127.0.0.1:8001 -t public` and use `http://127.0.0.1:8001` in the browser too.

### Stop the server

Once you have checked the page, click the terminal where you started PHP and press `Ctrl+C`.
Here, `Ctrl+C` stops the running process.
When the prompt returns, the server has stopped. Your edited files remain.

Next, use that terminal to record your changes.

## Record your first changes with Git

Saving a file keeps its current contents on your PC.
After several edits, though, you may want to know what you wrote yesterday or what you changed.
For that, use **Git**, which can record your work at meaningful points in the editing process.

**GitHub** is a service where you can store the history recorded by Git on the internet.
You can share that history and the code with other people on GitHub.
Git and GitHub are separate: recording a change with Git does not send it to GitHub.

### Prepare a GitHub account and a name for your records

Open [GitHub](https://github.com/) in your browser and create an account through “Sign up.”
Follow the prompts to choose a username and verify your email address.
If you already have an account, you can use it.

Git history records the name and email address of the person who made each change.
To avoid publishing your personal email address with the code, use the **`noreply` address** provided by GitHub.

Click your profile picture at the top right of GitHub, open “Settings → Emails,” and enable “Keep my email addresses private.”
Copy your own `noreply` address shown on that page.
Formats vary, including versions with numbers, so use the displayed value exactly rather than constructing one from an example. See [GitHub's commit email settings documentation](https://docs.github.com/en/account-and-profile/how-tos/email-preferences/setting-your-commit-email-address).

In Ubuntu, replace the uppercase placeholders below with your own values. Keep the `"` characters around them.

```bash
git config --global user.name "YOUR_GITHUB_NAME"
git config --global user.email "YOUR_NOREPLY_EMAIL"
git config --global init.defaultBranch main
```

`YOUR_GITHUB_NAME` is your GitHub username, and `YOUR_NOREPLY_EMAIL` is the address copied from the settings page.
`--global` makes these settings apply to Git used by this Ubuntu user.

`user.name` is the name displayed in your history. It does not have to match your GitHub username, but you will use the same name here.
This setting does not log you in to GitHub. See [Git names and GitHub usernames](https://docs.github.com/en/get-started/git-basics/setting-your-username-in-git).

Check the settings:

```bash
git config --global user.name
git config --global user.email
```

If your own values appear, the settings are in place. If an uppercase placeholder remains, run the corresponding configuration command again with the correct value.

### Start tracking this directory

```bash
cd ~/simple-application-manager
git init
git status
```

`git init` starts Git's history tracking in this directory.
A collection of files and their history is called a **repository**.
Run this operation once, when you first set up the workspace.

`git status` displays the current state, including changes that have not been recorded.
Here, it shows the name `main` and `public/`, which is not yet tracked.
`main` is the name of a **branch**, a line of development history. You will use this one branch for now.

### Choose files to record and inspect the changes

```bash
git add public/index.html
git diff --cached
```

`git add` selects file changes to include in the next record. This preparation is called **staging**.
`git diff --cached` displays the changes you selected.
Because this is a new file, the HTML you wrote appears as added content.

Check that the file being recorded is `public/index.html`.
If the output is long and the prompt does not return, a viewer may be open.
In that case, press `q` to exit the viewer.

### Commit with a message

Recording changes in the history with a description is called a **commit**.

```bash
git commit -m "Add a practice HTML page"
git log -1 --oneline
git status
```

The text after `-m` describes this change.
`git log -1 --oneline` displays the latest record on one line.
If you see a sequence of letters and numbers followed by “Add a practice HTML page,” the commit succeeded.

If the final `git status` shows `nothing to commit, working tree clean`, there are no unrecorded changes after the commit.
At this point, however, the record is still on your PC. Next, you will send it to GitHub.

## Publish the code and history on GitHub

What you will publish here is the code you wrote and its change history.
Publishing the running app itself on the internet is outside the scope of this guide.

### Log in with GitHub CLI

In Ubuntu, use the `gh` command you installed earlier.

```bash
gh auth login
```

Questions will appear in sequence. Use the up and down arrow keys to select an answer and press `Enter` to confirm.
The wording may vary by version, but choose the following:

| Question | Choice |
| --- | --- |
| Which GitHub do you want to log in to? | `GitHub.com` |
| Which protocol should Git use? | `HTTPS` |
| Should Git use your GitHub credentials too? | `Yes` |
| How do you want to log in? | `Login with a web browser` |

The terminal displays a temporary code and instructions.
Follow the instructions to open a browser, log in to GitHub, and enter that code to authorize GitHub CLI.
This code is for the current login process. Do not paste it into an article or learning log.

If WSL does not open the browser automatically, open the URL shown in the terminal in a Windows browser and continue.
After authorization, return to the Ubuntu terminal and check for the completion message.
These steps use [GitHub CLI's browser authentication](https://cli.github.com/manual/gh_auth_login).

```bash
gh auth status
gh auth setup-git
```

Use `gh auth status` to check that you are logged in to your own GitHub account.
Then `gh auth setup-git` configures Git to use `gh` authentication when sending changes to GitHub. See the [authentication setup command](https://cli.github.com/manual/gh_auth_setup-git).

### Create the repository on GitHub

For this exercise, create a public repository so you can show your learning progress to others.
Anyone can read a public repository's code and history. Review your HTML and author information before continuing.
Do not put real people's purchase requests or passwords into the exercise code.

```bash
cd ~/simple-application-manager
gh repo create simple-application-manager --public --source=. --remote=origin
```

`simple-application-manager` is the repository name on GitHub.
`--public` makes it public, and `--source=.` uses your current directory as its source.
`--remote=origin` gives the destination on GitHub the local name `origin`.

Because you are [creating the repository with GitHub CLI](https://cli.github.com/manual/gh_repo_create), you do not need to create one with the same name on GitHub's website first.
If creation fails because that name already exists, change only the repository name in the command to an unused name such as `simple-application-manager-practice`. You can keep your local directory name as it is.

After creation succeeds, check the destination:

```bash
git remote -v
```

Check that the `origin` entries show a URL containing your GitHub username and the repository name you just created.
There are two lines, `fetch` and `push`, because Git displays both the source for receiving changes and the destination for sending them.

### Send the commit and check it in the browser

```bash
git push -u origin main
```

`push` sends your local commits.
`origin main` means “send the history of `main` to the destination named `origin`.”
Using `-u` on the first push records that relationship, so later you can send changes from this branch with just `git push`.

When the command finishes without errors, open the GitHub page:

```bash
gh repo view --web
```

If the browser does not open automatically, run `gh repo view` and open the repository URL it displays in a Windows browser.
If you can see the contents of `public/index.html` and the commit message “Add a practice HTML page,” publication is complete.

If the push fails, first use `gh auth status` and `git remote -v` to check your login and destination.
If you see `src refspec main does not match any`, check for a commit with `git log -1 --oneline` and verify with `git status` that the branch is named `main`.
If there is no commit, work through “Record your first changes with Git” above.

### Record changes after editing

When you edit HTML or PHP, do more than save: inspect the changes and commit them.
For example, after changing `public/index.html`, the sequence is:

```bash
git status
git diff
git add public/index.html
git diff --cached
git commit -m "Describe the changes you made"
git push
```

Write a commit message that describes the changes being recorded.
`git diff` displays changes that have not been staged, while `git diff --cached` displays changes that will go into the next commit.
If you have not edited anything, you do not need a new commit.

## Close and reopen your development environment

Check whether you can resume the same work after closing the windows.
Save your files in VS Code. If the PHP server is running, stop it with `Ctrl+C` in its terminal.
Close VS Code and the terminal.

Now open Terminal yourself from the Start menu and choose Ubuntu.
If Ubuntu is not available in the menu, run `wsl -d Ubuntu` in PowerShell.

**Where to type: Ubuntu**

```bash
cd ~/simple-application-manager
pwd
code .
php -S 127.0.0.1:8000 -t public
```

Open `http://127.0.0.1:8000` in your browser and check that the saved page appears.
Try checking each of these points:

- You can identify where you are working from the output of `pwd`.
- You can confirm that VS Code has opened your workspace inside Ubuntu.
- When you change text, save, and reload the browser, the change appears.
- Your first HTML file and commit are still on GitHub.
- You can stop the PHP server and start it again with the same command.

When you finish checking, stop the server with `Ctrl+C`.
Your development environment is ready for editing and displaying pages and recording their change history.

## Appendix: Hidden files and deletion practice

If you type `./.index.html` instead of `./index.html`, **the filename changes**, even though the directory is the same.

`./` indicates the current directory; the rest is the filename.
In `./.index.html`, the filename itself also starts with a `.`.
Ubuntu treats files with names like this as hidden files, so ordinary `ls` does not display them.

### Add options to `ls`

Arguments such as `-a` and `-l` attached to a command are called **options**.
Here, they change how the contents are displayed.

| Command | What it displays |
| --- | --- |
| `ls` | Ordinary files and directories |
| `ls -a` | A list including hidden files, as well as `.` and `..` |
| `ls -l` | Details such as sizes and modification times |
| `ls -al` | Details including hidden files |

If the `index.html` you thought you created is missing, first check your location with `pwd`, then run `ls -a`.
If your workspace contains `.index.html` but no `index.html`, you can correct the name like this:

```bash
mv ./.index.html ./index.html
```

`mv` can also rename a file within the same directory.
If you already put it inside `public`, check with `ls -a ./public`. After confirming that `public/index.html` does not exist, run `mv ./public/.index.html ./public/index.html`.
This corrects the name while keeping the contents you wrote.

### Delete only the practice file

Use `rm` to delete files. Normally, files deleted with `rm` do not go to the Windows Recycle Bin.
For this exercise, create an empty practice file instead of deleting the app's HTML.

```bash
cd ~
mkdir command-practice-01
cd command-practice-01
pwd
touch ./.practice.txt
ls
ls -a
```

If `mkdir` says the directory already exists, choose another unused practice directory name and use that same name in `cd`.
Check that `pwd` shows your practice directory before running `touch`.

Ordinary `ls` will not show the file, but `ls -a` will show `.practice.txt`.
Next, rename it, inspect its details, and delete it.

```bash
mv ./.practice.txt ./practice.txt
ls -l
rm ./practice.txt
ls -a
```

The file you are deleting is the empty `practice.txt` you just created.
If the final `ls -a` shows only `.` and `..`, the practice file has been deleted.

Clean up the now-empty practice directory too. `rmdir` deletes an empty directory.

```bash
cd ~
rmdir command-practice-01
cd ~/simple-application-manager
```

If you changed the practice directory's name, use that name with `rmdir` too.
If an error says the directory is not empty, inspect its contents. You do not need to delete the app's workspace.

## Appendix: When your C drive is short on space {#wsl-storage}

Ubuntu's files are stored on a Windows drive.
If your C drive has little free space but your D drive has room, you can store Ubuntu on D.

### Choose a location for a new installation

For a new installation, you can specify the storage location from the start.
Run `wsl --help` in administrator PowerShell and check for `--location` under `--install`.
If it is missing, run `wsl --update` and check again.

In File Explorer, create a folder named `wsl` on D and confirm that `Ubuntu` inside it is unused.
Use this command instead of the installation command in the main instructions:

```powershell
wsl --install -d Ubuntu --location "D:\wsl\Ubuntu"
```

The restart and Ubuntu user creation steps are the same as in the main instructions.
`--location` is [Microsoft's documented option for choosing an installation location](https://learn.microsoft.com/en-us/windows/wsl/basic-commands).
Inside Ubuntu, your home still appears as `/home/your-username`, even when the storage location is on D.

### Move an existing Ubuntu installation

You can move an installed Ubuntu distribution with WSL's `--manage --move`. See the [WSL release notes introducing this feature](https://github.com/microsoft/WSL/releases/tag/2.3.11).

**Where to type: Windows PowerShell**

The following assumes that the registered distribution name is `Ubuntu`.

```powershell
wsl --list --verbose
wsl --help
```

Check the distribution's name in the list and confirm that `--manage` and `--move` appear in the help.
If they are missing, run `wsl --update`. If they are still missing after the update, investigate why WSL cannot be updated. Do not substitute a command that unregisters the distribution.

Before moving it, save your files in VS Code, stop processes running in Ubuntu, and close the windows connected to Ubuntu.
In File Explorer, prepare `D:\wsl-backup` and `D:\wsl`. Confirm that both `D:\wsl-backup\Ubuntu.tar` and the destination `D:\wsl\Ubuntu` are unused.
D must have enough free space for both the backup and the data being moved.

```powershell
wsl --shutdown
wsl --export Ubuntu "D:\wsl-backup\Ubuntu.tar"
```

`--shutdown` stops WSL, including other Ubuntu distributions. If other work is running there, save and stop it before running this command too.
Check for a successful export message and confirm in File Explorer that the backup file exists.
If an error appears, complete the export before proceeding with the move.

Next, move the storage location:

```powershell
wsl --manage Ubuntu --move "D:\wsl\Ubuntu"
wsl -d Ubuntu
```

When Ubuntu opens, check your username with `whoami` and your home directory with `cd ~` and `pwd`.
If you already created the app, use `cd ~/simple-application-manager` and `ls` to check the files, then display the page using the reopening steps in the main instructions.
Keep the backup until you have confirmed that the data is at the new location and Ubuntu works.

## For instructors: Check both successful operation and understanding

### Have learners operate the tools from the start

Check whether an operation succeeded separately from whether the learner understands it.

You can describe a terminal as “a tool for entering commands and seeing the results” and an editor as “a writing tool, like paper and pen.”
For directory structures, nested objects such as boxes or nesting dolls can serve as an analogy.

After using an analogy, return to the actual screen.
Ask learners to point out the location shown by `pwd` and the corresponding location in VS Code's file list.
If they do not understand, return to comparing the display before and after `cd` rather than introducing more terminology.

When explaining that a terminal need not be frightening, do not imply that every command is safe.
Distinguish the results: `pwd` and `ls` inspect, `mkdir` and `touch` create, `mv` moves or renames, and `rm` deletes.
It is important to develop the habit of predicting a result before running a command and checking it afterward.

### Add short checks at each stage

There is no need to make memorizing every command the first requirement for success.
Check whether learners can choose where to type, inspect the result, and move on, even while consulting the article.

| Stage | What to ask learners to check |
| --- | --- |
| After starting Ubuntu | Are you typing in PowerShell or Ubuntu? |
| After creating the directory | Which parts of the `pwd` output are your username and workspace name? |
| Before and after `cd public` | How did the location represented by `.` change? |
| After editing HTML | Which edit changes which text on the page? |
| After displaying the page | If saving alone does not update the display, what do you do next? |
| After committing | Which operation recorded the change on the PC, and which sent it to GitHub? |
| At the end of setup | Can you start with the windows closed and get back to displaying the page? |

If a learner creates `.index.html`, do more than type the correct command for them: use it as an opportunity to show the difference between `ls` and `ls -a`.
Also check that they understand the different roles of a `.` at the beginning of a filename and `./` in a path.

Instead of expecting everyone to finish in the same amount of time, check progress at milestones such as “the page appeared,” “the history is on GitHub,” and “I could resume work on my own.”
