Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions common-content/en/module/git-cli/adding-committing/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
+++
title = 'Adding & Committing'

time = 30
[objectives]
1='Stage a change using the terminal'
2='Make a commit using the terminal'
3='Check the status of a repository'
4='Access the commit history'
[build]
render = 'never'
list = 'local'
publishResources = false

+++

It's time to create a file to work in. Use the terminal to create `notes.txt` then open the directory in VSCode.

```sh {title="git-cli-practice"}
touch notes.txt
```

Just like last time we'll add some text to the file and save it.

```text {title="notes.txt"}
Git in the Terminal

I'm learning how to use Git from the command line.
It's going well so far!
```

### Staging changes

Let's move back to the terminal. If your terminal may have some sort of indication that something has changed, but it may not. We can always use `git status` again to check the state of our repository. This time the output will look like this:

```console {title="git-cli-practice"}
On branch main

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)
notes.txt

nothing added to commit but untracked files present (use "git add" to track)
```

This is the terminal equivalent of the big green "U" next to the file name in VSCode. Git is very helpfully telling us the command we need to stage our change so let's go ahead and do it.

```sh {title="git-cli-practice"}
git add notes.txt
```

Now if we check our repository's status again we see a different message:

```console {title="git-cli-practice"}
On branch main

No commits yet

Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: notes.txt
```

We can add multiple files at once if we want to by passing multiple arguments to `git add`:

```sh
git add file1.txt file2.txt #...
```

{{<note type="tip" title="Other ways to stage changes">}}
Adding individual files gives us precise control over what we want to stage but it can be a little cumbersome if we have lots of files to stage at once. There are other ways of staging changes which capture multiple files at once:

- `git add .` - This stages all changes in the **current directory**.
- `git add --all` - This stages all changes in the **current repository**.

At the moment our repository is a single directory so these commands will do the same thing, but as our projects get more complex the distinction becomes useful.
{{</note>}}

### Making a commit

The next step in the process is to commit our staged change. We still need to provide a commit message and it's still very important that it tells our colleagues **what** we changed and **why**. We don't have a text box to type it in though, so how do we supply the information?

We will use the `git commit` command to make the commit but we will use the `-m` flag to provide the commit message.

```sh {title="git-cli-practice"}
git commit -m "adding initial notes"
```

Our commit has now been made.

{{<note type="caution" title="What if I forget the message?">}}
Forgetting to add the `-m` flag is another common error when learning Git. A commit _must_ have a message associated with it, so if you forget to include one you will be prompted to add one before the commit is made. Git will open your default text editor and prompt you to add the message. When you are done you can save and close the file and you will be in the same place you would have been using the flag.
{{</note>}}

Another `git status` check will have us back at the "nothing to commit" stage.

### Viewing the commit history

We no longer have our repository's history represented as a nicely-coloured timeline, but we do still have access to the information. The `git log` command will show us the same information, and will actually give us even more!

```console
commit dc976c03d859a368281ff8875997d1afa6e643d8 (HEAD -> main)
Author: A. User <user@email.com>
Date: Thu Sep 17 17:10:24 2026 +0100

adding initial notes
```

We can see all the same information that VSCode provided us with:

- The commit message
- The user who made the commit
- The date and time of the commit
- The branch the commit was made to

We also have a long hexadecimal number on the first line which wasn't there before. This is the **commit hash** which acts as a unique identifier for the commit. Any time we need to refer to a specific commit we use this hash. Typically we only need to provide the first seven characters when doing so.

Commits are listed with the most recent first and you can exit the log by pressing the `q` key.

{{<note type="exercise" title="Exercise: Make another commit">}}
It's time to practice using the CLI by recreating the next stage of our original Git notes.

1. Create a new file called planning.txt
2. Add some text to it
3. Save it
4. Stage your changes
5. Make a commit with the message "Add project planning document"
6. Check the history to see both commits
{{</note>}}
121 changes: 121 additions & 0 deletions common-content/en/module/git-cli/branches/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
+++
title = 'Branching & Merging'

time = 20
[objectives]
1='Create a branch in a repository from the terminal'
2='Merge two branches in the terminal'
3='Delete a branch'
[build]
render = 'never'
list = 'local'
publishResources = false

+++

