Skip to content

Commit

Permalink
Merge branch 'main' into recipes-draft
Browse files Browse the repository at this point in the history
  • Loading branch information
martinosorb committed Aug 15, 2024
2 parents 97c652f + db7155f commit f046672
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 153 deletions.
13 changes: 0 additions & 13 deletions episodes/03-create.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,6 @@ including the tracked files and sub-directories located within the project's dir
If we ever delete the `.git` subdirectory,
we will lose the project's history.

Next, we will change the default branch to be called `main`.
This might be the default branch depending on your settings and version
of git.
See the [setup episode](02-setup.md#default-git-branch-naming) for more information on this change.

```bash
$ git checkout -b main
```

```output
Switched to a new branch 'main'
```

We can now start using one of the most important git commands, which is particularly helpful to beginners. `git status` tells us the status of our project, and better, a list of changes in the project and options on what to do with those changes. We can use it as often as we want, whenever we want to understand what is going on.

```bash
Expand Down
164 changes: 51 additions & 113 deletions episodes/05-history.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ while `HEAD~123` goes back 123 commits from where we are now.

We can also refer to commits using
those long strings of digits and letters
that `git log` displays.
that both `git log` and `git show` display.
These are unique IDs for the changes,
and "unique" really does mean unique:
every change to any set of files on any computer
Expand Down Expand Up @@ -171,7 +171,7 @@ index df0654a..93a3e13 100644
--- a/guacamole.md
+++ b/guacamole.md
@@ -1,3 +1,7 @@
# Gucamole
# Guacamole
## Ingredients
+* avocado
+* lime
Expand All @@ -197,18 +197,17 @@ $ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
(use "git restore <file>..." to discard changes in working directory)
modified: guacamole.md
no changes added to commit (use "git add" and/or "git commit -a")
```

We can put things back the way they were
by using `git checkout`:
by using `git restore`:

```bash
$ git checkout HEAD guacamole.md
$ git restore guacamole.md
$ cat guacamole.md
```

Expand All @@ -222,15 +221,15 @@ $ cat guacamole.md
```

As you might guess from its name,
`git checkout` checks out (i.e., restores) an old version of a file.
In this case,
we're telling Git that we want to recover the version of the file recorded in `HEAD`,
`git restore` restores an old version of a file.
By default,
it recovers the version of the file recorded in `HEAD`,
which is the last saved commit.
If we want to go back even further,
we can use a commit identifier instead:
we can use a commit identifier instead, using `-s` option:

```bash
$ git checkout f22b25e guacamole.md
$ git restore -s f22b25e guacamole.md
```

```bash
Expand All @@ -249,97 +248,46 @@ $ git status

```output
On branch main
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: guacamole.md
```

Notice that the changes are currently in the staging area.
Again, we can put things back the way they were
by using `git checkout`:

```bash
$ git checkout HEAD guacamole.md
```

::::::::::::::::::::::::::::::::::::::::: callout

## Don't Lose Your HEAD

Above we used
no changes added to commit (use "git add" and/or "git commit -a")
```bash
$ git checkout f22b25e guacamole.md
```

to revert `guacamole.md` to its state after the commit `f22b25e`. But be careful!
The command `checkout` has other important functionalities and Git will misunderstand
your intentions if you are not accurate with the typing. For example,
if you forget `guacamole.md` in the previous command.
Notice that the changes are currently in the staging area.
Again, we can put things back the way they were by using `git restore`:

```bash
$ git checkout f22b25e
$ git restore guacamole.md
$ cat guacamole.md
```

```error
Note: checking out 'f22b25e'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
HEAD is now at f22b25e Create a template for recipe
```output
# Guacamole
## Ingredients
* avocado
* lime
* salt
## Instructions
```

The "detached HEAD" is like "look, but don't touch" here,
so you shouldn't make any changes in this state.
After investigating your repo's past state, reattach your `HEAD` with `git checkout main`.


::::::::::::::::::::::::::::::::::::::::::::::::::

It's important to remember that
we must use the commit number that identifies the state of the repository
*before* the change we're trying to undo.
A common mistake is to use the number of
the commit in which we made the change we're trying to discard.
In the example below, we want to retrieve the state from before the most
recent commit (`HEAD~1`), which is commit `f22b25e`:
recent commit (`HEAD~1`), which is commit `f22b25e`. We use the `.` to mean all files:

![](fig/git-checkout.svg){alt='A diagram showing how git checkout HEAD~1 can be used to restore the previous version of two files'}
![](fig/git-restore.svg){alt='A diagram showing how git restore can be used to restore the previous version of two files'}

So, to put it all together,
here's how Git works in cartoon form:

![https://figshare.com/articles/How_Git_works_a_cartoon/1328266](fig/git_staging.svg){alt='A diagram showing the entire git workflow: local changes are staged using git add, applied to the local repository using git commit, and can be restored from the repository using git checkout'}

::::::::::::::::::::::::::::::::::::::::: callout

## Simplifying the Common Case

If you read the output of `git status` carefully,
you'll see that it includes this hint:

```output
(use "git checkout -- <file>..." to discard changes in working directory)
```

As it says,
`git checkout` without a version identifier restores files to the state saved in `HEAD`.
The double dash `--` is needed to separate the names of the files being recovered
from the command itself:
without it,
Git would try to use the name of the file as the commit identifier.


::::::::::::::::::::::::::::::::::::::::::::::::::

The fact that files can be reverted one by one
tends to change the way people organize their work.
Expand All @@ -362,13 +310,13 @@ Luckily, she has been keeping track of her project's versions using Git! Which c
let her recover the last committed version of her Python script called
`data_cruncher.py`?

1. `$ git checkout HEAD`
1. `$ git restore`

2. `$ git checkout HEAD data_cruncher.py`
2. `$ git restore data_cruncher.py`

3. `$ git checkout HEAD~1 data_cruncher.py`
3. `$ git restore -s HEAD~1 data_cruncher.py`

4. `$ git checkout <unique ID of last commit> data_cruncher.py`
4. `$ git restore -s <unique ID of last commit> data_cruncher.py`

5. Both 2 and 4

Expand All @@ -378,20 +326,16 @@ let her recover the last committed version of her Python script called

The answer is (5)-Both 2 and 4.

The `checkout` command restores files from the repository, overwriting the files in your working
The `restore` command restores files from the repository, overwriting the files in your working
directory. Answers 2 and 4 both restore the *latest* version *in the repository* of the file
`data_cruncher.py`. Answer 2 uses `HEAD` to indicate the *latest*, whereas answer 4 uses the
unique ID of the last commit, which is what `HEAD` means.

Answer 3 gets the version of `data_cruncher.py` from the commit *before* `HEAD`, which is NOT
what we wanted.

Answer 1 can be dangerous! Without a filename, `git checkout` will restore **all files**
in the current directory (and all directories below it) to their state at the commit specified.
This command will restore `data_cruncher.py` to the latest commit version, but it will also
restore *any other files that are changed* to that version, erasing any changes you may
have made to those files!
As discussed above, you are left in a *detached* `HEAD` state, and you don't want to be there.
Answer 1 results in an error. You need to specify a file to restore. If you want to restore all files
you should use `git restore .`



Expand All @@ -410,7 +354,7 @@ repository gets the correct change. The command `git revert [erroneous commit ID
new commit that reverses the erroneous commit.

The command `git revert` is
different from `git checkout [commit ID]` because `git checkout` returns the
different from `git restore -s [commit ID] .` because `git restore` returns the
files not yet committed within the local repository to a previous state, whereas `git revert`
reverses changes committed to the local and project repositories.

Expand Down Expand Up @@ -453,21 +397,21 @@ What is the output of the last command in
$ cd recipes
$ echo "I like tomatoes, therefore I like ketchup" > ketchup.md
$ git add ketchup.md
$ echo "ketchup enchances pasta dishes" > ketchup.md
$ echo "ketchup enhances pasta dishes" >> ketchup.md
$ git commit -m "My opinions about the red sauce"
$ git checkout HEAD ketchup.md
$ git restore ketchup.md
$ cat ketchup.md # this will print the content of ketchup.md on screen
```

1. ```output
ketchup enchances pasta dishes
ketchup enhances pasta dishes
```
2. ```output
I like tomatoes, therefore I like ketchup
```
3. ```output
I like tomatoes, therefore I like ketchup
ketchup enchances pasta dishes
ketchup enhances pasta dishes
```
4. ```output
Error because you have changed ketchup.md without committing the changes
Expand All @@ -489,7 +433,7 @@ has only one line.

At this time, the working copy still has the second line (and

`git status` will show that the file is modified). However, `git checkout HEAD ketchup.md`
`git status` will show that the file is modified). However, `git restore ketchup.md`
replaces the working copy with the most recently committed version of `ketchup.md`.
So, `cat ketchup.md` will output

Expand Down Expand Up @@ -519,23 +463,22 @@ and what does happen?

## Getting Rid of Staged Changes

`git checkout` can be used to restore a previous commit when unstaged changes have
`git restore` can be used to restore a previous commit when unstaged changes have
been made, but will it also work for changes that have been staged but not committed?
Make a change to `guacamole.md`, add that change using `git add`,
then use `git checkout` to see if you can remove your change.
then use `git restore` to see if you can remove your change.

::::::::::::::: solution

## Solution

After adding a change, `git checkout` can not be used directly.
After adding a change, `git restore` can not be used directly.
Let's look at the output of `git status`:

```output
On branch main
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
(use "git restore --staged <file>..." to unstage)
modified: guacamole.md
```
Expand All @@ -544,19 +487,15 @@ Note that if you don't have the same output
you may either have forgotten to change the file,
or you have added it *and* committed it.

Using the command `git checkout -- guacamole.md` now does not give an error,
Using the command `git restore guacamole.md` now does not give an error,
but it does not restore the file either.
Git helpfully tells us that we need to use `git reset` first
Git helpfully tells us that we need to use `git restore --staged` first
to unstage the file:

```bash
$ git reset HEAD guacamole.md
$ git restore --staged guacamole.md
```

```output
Unstaged changes after reset:
M guacamole.md

Now, `git status` gives us:

Expand All @@ -568,18 +507,17 @@ $ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
(use "git git restore <file>..." to discard changes in working directory)
modified: guacamole.md
no changes added to commit (use "git add" and/or "git commit -a")
```

This means we can now use `git checkout` to restore the file
This means we can now use `git restore` to restore the file
to the previous commit:

```bash
$ git checkout -- guacamole.md
$ git restore guacamole.md
$ git status
```

Expand Down Expand Up @@ -636,6 +574,6 @@ $ git log --patch HEAD~9 *.md
:::::::::::::::::::::::::::::::::::::::: keypoints

- `git diff` displays differences between commits.
- `git checkout` recovers old versions of files.
- `git restore` recovers old versions of files.

::::::::::::::::::::::::::::::::::::::::::::::::::
8 changes: 5 additions & 3 deletions episodes/07-github.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ Created directory '/c/Users/Alfredo/.ssh'.
Enter passphrase (empty for no passphrase):
```

Now, it is prompting Alfredo for a passphrase. Since he is using his kitchen's laptop that other people sometimes have access to, he wants to create a passphrase. Be sure to use something memorable or save your passphrase somewhere, as there is no "reset my password" option.
Now, it is prompting Alfredo for a passphrase. Since he is using his kitchen's laptop that other people sometimes have access to, he wants to create a passphrase. Be sure to use something memorable or save your passphrase somewhere, as there is no "reset my password" option.
Note that, when typing a passphrase on a terminal, there won't be any visual feedback of your typing.
This is normal: your passphrase will be recorded even if you see nothing changing on your screen.

```output
Enter same passphrase again:
Expand Down Expand Up @@ -273,8 +275,8 @@ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDmRA3d51X0uu9wXek559gfn6UFNF69yZjChyBIU2qKI a.linguini@ratatouille.fr
```

Now, going to GitHub.com, click on your profile icon in the top right corner to get the drop-down menu. Click "Settings," then on the
settings page, click "SSH and GPG keys," on the left side "Account settings" menu. Click the "New SSH key" button on the right side. Now,
Now, going to GitHub.com, click on your profile icon in the top right corner to get the drop-down menu. Click "Settings", then on the
settings page, click "SSH and GPG keys", on the left side "Access" menu. Click the "New SSH key" button on the right side. Now,
you can add the title (Alfredo uses the title "Alfredo's Kitchen Laptop" so he can remember where the original key pair
files are located), paste your SSH key into the field, and click the "Add SSH key" to complete the setup.

Expand Down
Loading

0 comments on commit f046672

Please sign in to comment.