By now you have had lots of experience creating branches and raising pull requests on GitHub. When it comes to merging work we won't make any fundamental changes: we will still use Github to manage PRs and to complete any merges when working on group projects. Pull requests are a feature of GitHub specifically rather than Git so we can't recreate them exactly using the terminal, but in this section we'll look at how we can create and merge branches.

### Creating a branch

For this section we'll revisit the educational blog from the [JavaScript Fundamentals module](/itp/javascript-fundamentals/sprints/1/prep/). Open the project in VSCode and navigate to that directory in your terminal.

We're going to follow a similar workflow to begin with by creating a branch. For this we're going to use the `git branch` command along with the name we want to give our branch. Since this will be our second update we'll call it `update-blog-2`.

```sh {title="education-blog"}
git branch update-blog-2
```

At this point we diverge from how VSCode handled the process because we haven't actually switched to our new branch, only created it. We can confirm this by typing `git branch` without any arguments and checking the output.

```console
* main
update-blog-1
update-blog-2
```

We have our `main` branch, our new branch and `update-blog-1` from our previous Git work. The asterisk indicates which branch we are currently working on. If we want to work on our new branch we can move over to it using `git switch`.

```sh {title="education-blog"}
git switch update-blog-2
```

Checking `git branch` will confirm the change.

```console
main
update-blog-1
* update-blog-2
```

If we know we're going to switch immediately we can do both steps at once by adding the `-c` flag to the switch command and providing the name of the branch.

```sh
git switch -c update-blog-2
```

{{<note type="exercise" title="Exercise: Update the blog">}}
Add some more unblocking tips to the list and commit your changes.
{{</note>}}

### Merging

With the tools we have had at our disposal so far, at this point we would publish our branch to Github and raise a pull request. Once everything was reviewed and merged we would pull the updated version of `main` and continue. To be clear, **this is still the recommended way of working!**

It's not the only way of working though. We can use `git merge` to complete the merge locally and bypass Github. This has its drawbacks though, in particular the fact it is only possible to get your changes reviewed if your colleague is in the room with you.

We need to think carefully about how we manage the merge. We don't want to end up with any broken code on our `main` branch, so if there are any issues it's better to sort them out before they get there. How will we know there are going to be issues?

Before merging our branch onto `main` we can discover any conflicts by merging `main` onto our branch first. If there are problems (such as merge conflicts) we fix them on the branch and leave `main` unpolluted for everyone else. Once the conflicts are resolved we merge our changes to `main`.

First we need to ensure we are on the correct branch. Use `git branch` to check if you are unsure. Then use `git merge` and the name of the branch you want to merge.

```sh {title="education-blog"}
git merge main
```

We are asking Git to merge the _named_ branch onto the _current_ branch. If there were commits on `main` which we did not have on `update-blog-2` they would be moved across, but since there aren't we will see a message confirming this.

```console
Already up to date.
```

The next step is switching to `main`:

```sh {title="education-blog"}
git switch main
```

Pause for a moment and look at the files in VSCode - see how the new tips you added have disappeared? That commit only exists on `update-blog-2`, so the changes we made don't show up on `main` yet. We can confirm this by checking `git log` and seeing that the commit isn't listed.

Next merge our working branch:

```sh {title="education-blog"}
git merge update-blog-2
```

This time we do have some commits to merge so we get a summary of the changes:

```console
Updating 4244c24..438484a
Fast-forward
blogs/1.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
```

And now our changes are visible in VSCode while we're on `main`.

### Deleting branches

When working on longer projects we will likely end up with a _lot_ of branches. This can get very confusing very quickly so we're going to practice good Git hygiene by deleting branches we no longer need.

We're going to use the `git branch` command again but this time we're going to add a flag. By including `-d` before a branch name we will delete the branch locally, but **not** on Github. Likewise if we delete a branch on Github the local version will remain. Let's delete `update-blog-2` since we're done updating our list for now.

```sh {title="education-blog"}
git branch -d update-blog-2
```

Checking with `git branch` will confirm the branch is gone.

{{<note type="caution" title="Make sure you mean to do this!">}}
Like most other things in the terminal, **this is permanent!** Make sure you're _definitely_ done with the branch before deleting it.
{{</note>}}
64 changes: 64 additions & 0 deletions common-content/en/module/git-cli/initialisation/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
+++
title = 'Working with Git in Terminal'

time = 10
[objectives]
1='Initialise a Git repository from the terminal'
[build]
render = 'never'
list = 'local'
publishResources = false

+++

So far you have seen two ways of interacting with your file system: your computer's terminal application and its explorer GUI. You probably have a preference and you probably prefer using one over the other for particular tasks. Neither is the "correct" way of working, but it's useful to know about both.

We have similar options for Git. So far we have been working with VSCode's version control tools and they're fine for what we need, but there are some things that are quite fiddly and some things we we can't do at all. In this sprint we'll look at using Git in the terminal and recreate our VSCode workflow, looking at some of the differences as we go.

### Preparation

We're going to recreate our workflow from the Onboarding module and sprint 1 of JavaScript Fundamentals exactly. We'll create the same files and the same commits, but this time we won't touch the source control tab at all.

Start by opening your terminal and creating a directory to work in. Call this one `git-cli-practice`

```sh
mkdir git-cli-practice
```

### Initialising a repository

Everything we did using buttons in VSCode can be recreated using terminal commands. Think back to working with packages last sprint: we knew we were doing something with npm because the commands we used all started with `npm`. In a similar way our Git commands will all start with `git`.

We initialise a new repository using the `init` command in our directory.

```sh {title="git-cli-practice"}
git init
```

Our directory is now a local git repository. We can confirm this using the `status` command.

```sh {title="git-cli-practice"}
git status
```

This should give the following output:

```console
On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)
```

We are ready to start committing!

{{<note type="tip" title="Visual indicators">}}
Some terminal applications will give a visual indication when the current directory is a git repository or can be customised to do so. For example, it may include the word "git" and the name of the current branch next to the directory name. Check the documentation for your OS and terminal app to find out how to set this up if you want to.
{{</note>}}

What have we actually done here? The `ls -a` command will list files and folders including anything which has been hidden and if we run it here we will see that a `.git` folder has been created. This is the directory Git uses to store our commit history and everything else it needs to do its job.

{{<note type="caution" title="Initialising in the wrong place">}}
Initialising a repository in the wrong place is a common mistake to make when learning how to use Git in the terminal. It can cause some tricky problems, but it isn't difficult to fix. Just delete the `.git` folder with `rm -r .git` and the repository will be deleted. Remember that this is permanent though - the files will remain but the commit history showing how they changed will be gone.
{{</note>}}
60 changes: 60 additions & 0 deletions common-content/en/module/git-cli/pushing-pulling/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
+++
title = 'Pushing & Pulling'

time = 20
[objectives]
1='Push to a remote repository from the terminal'
2='Configure a default upstream'
[build]
render = 'never'
list = 'local'
publishResources = false

+++

Our repositories are linked and it's time to push our changes. Once again we can condense many button clicks down to a single command in the terminal.

### Pushing changes

The command we will use is `git push`, but it needs two extra pieces of information:

- The remote we are pushing to
- The branch we are pushing

We only have one of each at the moment so our command will be pretty straight-forward. We'll see how to push a different branch in a later section.

```sh {title="git-cli-practice"}
git push origin main
```

This will take every commit on `mian` which has not yet been pushed and upload it to the url specified as `origin`. In our case this will be GitHub and if we check the repository now we will see our files there, just like when we used VSCode.

{{<note type="exercise" title="Exercise: Practice the workflow again">}}
1. Create a file called `facts.txt`
2. Add your favourite fun fact to the file
3. Save the file
4. Commit your changes
5. Add another fact. Commit this change.
6. Push to GitHub
7. Go to GitHub and refresh to see your changes!
{{</note>}}

### Default upstream

When we push to GitHub we are pushing to an **upstream** branch. If we are regularly pushing to the same branch we can configure a default so that we only need to type `git push` without the remote or branch name. **Handle with care!** When we are working in the terminal we don't have any of the safety features VSCode has and it would be very easy to accidentally push something to the wrong place if we rely on a default.

We can set a default by using the `-u` flag when we push.

```sh
git push -u origin main
```

### Pulling

The commands to pull are similar but use the `pull` keyword instead of `push`.

```sh
git pull origin main
```

It is possible to pull one branch from GitHub onto another locally, eg. pull the remote `main` onto the local `my-feature-branch`. This can lead to conflicts though and is best avoided in favour of managing branches properly.
Loading
Loading