diff --git a/02-setup.md b/02-setup.md index 2f23b88528..3e701495bb 100644 --- a/02-setup.md +++ b/02-setup.md @@ -27,14 +27,14 @@ of configurations we will set as we get started with Git: On a command line, Git commands are written as `git verb options`, where `verb` is what we actually want to do and `options` is additional optional information which may be needed for the `verb`. So here is how -Dracula sets up his new laptop: +Alfredo sets up his new laptop: ```bash -$ git config --global user.name "Vlad Dracula" -$ git config --global user.email "vlad@tran.sylvan.ia" +$ git config --global user.name "Alfredo Linguini" +$ git config --global user.email "a.linguini@ratatouille.fr" ``` -Please use your own name and email address instead of Dracula's. This user name and email will be associated with your subsequent Git activity, +Please use your own name and email address instead of Alfredo's. This user name and email will be associated with your subsequent Git activity, which means that any changes pushed to [GitHub](https://github.com/), [BitBucket](https://bitbucket.org/), @@ -84,7 +84,7 @@ $ git config --global core.autocrlf true :::::::::::::::::::::::::::::::::::::::::::::::::: -Dracula also has to set his favorite text editor, following this table: +Alfredo also has to set his favorite text editor, following this table: | Editor | Configuration command | | :----------- | :------------------------------ | @@ -118,7 +118,7 @@ If you want to save your changes and quit, press Esc then type `:wq` :::::::::::::::::::::::::::::::::::::::::::::::::: Git (2.28+) allows configuration of the name of the branch created when you -initialize any new repository. Dracula decides to use that feature to set it to `main` so +initialize any new repository. Alfredo decides to use that feature to set it to `main` so it matches the cloud service he will eventually use. ```bash diff --git a/03-create.md b/03-create.md index 3451c20061..c13ea4b2bf 100644 --- a/03-create.md +++ b/03-create.md @@ -20,32 +20,17 @@ exercises: 0 Once Git is configured, we can start using it. -We will continue with the story of Wolfman and Dracula who are investigating if it -is possible to send a planetary lander to Mars. - -![](fig/motivatingexample.png){alt='The main elements of the story: Dracula, Wolfman, the Mummy, Mars, Pluto and The Moon'} -[Werewolf vs dracula](https://www.deviantart.com/b-maze/art/Werewolf-vs-Dracula-124893530) -by [b-maze](https://www.deviantart.com/b-maze) / [Deviant Art](https://www.deviantart.com/). -[Mars](https://en.wikipedia.org/wiki/File:OSIRIS_Mars_true_color.jpg) by European Space Agency / -[CC-BY-SA 3.0 IGO](https://creativecommons.org/licenses/by/3.0/deed.en). -[Pluto](https://commons.wikimedia.org/wiki/File:PIA19873-Pluto-NewHorizons-FlyingPastImage-20150714-transparent.png) / -Courtesy NASA/JPL-Caltech. -[Mummy](https://commons.wikimedia.org/wiki/File:Mummy_icon_-_Noun_Project_4070.svg) -© Gilad Fried / [The Noun Project](https://thenounproject.com/) / -[CC BY 3.0](https://creativecommons.org/licenses/by/3.0/deed.en). -[Moon](https://commons.wikimedia.org/wiki/File:Lune_ico.png) -© Luc Viatour / [https://lucnix.be](https://lucnix.be/) / -[CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/deed.en). +We will help Alfredo with his new project, create a repository with all his recipes. First, let's create a new directory in the `Desktop` folder for our work and then change the current working directory to the newly created one: ```bash $ cd ~/Desktop -$ mkdir planets -$ cd planets +$ mkdir recipes +$ cd recipes ``` -Then we tell Git to make `planets` a [repository](../learners/reference.md#repository) +Then we tell Git to make `recipes` a [repository](../learners/reference.md#repository) \-- a place where Git can store versions of our files: ```bash @@ -54,9 +39,9 @@ $ git init It is important to note that `git init` will create a repository that can include subdirectories and their files---there is no need to create -separate repositories nested within the `planets` repository, whether +separate repositories nested within the `recipes` repository, whether subdirectories are present from the beginning or added later. Also, note -that the creation of the `planets` directory and its initialization as a +that the creation of the `recipes` directory and its initialization as a repository are completely separate processes. If we use `ls` to show the directory's contents, @@ -67,7 +52,7 @@ $ ls ``` But if we add the `-a` flag to show everything, -we can see that Git has created a hidden directory within `planets` called `.git`: +we can see that Git has created a hidden directory within `recipes` called `.git`: ```bash $ ls -a @@ -82,6 +67,19 @@ 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 @@ -103,33 +101,33 @@ wording of the output might be slightly different. ## Places to Create Git Repositories -Along with tracking information about planets (the project we have already created), -Dracula would also like to track information about moons. -Despite Wolfman's concerns, Dracula creates a `moons` project inside his `planets` +Along with tracking information about recipes (the project we have already created), +Alfredo would also like to track information about desserts specifically. +Alfredo creates a `desserts` project inside his `recipes` project with the following sequence of commands: ```bash -$ cd ~/Desktop # return to Desktop directory -$ cd planets # go into planets directory, which is already a Git repository -$ ls -a # ensure the .git subdirectory is still present in the planets directory -$ mkdir moons # make a subdirectory planets/moons -$ cd moons # go into moons subdirectory -$ git init # make the moons subdirectory a Git repository -$ ls -a # ensure the .git subdirectory is present indicating we have created a new Git repository +$ cd ~/Desktop # return to Desktop directory +$ cd recipes # go into recipes directory, which is already a Git repository +$ ls -a # ensure the .git subdirectory is still present in the recipes directory +$ mkdir desserts # make a sub-directory recipes/desserts +$ cd desserts # go into desserts subdirectory +$ git init # make the desserts subdirectory a Git repository +$ ls -a # ensure the .git subdirectory is present indicating we have created a new Git repository ``` -Is the `git init` command, run inside the `moons` subdirectory, required for -tracking files stored in the `moons` subdirectory? +Is the `git init` command, run inside the `desserts` subdirectory, required for +tracking files stored in the `desserts` subdirectory? ::::::::::::::: solution ## Solution -No. Dracula does not need to make the `moons` subdirectory a Git repository -because the `planets` repository can track any files, sub-directories, and -subdirectory files under the `planets` directory. Thus, in order to track -all information about moons, Dracula only needed to add the `moons` subdirectory -to the `planets` directory. +No. Alfredo does not need to make the `desserts` subdirectory a Git repository +because the `recipes` repository will track all files, sub-directories, and +subdirectory files under the `recipes` directory. Thus, in order to track +all information about desserts, Alfredo only needed to add the `desserts` subdirectory +to the `recipes` directory. Additionally, Git repositories can interfere with each other if they are "nested": the outer repository will try to version-control @@ -151,9 +149,9 @@ fatal: Not a git repository (or any of the parent directories): .git ## Correcting `git init` Mistakes -Wolfman explains to Dracula how a nested repository is redundant and may cause confusion -down the road. Dracula would like to go back to a single git repository. How can Dracula undo -his last `git init` in the `moons` subdirectory? +Jimmy explains to Alfredo how a nested repository is redundant and may cause confusion +down the road. Alfredo would like to go back to a single git repository. How can Alfredo undo +his last `git init` in the `desserts` subdirectory? ::::::::::::::: solution @@ -176,11 +174,11 @@ becomes another change that we will need to track, as we will see in the next ep ### Solution Git keeps all of its files in the `.git` directory. -To recover from this little mistake, Dracula can remove the `.git` -folder in the moons subdirectory by running the following command from inside the `planets` directory: +To recover from this little mistake, Alfredo can remove the `.git` +folder in the desserts subdirectory by running the following command from inside the `recipes` directory: ```bash -$ rm -rf moons/.git +$ rm -rf desserts/.git ``` But be careful! Running this command in the wrong directory will remove diff --git a/04-changes.md b/04-changes.md index 337dea69b1..9920166bb2 100644 --- a/04-changes.md +++ b/04-changes.md @@ -21,26 +21,28 @@ exercises: 0 :::::::::::::::::::::::::::::::::::::::::::::::::: First let's make sure we're still in the right directory. -You should be in the `planets` directory. +You should be in the `recipes` directory. ```bash -$ cd ~/Desktop/planets +$ cd ~/Desktop/recipes ``` -Let's create a file called `mars.txt` that contains some notes -about the Red Planet's suitability as a base. +Let's create a file called `guacamole.md` that contains the basic structure to +have a recipe. We'll use `nano` to edit the file; you can use whatever editor you like. In particular, this does not have to be the `core.editor` you set globally earlier. But remember, the bash command to create or edit a new file will depend on the editor you choose (it might not be `nano`). For a refresher on text editors, check out ["Which Editor?"](https://swcarpentry.github.io/shell-novice/03-create.html#which-editor) in [The Unix Shell](https://swcarpentry.github.io/shell-novice/) lesson. ```bash -$ nano mars.txt +$ nano guacamole.md ``` -Type the text below into the `mars.txt` file: +Type the text below into the `guacamole.md` file: ```output -Cold and dry, but everything is my favorite color +# Guacamole +## Ingredients +## Instructions ``` Let's first verify that the file was properly created by running the list command (`ls`): @@ -50,17 +52,19 @@ $ ls ``` ```output -mars.txt +guacamole.md ``` -`mars.txt` contains a single line, which we can see by running: +`guacamole.md` contains a single line, which we can see by running: ```bash -$ cat mars.txt +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color +# Guacamole +## Ingredients +## Instructions ``` If we check the status of our project again, @@ -78,7 +82,7 @@ No commits yet Untracked files: (use "git add ..." to include in what will be committed) - mars.txt + guacamole.md nothing added to commit but untracked files present (use "git add" to track) ``` @@ -88,7 +92,7 @@ that Git isn't keeping track of. We can tell Git to track a file using `git add`: ```bash -$ git add mars.txt +$ git add guacamole.md ``` and then check that the right thing happened: @@ -105,23 +109,23 @@ No commits yet Changes to be committed: (use "git rm --cached ..." to unstage) - new file: mars.txt + new file: guacamole.md ``` -Git now knows that it's supposed to keep track of `mars.txt`, +Git now knows that it's supposed to keep track of `guacamole.md`, but it hasn't recorded these changes as a commit yet. To get it to do that, we need to run one more command: ```bash -$ git commit -m "Start notes on Mars as a base" +$ git commit -m "Create a template for recipe" ``` ```output -[main (root-commit) f22b25e] Start notes on Mars as a base +[main (root-commit) f22b25e] Create a template for recipe 1 file changed, 1 insertion(+) - create mode 100644 mars.txt + create mode 100644 guacamole.md ``` When we run `git commit`, @@ -161,10 +165,10 @@ $ git log ```output commit f22b25e3233b4645dabd0d81e651fe074bd8e73b -Author: Vlad Dracula +Author: Alfredo Linguini Date: Thu Aug 22 09:51:46 2013 -0400 - Start notes on Mars as a base + Create a template for recipe ``` `git log` lists all commits made to a repository in reverse chronological order. @@ -180,7 +184,7 @@ and the log message Git was given when the commit was created. ## Where Are My Changes? -If we run `ls` at this point, we will still see just one file called `mars.txt`. +If we run `ls` at this point, we will still see just one file called `guacamole.md`. That's because Git saves information about files' history in the special `.git` directory mentioned earlier so that our filesystem doesn't become cluttered @@ -189,18 +193,22 @@ so that our filesystem doesn't become cluttered :::::::::::::::::::::::::::::::::::::::::::::::::: -Now suppose Dracula adds more information to the file. +Now suppose Alfredo adds more information to the file. (Again, we'll edit with `nano` and then `cat` the file to show its contents; you may use a different editor, and don't need to `cat`.) ```bash -$ nano mars.txt -$ cat mars.txt +$ nano guacamole.md +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman +# Guacamole +## Ingredients +* avocado +* lemon +* salt +## Instructions ``` When we run `git status` now, @@ -216,7 +224,7 @@ Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) - modified: mars.txt + modified: guacamole.md no changes added to commit (use "git add" and/or "git commit -a") ``` @@ -237,13 +245,17 @@ $ git diff ``` ```output -diff --git a/mars.txt b/mars.txt +diff --git a/guacamole.md b/guacamole.md index df0654a..315bf3a 100644 ---- a/mars.txt -+++ b/mars.txt -@@ -1 +1,2 @@ - Cold and dry, but everything is my favorite color -+The two moons may be a problem for Wolfman +--- a/guacamole.md ++++ b/guacamole.md +@@ -1,3 +1,6 @@ + # Guacamole + ## Ingredients ++* avocado ++* lemon ++* salt + ## Instructions ``` The output is cryptic because @@ -265,7 +277,8 @@ If we break it down into pieces: After reviewing our change, it's time to commit it: ```bash -$ git commit -m "Add concerns about effects of Mars' moons on Wolfman" +$ git commit -m "Add basic guacamole's ingredients" +$ git status ``` ```output @@ -274,7 +287,7 @@ Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) - modified: mars.txt + modified: guacamole.md no changes added to commit (use "git add" and/or "git commit -a") ``` @@ -284,13 +297,13 @@ Git won't commit because we didn't use `git add` first. Let's fix that: ```bash -$ git add mars.txt -$ git commit -m "Add concerns about effects of Mars' moons on Wolfman" +$ git add guacamole.md +$ git commit -m "Add basic guacamole's ingredients" ``` ```output -[main 34961b1] Add concerns about effects of Mars' moons on Wolfman - 1 file changed, 1 insertion(+) +[main 34961b1] Add basic guacamole's ingredient + 1 file changed, 3 insertions(+) ``` Git insists that we add files to the set we want to commit @@ -340,17 +353,20 @@ Let's watch as our changes to a file move from our editor to the staging area and into long-term storage. First, -we'll add another line to the file: +we'll improve our recipe by changing 'lemon' to 'lime': ```bash -$ nano mars.txt -$ cat mars.txt +$ nano guacamole.md +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity +# Guacamole +## Ingredients +* avocado +* lime +* salt +## Instructions ``` ```bash @@ -358,24 +374,28 @@ $ git diff ``` ```output -diff --git a/mars.txt b/mars.txt +diff --git a/guacamole.md b/guacamole.md index 315bf3a..b36abfd 100644 ---- a/mars.txt -+++ b/mars.txt -@@ -1,2 +1,3 @@ - Cold and dry, but everything is my favorite color - The two moons may be a problem for Wolfman -+But the Mummy will appreciate the lack of humidity +--- a/guacamole.md ++++ b/guacamole.md +@@ -1,6 +1,6 @@ + # Guacamole + ## Ingredients + * avocado +-* lemon ++* lime + * salt + ## Instructions ``` So far, so good: -we've added one line to the end of the file +we've replaced one line (shown with a `-` in the first column) with a new line (shown with a `+` in the first column). Now let's put that change in the staging area and see what `git diff` reports: ```bash -$ git add mars.txt +$ git add guacamole.md $ git diff ``` @@ -391,14 +411,18 @@ $ git diff --staged ``` ```output -diff --git a/mars.txt b/mars.txt +diff --git a/guacamole.md b/guacamole.md index 315bf3a..b36abfd 100644 ---- a/mars.txt -+++ b/mars.txt -@@ -1,2 +1,3 @@ - Cold and dry, but everything is my favorite color - The two moons may be a problem for Wolfman -+But the Mummy will appreciate the lack of humidity +--- a/guacamole.md ++++ b/guacamole.md +@@ -1,6 +1,6 @@ + # Guacamole + ## Ingredients + * avocado +-* lemon ++* lime + * salt + ## Instructions ``` it shows us the difference between @@ -407,11 +431,11 @@ and what's in the staging area. Let's save our changes: ```bash -$ git commit -m "Discuss concerns about Mars' climate for Mummy" +$ git commit -m "Modify guacamole to the traditional recipe" ``` ```output -[main 005937f] Discuss concerns about Mars' climate for Mummy +[main 005937f] Modify guacamole to the traditional recipe 1 file changed, 1 insertion(+) ``` @@ -434,22 +458,22 @@ $ git log ```output commit 005937fbe2a98fb83f0ade869025dc2636b4dad5 (HEAD -> main) -Author: Vlad Dracula +Author: Alfredo Linguini Date: Thu Aug 22 10:14:07 2013 -0400 - Discuss concerns about Mars' climate for Mummy + Modify guacamole to the traditional recipe commit 34961b159c27df3b475cfe4415d94a6d1fcd064d -Author: Vlad Dracula +Author: Alfredo Linguini Date: Thu Aug 22 10:07:21 2013 -0400 - Add concerns about effects of Mars' moons on Wolfman + Add basic guacamole's ingredients commit f22b25e3233b4645dabd0d81e651fe074bd8e73b -Author: Vlad Dracula +Author: Alfredo Linguini Date: Thu Aug 22 09:51:46 2013 -0400 - Start notes on Mars as a base + Create a template for recipe ``` ::::::::::::::::::::::::::::::::::::::::: callout @@ -498,10 +522,10 @@ $ git log -1 ```output commit 005937fbe2a98fb83f0ade869025dc2636b4dad5 (HEAD -> main) -Author: Vlad Dracula +Author: Alfredo Linguini Date: Thu Aug 22 10:14:07 2013 -0400 - Discuss concerns about Mars' climate for Mummy + Modify guacamole to the traditional recipe ``` You can also reduce the quantity of information using the @@ -512,9 +536,9 @@ $ git log --oneline ``` ```output -005937f (HEAD -> main) Discuss concerns about Mars' climate for Mummy -34961b1 Add concerns about effects of Mars' moons on Wolfman -f22b25e Start notes on Mars as a base +005937f (HEAD -> main) Modify guacamole to the traditional recipe +34961b1 Add basic guacamole's ingredients +f22b25e Create a template for recipe ``` You can also combine the `--oneline` option with others. One useful @@ -528,9 +552,9 @@ $ git log --oneline --graph ``` ```output -* 005937f (HEAD -> main) Discuss concerns about Mars' climate for Mummy -* 34961b1 Add concerns about effects of Mars' moons on Wolfman -* f22b25e Start notes on Mars as a base +* 005937f (HEAD -> main) Modify guacamole to the traditional recipe +* 34961b1 Add basic guacamole's ingredients +* f22b25e Create a template for recipe ``` :::::::::::::::::::::::::::::::::::::::::::::::::: @@ -545,13 +569,13 @@ Two important facts you should know about directories in Git. Try it for yourself: ```bash - $ mkdir spaceships + $ mkdir cakes $ git status - $ git add spaceships + $ git add cakes $ git status ``` - Note, our newly created empty directory `spaceships` does not appear in + Note, our newly created empty directory `cakes` does not appear in the list of untracked files even if we explicitly add it (*via* `git add`) to our repository. This is the reason why you will sometimes see `.gitkeep` files in otherwise empty directories. Unlike `.gitignore`, these files are not special @@ -568,16 +592,16 @@ Two important facts you should know about directories in Git. Try it for yourself: ```bash - $ touch spaceships/apollo-11 spaceships/sputnik-1 + $ touch cakes/brownie cakes/lemon_drizzle $ git status - $ git add spaceships + $ git add cakes $ git status ``` Before moving on, we will commit these changes. ```bash - $ git commit -m "Add some initial thoughts on spaceships" + $ git commit -m "Add some initial cakes" ``` :::::::::::::::::::::::::::::::::::::::::::::::::: @@ -594,11 +618,11 @@ repository (`git commit`): ## Choosing a Commit Message Which of the following commit messages would be most appropriate for the -last commit made to `mars.txt`? +last commit made to `guacamole.md`? 1. "Changes" -2. "Added line 'But the Mummy will appreciate the lack of humidity' to mars.txt" -3. "Discuss effects of Mars' climate on the Mummy" +2. "Changed lemon for lime" +3. "Guacamole modified to the traditional recipe" ::::::::::::::: solution @@ -658,10 +682,10 @@ to my local Git repository? The staging area can hold changes from any number of files that you want to commit as a single snapshot. -1. Add some text to `mars.txt` noting your decision - to consider Venus as a base -2. Create a new file `venus.txt` with your initial thoughts - about Venus as a base for you and your friends +1. Add some text to `guacamole.md` noting the rough price of the + ingredients. +2. Create a new file `groceries.md` with a list of products and + their prices for different markets. 3. Add changes from both files to the staging area, and commit those changes. @@ -669,53 +693,57 @@ that you want to commit as a single snapshot. ## Solution -The output below from `cat mars.txt` reflects only content added during -this exercise. Your output may vary. - -First we make our changes to the `mars.txt` and `venus.txt` files: +First we make our changes to the `guacamole.md` and `groceries.md` files: ```bash -$ nano mars.txt -$ cat mars.txt +$ nano guacamole.md +$ cat guacamole.md ``` ```output -Maybe I should start with a base on Venus. +# Guacamole +## Ingredients +* avocado (1.35) +* lime (0.64) +* salt (2) ``` ```bash -$ nano venus.txt -$ cat venus.txt +$ nano groceries.md +$ cat groceries.md ``` ```output -Venus is a nice planet and I definitely should consider it as a base. +# Market A +* avocado: 1.35 per unit. +* lime: 0.64 per unit +* salt: 2 per kg ``` Now you can add both files to the staging area. We can do that in one line: ```bash -$ git add mars.txt venus.txt +$ git add guacamole.md groceries.md ``` Or with multiple commands: ```bash -$ git add mars.txt -$ git add venus.txt +$ git add guacamole.md +$ git add groceries.md ``` Now the files are ready to commit. You can check that using `git status`. If you are ready to commit use: ```bash -$ git commit -m "Write plans to start a base on Venus" +$ git commit -m "Write prices for ingredients and their source" ``` ```output [main cc127c2] - Write plans to start a base on Venus - 2 files changed, 2 insertions(+) - create mode 100644 venus.txt + Write prices for ingredients and their source + 2 files changed, 7 insertions(+) + create mode 100644 groceries.md ``` ::::::::::::::::::::::::: @@ -737,7 +765,7 @@ $ git commit -m "Write plans to start a base on Venus" ## Solution -If needed, move out of the `planets` folder: +If needed, move out of the `recipes` folder: ```bash $ cd .. @@ -761,7 +789,7 @@ Once in place, add and commit it to the repository: ```bash $ git add me.txt -$ git commit -m "Add biography file" +$ git commit -m "Add biography file" ``` Modify the file as described (modify one line, add a fourth line). diff --git a/05-history.md b/05-history.md index b4633ef442..938b1dd7fe 100644 --- a/05-history.md +++ b/05-history.md @@ -25,38 +25,41 @@ As we saw in the previous episode, we can refer to commits by their identifiers. You can refer to the *most recent commit* of the working directory by using the identifier `HEAD`. -We've been adding one line at a time to `mars.txt`, so it's easy to track our +We've been adding small changes at a time to `guacamole.md`, so it's easy to track our progress by looking, so let's do that using our `HEAD`s. Before we start, -let's make a change to `mars.txt`, adding yet another line. +let's make a change to `guacamole.md`, adding yet another line. ```bash -$ nano mars.txt -$ cat mars.txt +$ nano guacamole.md +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity +# Guacamole +## Ingredients +* avocado +* lime +* salt +## Instructions An ill-considered change ``` Now, let's see what we get. ```bash -$ git diff HEAD mars.txt +$ git diff HEAD guacamole.md ``` ```output -diff --git a/mars.txt b/mars.txt +diff --git a/guacamole.md b/guacamole.md index b36abfd..0848c8d 100644 ---- a/mars.txt -+++ b/mars.txt -@@ -1,3 +1,4 @@ - Cold and dry, but everything is my favorite color - The two moons may be a problem for Wolfman - But the Mummy will appreciate the lack of humidity -+An ill-considered change. +--- a/guacamole.md ++++ b/guacamole.md +@@ -4,3 +4,4 @@ + * lime + * salt + ## Instructions ++An ill-considered change ``` which is the same as what you would get if you leave out `HEAD` (try it). The @@ -66,26 +69,28 @@ that by adding `~1` to refer to the commit one before `HEAD`. ```bash -$ git diff HEAD~1 mars.txt +$ git diff HEAD~1 guacamole.md ``` If we want to see the differences between older commits we can use `git diff` again, but with the notation `HEAD~1`, `HEAD~2`, and so on, to refer to them: ```bash -$ git diff HEAD~2 mars.txt +$ git diff HEAD~2 guacamole.md ``` ```output -diff --git a/mars.txt b/mars.txt +diff --git a/guacamole.md b/guacamole.md index df0654a..b36abfd 100644 ---- a/mars.txt -+++ b/mars.txt -@@ -1 +1,4 @@ - Cold and dry, but everything is my favorite color -+The two moons may be a problem for Wolfman -+But the Mummy will appreciate the lack of humidity -+An ill-considered change +--- a/guacamole.md ++++ b/guacamole.md +@@ -1,3 +1,6 @@ + # Guacamole + ## Ingredients ++* avocado ++* lime ++* salt + ## Instructions ``` We could also use `git show` which shows us what changes we made at an older commit as @@ -93,23 +98,25 @@ well as the commit message, rather than the *differences* between a commit and o working directory that we see by using `git diff`. ```bash -$ git show HEAD~2 mars.txt +$ git show HEAD~2 guacamole.md ``` ```output commit f22b25e3233b4645dabd0d81e651fe074bd8e73b -Author: Vlad Dracula -Date: Thu Aug 22 09:51:46 2013 -0400 +Author: Alfredo Linguini +Date: Thu Aug 22 10:07:21 2013 -0400 - Start notes on Mars as a base + Create a template for recipe -diff --git a/mars.txt b/mars.txt +diff --git a/guacamole.md b/guacamole.md new file mode 100644 index 0000000..df0654a --- /dev/null -+++ b/mars.txt -@@ -0,0 +1 @@ -+Cold and dry, but everything is my favorite color ++++ b/guacamole.md +@@ -0,0 +1,3 @@ ++# Guacamole ++## Ingredients ++## Instructions ``` In this way, @@ -122,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 both `git log` and `git show` display. +that `git log` displays. These are unique IDs for the changes, and "unique" really does mean unique: every change to any set of files on any computer @@ -132,18 +139,21 @@ Our first commit was given the ID so let's try this: ```bash -$ git diff f22b25e3233b4645dabd0d81e651fe074bd8e73b mars.txt +$ git diff f22b25e3233b4645dabd0d81e651fe074bd8e73b guacamole.md ``` ```output -diff --git a/mars.txt b/mars.txt +diff --git a/guacamole.md b/guacamole.md index df0654a..93a3e13 100644 ---- a/mars.txt -+++ b/mars.txt -@@ -1 +1,4 @@ - Cold and dry, but everything is my favorite color -+The two moons may be a problem for Wolfman -+But the Mummy will appreciate the lack of humidity +--- a/guacamole.md ++++ b/guacamole.md +@@ -1,3 +1,7 @@ + # Guacamole + ## Ingredients ++* avocado ++* lime ++* salt + ## Instructions +An ill-considered change ``` @@ -152,18 +162,21 @@ but typing out random 40-character strings is annoying, so Git lets us use just the first few characters (typically seven for normal size projects): ```bash -$ git diff f22b25e mars.txt +$ git diff f22b25e guacamole.md ``` ```output -diff --git a/mars.txt b/mars.txt +diff --git a/guacamole.md b/guacamole.md index df0654a..93a3e13 100644 ---- a/mars.txt -+++ b/mars.txt -@@ -1 +1,4 @@ - Cold and dry, but everything is my favorite color -+The two moons may be a problem for Wolfman -+But the Mummy will appreciate the lack of humidity +--- a/guacamole.md ++++ b/guacamole.md +@@ -1,3 +1,7 @@ + # Gucamole + ## Ingredients ++* avocado ++* lime ++* salt + ## Instructions +An ill-considered change ``` @@ -171,7 +184,7 @@ All right! So we can save changes to files and see what we've changed. Now, how can we restore older versions of things? Let's suppose we change our mind about the last update to -`mars.txt` (the "ill-considered change"). +`guacamole.md` (the "ill-considered change"). `git status` now tells us that the file has been changed, but those changes haven't been staged: @@ -184,45 +197,50 @@ $ git status On branch main Changes not staged for commit: (use "git add ..." to update what will be committed) - (use "git restore ..." to discard changes in working directory) + (use "git checkout -- ..." to discard changes in working directory) - modified: mars.txt + 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 restore`: +by using `git checkout`: ```bash -$ git restore mars.txt -$ cat mars.txt +$ git checkout HEAD guacamole.md +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity +# Guacamole +## Ingredients +* avocado +* lime +* salt +## Instructions ``` As you might guess from its name, -`git restore` restores an old version of a file. -By default, -it recovers the version of the file recorded in `HEAD`, +`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`, which is the last saved commit. If we want to go back even further, -we can use a commit identifier instead, using `-s` option: +we can use a commit identifier instead: ```bash -$ git restore -s f22b25e mars.txt +$ git checkout f22b25e guacamole.md ``` ```bash -$ cat mars.txt +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color +# Guacamole +## Ingredients +## Instructions ``` ```bash @@ -231,28 +249,61 @@ $ git status ```output On branch main -Changes not staged for commit: - (use "git add ..." to update what will be committed) - (use "git restore ..." to discard changes in working directory) - modified: mars.txt +Changes to be committed: + (use "git reset HEAD ..." to unstage) -no changes added to commit (use "git add" and/or "git commit -a") + 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 restore`: + +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 restore mars.txt -$ cat mars.txt +$ git checkout HEAD guacamole.md ``` -```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity +::::::::::::::::::::::::::::::::::::::::: callout + +## Don't Lose Your HEAD + +Above we used + +```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. + +```bash +$ git checkout f22b25e +``` + +```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 + +HEAD is now at f22b25e Create a template for recipe +``` + +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 @@ -260,15 +311,35 @@ we must use the commit number that identifies the state of the repository 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`. We use the `.` to mean all files: +recent commit (`HEAD~1`), which is commit `f22b25e`: -![](fig/git-restore.svg){alt='A diagram showing how git restore can be used to restore the previous version of two 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'} 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: + +```bash +(use "git checkout -- ..." 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. @@ -291,13 +362,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 restore` +1. `$ git checkout HEAD` -2. `$ git restore data_cruncher.py` +2. `$ git checkout HEAD data_cruncher.py` -3. `$ git restore -s HEAD~1 data_cruncher.py` +3. `$ git checkout HEAD~1 data_cruncher.py` -4. `$ git restore -s data_cruncher.py` +4. `$ git checkout data_cruncher.py` 5. Both 2 and 4 @@ -307,7 +378,7 @@ let her recover the last committed version of her Python script called The answer is (5)-Both 2 and 4. -The `restore` command restores files from the repository, overwriting the files in your working +The `checkout` 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. @@ -315,8 +386,12 @@ 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 results in an error. You need to specify a file to restore. If you want to restore all files -you should use `git restore .` +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. @@ -335,7 +410,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 restore -s [commit ID] .` because `git restore` returns the +different from `git checkout [commit ID]` because `git checkout` 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. @@ -375,27 +450,27 @@ else has committed changes to the repository. What is the output of the last command in ```bash -$ cd planets -$ echo "Venus is beautiful and full of love" > venus.txt -$ git add venus.txt -$ echo "Venus is too hot to be suitable as a base" >> venus.txt -$ git commit -m "Comment on Venus as an unsuitable base" -$ git restore venus.txt -$ cat venus.txt #this will print the contents of venus.txt to the screen +$ cd recipes +$ echo "I like tomatos, therefore I like ketchup" > ketchup.md +$ git add ketchup.md +$ echo "ketchup enchances pasta dishes" > ketchup.md +$ git commit -m "my opinions about the red sauce" +$ git checkout HEAD ketchup.md +$ cat ketchup.md # this will print the content of ketchup.md on screen ``` 1. ```output - Venus is too hot to be suitable as a base + ketchup enchances pasta dishes ``` 2. ```output - Venus is beautiful and full of love + I like tomatos, therefore I like ketchup ``` 3. ```output - Venus is beautiful and full of love - Venus is too hot to be suitable as a base + I like tomatos, therefore I like ketchup + ketchup enchances pasta dishes ``` 4. ```output - Error because you have changed venus.txt without committing the changes + Error because you have changed ketchup.md without committing the changes ``` ::::::::::::::: solution @@ -404,22 +479,22 @@ $ cat venus.txt #this will print the contents of venus.txt to the screen The answer is 2. -The command `git add venus.txt` places the current version of `venus.txt` into the staging area. The changes to the file from the second `echo` command are only applied to the working copy, +The command `git add ketchup.md` places the current version of `ketchup.md` into the staging area. not the version in the staging area. -So, when `git commit -m "Comment on Venus as an unsuitable base"` is executed, -the version of `venus.txt` committed to the repository is the one from the staging area and +So, when `git commit -m "my opinions about the red sauce"` is executed, +the version of `ketchup.md` committed to the repository is the one from the staging area and 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 restore venus.txt` -replaces the working copy with the most recently committed version of `venus.txt`. -So, `cat venus.txt` will output +`git status` will show that the file is modified). However, `git checkout HEAD ketchup.md` +replaces the working copy with the most recently committed version of `ketchup.md`. +So, `cat ketchup.md` will output ```output -Venus is beautiful and full of love. +I like tomatos, therefore I like ketchup ``` ::::::::::::::::::::::::: @@ -430,10 +505,10 @@ Venus is beautiful and full of love. ## Checking Understanding of `git diff` -Consider this command: `git diff HEAD~9 mars.txt`. What do you predict this command +Consider this command: `git diff HEAD~9 guacamole.md`. What do you predict this command will do if you execute it? What happens when you do execute it? Why? -Try another command, `git diff [ID] mars.txt`, where [ID] is replaced with +Try another command, `git diff [ID] guacamole.md`, where [ID] is replaced with the unique identifier for your most recent commit. What do you think will happen, and what does happen? @@ -444,23 +519,24 @@ and what does happen? ## Getting Rid of Staged Changes -`git restore` can be used to restore a previous commit when unstaged changes have +`git checkout` 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 `mars.txt`, add that change using `git add`, -then use `git restore` to see if you can remove your change. +Make a change to `guacamole.md`, add that change using `git add`, +then use `git checkout` to see if you can remove your change. ::::::::::::::: solution ## Solution -After adding a change, `git restore` can not be used directly. +After adding a change, `git checkout` can not be used directly. Let's look at the output of `git status`: ```output On branch main Changes to be committed: - (use "git restore --staged ..." to unstage) - modified: mars.txt + (use "git reset HEAD ..." to unstage) + + modified: guacamole.md ``` @@ -468,15 +544,19 @@ 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 restore mars.txt` now does not give an error, +Using the command `git checkout -- 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 restore --staged` first +Git helpfully tells us that we need to use `git reset` first to unstage the file: ```bash -$ git restore --staged mars.txt +$ git reset HEAD guacamole.md ``` +```output +Unstaged changes after reset: +M guacamole.md + Now, `git status` gives us: @@ -488,18 +568,18 @@ $ git status On branch main Changes not staged for commit: (use "git add ..." to update what will be committed) - (use "git git restore ..." to discard changes in working directory) + (use "git checkout -- ..." to discard changes in working directory) - modified: mars.txt + modified: guacamole.md no changes added to commit (use "git add" and/or "git commit -a") ``` -This means we can now use `git restore` to restore the file +This means we can now use `git checkout` to restore the file to the previous commit: ```bash -$ git restore mars.txt +$ git checkout -- guacamole.md $ git status ``` @@ -519,16 +599,16 @@ nothing to commit, working tree clean Exploring history is an important part of Git, and often it is a challenge to find the right commit ID, especially if the commit is from several months ago. -Imagine the `planets` project has more than 50 files. -You would like to find a commit that modifies some specific text in `mars.txt`. +Imagine the `recipes` project has more than 50 files. +You would like to find a commit that modifies some specific text in `guacamole.md`. When you type `git log`, a very long list appeared. How can you narrow down the search? Recall that the `git diff` command allows us to explore one specific file, -e.g., `git diff mars.txt`. We can apply a similar idea here. +e.g., `git diff guacamole.md`. We can apply a similar idea here. ```bash -$ git log mars.txt +$ git log guacamole.md ``` Unfortunately some of these commit messages are very ambiguous, e.g., `update files`. @@ -539,7 +619,7 @@ for you. Is it possible to combine both? Let's try the following: ```bash -$ git log --patch mars.txt +$ git log --patch guacamole.md ``` You should get a long list of output, and you should be able to see both commit messages and @@ -548,7 +628,7 @@ the difference between each commit. Question: What does the following command do? ```bash -$ git log --patch HEAD~9 *.txt +$ git log --patch HEAD~9 *.md ``` :::::::::::::::::::::::::::::::::::::::::::::::::: @@ -556,6 +636,6 @@ $ git log --patch HEAD~9 *.txt :::::::::::::::::::::::::::::::::::::::: keypoints - `git diff` displays differences between commits. -- `git restore` recovers old versions of files. +- `git checkout` recovers old versions of files. :::::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/06-ignore.md b/06-ignore.md index 0bdd8f5d07..2c75214162 100644 --- a/06-ignore.md +++ b/06-ignore.md @@ -23,8 +23,8 @@ or intermediate files created during data analysis? Let's create a few dummy files: ```bash -$ mkdir results -$ touch a.csv b.csv c.csv results/a.out results/b.out +$ mkdir receipts +$ touch a.png b.png c.png receipts/a.jpg receipts/b.jpg ``` and see what Git says: @@ -38,10 +38,10 @@ On branch main Untracked files: (use "git add ..." to include in what will be committed) - a.csv - b.csv - c.csv - results/ + a.png + b.png + c.png + receipts/ nothing added to commit but untracked files present (use "git add" to track) ``` @@ -59,12 +59,12 @@ $ cat .gitignore ``` ```output -*.csv -results/ +*.png +receipts/ ``` -These patterns tell Git to ignore any file whose name ends in `.csv` -and everything in the `results` directory. +These patterns tell Git to ignore any file whose name ends in `.png` +and everything in the `receipts` directory. (If any of these files were already being tracked, Git would continue to track them.) @@ -93,7 +93,7 @@ Let's add and commit `.gitignore`: ```bash $ git add .gitignore -$ git commit -m "Ignore data files and the results folder" +$ git commit -m "Ignore png files and the receipts folder." $ git status ``` @@ -105,12 +105,12 @@ nothing to commit, working tree clean As a bonus, using `.gitignore` helps us avoid accidentally adding files to the repository that we don't want to track: ```bash -$ git add a.csv +$ git add a.png ``` ```output The following paths are ignored by one of your .gitignore files: -a.csv +a.png Use -f if you really want to add them. ``` @@ -128,10 +128,10 @@ On branch main Ignored files: (use "git add -f ..." to include in what will be committed) - a.csv - b.csv - c.csv - results/ + a.png + b.png + c.png + receipts/ nothing to commit, working tree clean ``` @@ -143,27 +143,27 @@ nothing to commit, working tree clean Given a directory structure that looks like: ```bash -results/data -results/plots +receipts/data +receipts/plots ``` -How would you ignore only `results/plots` and not `results/data`? +How would you ignore only `receipts/plots` and not `receipts/data`? ::::::::::::::: solution ## Solution If you only want to ignore the contents of -`results/plots`, you can change your `.gitignore` to ignore +`receipts/plots`, you can change your `.gitignore` to ignore only the `/plots/` subfolder by adding the following line to your .gitignore: ```output -results/plots/ +receipts/plots/ ``` -This line will ensure only the contents of `results/plots` is ignored, and -not the contents of `results/data`. +This line will ensure only the contents of `receipts/plots` is ignored, and +not the contents of `receipts/data`. As with most programming issues, there are a few alternative ways that one may ensure this ignore rule is followed. @@ -182,8 +182,8 @@ Further, the discussion page has more detail on ignore rules. ## Including Specific Files -How would you ignore all `.csv` files in your root directory except for -`final.csv`? +How would you ignore all `.png` files in your root directory except for +`final.png`? Hint: Find out what `!` (the exclamation point operator) does ::::::::::::::: solution @@ -193,15 +193,15 @@ Hint: Find out what `!` (the exclamation point operator) does You would add the following two lines to your .gitignore: ```output -*.csv # ignore all data files -!final.csv # except final.csv +*.png # ignore all png files +!final.png # except final.png ``` The exclamation point operator will include a previously excluded entry. -Note also that because you've previously committed `.csv` files in this +Note also that because you've previously committed `.png` files in this lesson they will not be ignored with this new rule. Only future additions -of `.csv` files added to the root directory will be ignored. +of `.png` files added to the root directory will be ignored. @@ -217,13 +217,13 @@ Given a directory structure that looks similar to the earlier Nested Files exercise, but with a slightly different directory structure: ```bash -results/data -results/images -results/plots -results/analysis +receipts/data +receipts/images +receipts/plots +receipts/analysis ``` -How would you ignore all of the contents in the results folder, but not `results/data`? +How would you ignore all of the contents in the receipts folder, but not `receipts/data`? Hint: think a bit about how you created an exception with the `!` operator before. @@ -233,13 +233,13 @@ before. ## Solution If you want to ignore the contents of -`results/` but not those of `results/data/`, you can change your `.gitignore` to ignore -the contents of results folder, but create an exception for the contents of the -`results/data` subfolder. Your .gitignore would look like this: +`receipts/` but not those of `receipts/data/`, you can change your `.gitignore` to ignore +the contents of receipts folder, but create an exception for the contents of the +`receipts/data` subfolder. Your .gitignore would look like this: ```output -results/* # ignore everything in results folder -!results/data/ # do not ignore results/data/ contents +receipts/* # ignore everything in receipts folder +!receipts/data/ # do not ignore receipts/data/ contents ``` ::::::::::::::::::::::::: @@ -253,23 +253,23 @@ results/* # ignore everything in results folder Assuming you have an empty .gitignore file, and given a directory structure that looks like: ```bash -results/data/position/gps/a.csv -results/data/position/gps/b.csv -results/data/position/gps/c.csv -results/data/position/gps/info.txt -results/plots +receipts/data/market_position/gps/a.dat +receipts/data/market_position/gps/b.dat +receipts/data/market_position/gps/c.dat +receipts/data/market_position/gps/info.txt +receipts/plots ``` -What's the shortest `.gitignore` rule you could write to ignore all `.csv` -files in `result/data/position/gps`? Do not ignore the `info.txt`. +What's the shortest `.gitignore` rule you could write to ignore all `.dat` +files in `result/data/market_position/gps`? Do not ignore the `info.txt`. ::::::::::::::: solution ## Solution -Appending `results/data/position/gps/*.csv` will match every file in `results/data/position/gps` -that ends with `.csv`. -The file `results/data/position/gps/info.txt` will not be ignored. +Appending `receipts/data/market_position/gps/*.dat` will match every file in `receipts/data/market_position/gps` +that ends with `.dat`. +The file `receipts/data/market_position/gps/info.txt` will not be ignored. diff --git a/07-github.md b/07-github.md index 29e06d91ba..c267717f80 100644 --- a/07-github.md +++ b/07-github.md @@ -34,11 +34,11 @@ world. To this end we are going to create a *remote* repository that will be lin ## 1\. Create a remote repository Log in to [GitHub](https://github.com), then click on the icon in the top right corner to -create a new repository called `planets`: +create a new repository called `recipes`: ![](fig/github-create-repo-01.png){alt='The first step in creating a repository on GitHub: clicking the "create new" button'} -Name your repository "planets" and then click "Create Repository". +Name your repository "recipes" and then click "Create Repository". Note: Since this repository will be connected to a local repository, it needs to be empty. Leave "Initialize this repository with a README" unchecked, and keep "None" as options for both "Add @@ -55,22 +55,22 @@ information on how to configure your local repository: This effectively does the following on GitHub's servers: ```bash -$ mkdir planets -$ cd planets +$ mkdir recipes +$ cd recipes $ git init ``` If you remember back to the earlier [episode](04-changes.md) where we added and -committed our earlier work on `mars.txt`, we had a diagram of the local repository +committed our earlier work on `guacamole.md`, we had a diagram of the local repository which looked like this: ![](fig/git-staging-area.svg){alt='A diagram showing how "git add" registers changes in the staging area, while "git commit" moves changes from the staging area to the repository'} Now that we have two repositories, we need a diagram like this: -![](fig/git-freshly-made-github-repo.svg){alt='A diagram illustrating how the GitHub "planets" repository is also a git repository like our local repository, but that it is currently empty'} +![](fig/git-freshly-made-github-repo.svg){alt='A diagram illustrating how the GitHub "recipes" repository is also a git repository like our local repository, but that it is currently empty'} -Note that our local repository still contains our earlier work on `mars.txt`, but the +Note that our local repository still contains our earlier work on `guacamole.md`, but the remote repository on GitHub appears empty as it doesn't contain any files yet. ## 2\. Connect local to remote repository @@ -90,22 +90,23 @@ Click on the 'SSH' link to change the [protocol](../learners/reference.md#protoc We use SSH here because, while it requires some additional configuration, it is a security protocol widely used by many applications. The steps below describe SSH at a -minimum level for GitHub. +minimum level for GitHub. A supplemental episode to this lesson discusses advanced setup +and concepts of SSH and key pairs, and other material supplemental to git related SSH. :::::::::::::::::::::::::::::::::::::::::::::::::: ![](fig/github-change-repo-string.png){alt='A screenshot showing that clicking on "SSH" will make GitHub provide the SSH URL for a repository instead of the HTTPS URL'} -Copy that URL from the browser, go into the local `planets` repository, and run +Copy that URL from the browser, go into the local `recipes` repository, and run this command: ```bash -$ git remote add origin git@github.com:vlad/planets.git +$ git remote add origin git@github.com:alflin/recipes.git ``` -Make sure to use the URL for your repository rather than Vlad's: the only -difference should be your username instead of `vlad`. +Make sure to use the URL for your repository rather than Alfredo's: the only +difference should be your username instead of `alflin`. `origin` is a local name used to refer to the remote repository. It could be called anything, but `origin` is a convention that is often used by default in git @@ -118,8 +119,8 @@ $ git remote -v ``` ```output -origin git@github.com:vlad/planets.git (fetch) -origin git@github.com:vlad/planets.git (push) +origin git@github.com:alflin/recipes.git (fetch) +origin git@github.com:alflin/recipes.git (push) ``` We'll discuss remotes in more detail in the next episode, while @@ -127,7 +128,7 @@ talking about how they might be used for collaboration. ## 3\. SSH Background and Setup -Before Dracula can connect to a remote repository, he needs to set up a way for his computer to authenticate with GitHub so it knows it's him trying to connect to his remote repository. +Before Alfredo can connect to a remote repository, he needs to set up a way for his computer to authenticate with GitHub so it knows it's him trying to connect to his remote repository. We are going to set up the method that is commonly used by many different services to authenticate access on the command line. This method is called Secure Shell Protocol (SSH). SSH is a cryptographic network protocol that allows secure communication between computers using an otherwise insecure network. @@ -167,21 +168,21 @@ ls -al ~/.ssh Your output is going to look a little different depending on whether or not SSH has ever been set up on the computer you are using. -Dracula has not set up SSH on his computer, so his output is +Alfredo has not set up SSH on his computer, so his output is ```output -ls: cannot access '/c/Users/Vlad Dracula/.ssh': No such file or directory +ls: cannot access '/c/Users/Alfredo/.ssh': No such file or directory ``` -If SSH has been set up on the computer you're using, the public and private key pairs will be listed. The file names are either `id_ed25519`/`id_ed25519.pub` or `id_rsa`/`id_rsa.pub` depending on how the key pairs were set up. -Since they don't exist on Dracula's computer, he uses this command to create them. +If SSH has been set up on the computer you're using, the public and private key pairs will be listed. The file names are either `id_ed25519`/`id_ed25519.pub` or `id_rsa`/`id_rsa.pub` depending on how the key pairs were set up. +Since they don't exist on Alfredo's computer, he uses this command to create them. ### 3\.1 Create an SSH key pair To create an SSH key pair Vlad uses this command, where the `-t` option specifies which type of algorithm to use and `-C` attaches a comment to the key (here, Vlad's email): ```bash -$ ssh-keygen -t ed25519 -C "vlad@tran.sylvan.ia" +$ ssh-keygen -t ed25519 -C "a.linguini@ratatouille.fr" ``` If you are using a legacy system that doesn't support the Ed25519 algorithm, use: @@ -189,20 +190,17 @@ If you are using a legacy system that doesn't support the Ed25519 algorithm, use ```output Generating public/private ed25519 key pair. -Enter file in which to save the key (/c/Users/Vlad Dracula/.ssh/id_ed25519): +Enter file in which to save the key (/c/Users/Alfredo/.ssh/id_ed25519): ``` We want to use the default file, so just press Enter. ```output -Created directory '/c/Users/Vlad Dracula/.ssh'. +Created directory '/c/Users/Alfredo/.ssh'. Enter passphrase (empty for no passphrase): ``` -Now, it is prompting Dracula for a passphrase. Since he is using his lab'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. +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. ```output Enter same passphrase again: @@ -211,10 +209,10 @@ Enter same passphrase again: After entering the same passphrase a second time, we receive the confirmation ```output -Your identification has been saved in /c/Users/Vlad Dracula/.ssh/id_ed25519 -Your public key has been saved in /c/Users/Vlad Dracula/.ssh/id_ed25519.pub +Your identification has been saved in /c/Users/Alfredo/.ssh/id_ed25519 +Your public key has been saved in /c/Users/Alfredo/.ssh/id_ed25519.pub The key fingerprint is: -SHA256:SMSPIStNyA00KPxuYu94KpZgRAYjgt9g4BA4kFy3g1o vlad@tran.sylvan.ia +SHA256:SMSPIStNyA00KPxuYu94KpZgRAYjgt9g4BA4kFy3g1o a.linguini@ratatouille.fr The key's randomart image is: +--[ED25519 256]--+ |^B== o. | @@ -239,10 +237,10 @@ ls -al ~/.ssh ``` ```output -drwxr-xr-x 1 Vlad Dracula 197121 0 Jul 16 14:48 ./ -drwxr-xr-x 1 Vlad Dracula 197121 0 Jul 16 14:48 ../ --rw-r--r-- 1 Vlad Dracula 197121 419 Jul 16 14:48 id_ed25519 --rw-r--r-- 1 Vlad Dracula 197121 106 Jul 16 14:48 id_ed25519.pub +drwxr-xr-x 1 Alfredo 197121 0 Jul 16 14:48 ./ +drwxr-xr-x 1 Alfredo 197121 0 Jul 16 14:48 ../ +-rw-r--r-- 1 Alfredo 197121 419 Jul 16 14:48 id_ed25519 +-rw-r--r-- 1 Alfredo 197121 106 Jul 16 14:48 id_ed25519.pub ``` ### 3\.2 Copy the public key to GitHub @@ -272,12 +270,12 @@ cat ~/.ssh/id_ed25519.pub ``` ```output -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDmRA3d51X0uu9wXek559gfn6UFNF69yZjChyBIU2qKI vlad@tran.sylvan.ia +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 "Access" menu. Click the "New SSH key" button on the right side. Now, -you can add the title (Dracula uses the title "Vlad's Lab Laptop" so he can remember where the original key pair +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, +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. Now that we've set that up, let's check our authentication again from the command line. @@ -287,7 +285,7 @@ $ ssh -T git@github.com ``` ```output -Hi Vlad! You've successfully authenticated, but GitHub does not provide shell access. +Hi Alfredo! You've successfully authenticated, but GitHub does not provide shell access. ``` Good! This output confirms that the SSH key works as intended. We are now ready to push our work to the remote repository. @@ -301,7 +299,7 @@ our local repository to the repository on GitHub: $ git push origin main ``` -Since Dracula set up a passphrase, it will prompt him for it. If you completed advanced settings for your authentication, it +Since Alfredo set up a passphrase, it will prompt him for it. If you completed advanced settings for your authentication, it will not prompt for a passphrase. ```output @@ -312,7 +310,7 @@ Compressing objects: 100% (11/11), done. Writing objects: 100% (16/16), 1.45 KiB | 372.00 KiB/s, done. Total 16 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), done. -To https://github.com/vlad/planets.git +To https://github.com/alflin/recipes.git * [new branch] main -> main ``` @@ -389,7 +387,7 @@ $ git pull origin main ``` ```output -From https://github.com/vlad/planets +From https://github.com/alflin/recipes * branch main -> FETCH_HEAD Already up-to-date. ``` @@ -402,8 +400,8 @@ GitHub, though, this command would download them to our local repository. ## GitHub GUI -Browse to your `planets` repository on GitHub. -Underneath the Code button, find and click on the text that says "XX commits" (where "XX" is some number). +Browse to your `recipes` repository on GitHub. +Under the Code tab, find and click on the text that says "XX commits" (where "XX" is some number). Hover over, and click on, the three buttons to the right of each commit. What information can you gather/explore from these buttons? How would you get that same information in the shell? @@ -519,7 +517,7 @@ remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. -From https://github.com/vlad/planets +From https://github.com/alflin/recipes * branch main -> FETCH_HEAD * [new branch] main -> origin/main fatal: refusing to merge unrelated histories @@ -534,7 +532,7 @@ $ git pull --allow-unrelated-histories origin main ``` ```output -From https://github.com/vlad/planets +From https://github.com/alflin/recipes * branch main -> FETCH_HEAD Merge made by the 'recursive' strategy. README.md | 1 + diff --git a/08-collab.md b/08-collab.md index efaeb0eec2..18a0b942f5 100644 --- a/08-collab.md +++ b/08-collab.md @@ -48,21 +48,21 @@ or check for email notification. Once there she can accept access to the Owner's Next, the Collaborator needs to download a copy of the Owner's repository to her machine. This is called "cloning a repo". -The Collaborator doesn't want to overwrite her own version of `planets.git`, so +The Collaborator doesn't want to overwrite her own version of `recipes.git`, so needs to clone the Owner's repository to a different location than her own repository with the same name. To clone the Owner's repo into her `Desktop` folder, the Collaborator enters: ```bash -$ git clone git@github.com:vlad/planets.git ~/Desktop/vlad-planets +$ git clone git@github.com:alflin/recipes.git ~/Desktop/alflin-recipes ``` -Replace 'vlad' with the Owner's username. +Replace 'alflin' with the Owner's username. If you choose to clone without the clone path -(`~/Desktop/vlad-planets`) specified at the end, -you will clone inside your own planets folder! +(`~/Desktop/alflin-recipes`) specified at the end, +you will clone inside your own recipes folder! Make sure to navigate to the `Desktop` folder first. ![](fig/github-collaboration.svg){alt='A diagram showing that "git clone" can create a copy of a remote GitHub repository, allowing a second person to create their own local repository that they can make changes to.'} @@ -71,23 +71,28 @@ The Collaborator can now make a change in her clone of the Owner's repository, exactly the same way as we've been doing before: ```bash -$ cd ~/Desktop/vlad-planets -$ nano pluto.txt -$ cat pluto.txt +$ cd ~/Desktop/alflin-recipes +$ nano hummus.md +$ cat hummus.md ``` ```output -It is so a planet! +# Hummus +## Ingredients +* chickpeas +* lemon +* olive oil +* salt ``` ```bash -$ git add pluto.txt -$ git commit -m "Add notes about Pluto" +$ git add hummus.md +$ git commit -m "Add ingredients for hummus" ``` ```output - 1 file changed, 1 insertion(+) - create mode 100644 pluto.txt + 1 file changed, 6 insertion(+) + create mode 100644 hummus.md ``` Then push the change to the *Owner's repository* on GitHub: @@ -103,7 +108,7 @@ Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 306 bytes, done. Total 3 (delta 0), reused 0 (delta 0) -To https://github.com/vlad/planets.git +To https://github.com/alflin/recipes.git 9272da5..29aba7c main -> main ``` @@ -130,7 +135,7 @@ You would pull from `upstream` from time to time to get the latest updates that other people have committed. Remember that the name you give to a remote only exists locally. It's -an alias that you choose - whether `origin`, or `upstream`, or `fred` - +an alias that you choose - whether `origin`, or `upstream`, or `alfred` - and not something intrinstic to the remote repository. The `git remote` family of commands is used to set up and alter the remotes @@ -146,7 +151,7 @@ associated with a repository. Here are some of the most useful ones: account, or from GitHub to a different hosting service. Or, if we made a typo when adding it! - `git remote rename [oldname] [newname]` changes the local alias by which a remote - is known - its name. For example, one could use this to change `upstream` to `fred`. + is known - its name. For example, one could use this to change `upstream` to `alfred`. :::::::::::::::::::::::::::::::::::::::::::::::::: @@ -163,14 +168,14 @@ remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. -From https://github.com/vlad/planets +From https://github.com/alflin/recipes * branch main -> FETCH_HEAD 9272da5..29aba7c main -> origin/main Updating 9272da5..29aba7c Fast-forward - pluto.txt | 1 + - 1 file changed, 1 insertion(+) - create mode 100644 pluto.txt + hummus.md | 5 + + 1 file changed, 5 insertion(+) + create mode 100644 hummus.md ``` Now the three repositories (Owner's local, Collaborator's local, and Owner's on diff --git a/09-conflict.md b/09-conflict.md index ecaad1ac62..374c5d837b 100644 --- a/09-conflict.md +++ b/09-conflict.md @@ -25,42 +25,48 @@ different changes to each copy. Version control helps us manage these [resolve](../learners/reference.md#resolve) overlapping changes. To see how we can resolve conflicts, we must first create one. The file -`mars.txt` currently looks like this in both partners' copies of our `planets` +`guacamole.md` currently looks like this in both partners' copies of our `recipes` repository: ```bash -$ cat mars.txt +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity +# Guacamole +## Ingredients +* avocado +* lime +* salt +## Instructions ``` Let's add a line to the collaborator's copy only: ```bash -$ nano mars.txt -$ cat mars.txt +$ nano guacamole.md +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity -This line added to Wolfman's copy +# Guacamole +## Ingredients +* avocado +* lime +* salt +## Instructions +* put one avocado into a bowl. ``` and then push the change to GitHub: ```bash -$ git add mars.txt -$ git commit -m "Add a line in our home copy" +$ git add guacamole.md +$ git commit -m "First step on the instructions" ``` ```output -[main 5ae9631] Add a line in our home copy +[main 5ae9631] First step on the instructions 1 file changed, 1 insertion(+) ``` @@ -76,7 +82,7 @@ Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 331 bytes | 331.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 2 local objects. -To https://github.com/vlad/planets.git +To https://github.com/alflin/recipes.git 29aba7c..dabb4c8 main -> main ``` @@ -85,26 +91,29 @@ make a different change to their copy *without* updating from GitHub: ```bash -$ nano mars.txt -$ cat mars.txt +$ nano guacamole.md +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity -We added a different line in the other copy +# Guacamole +## Ingredients +* avocado +* lime +* salt +## Instructions +* peel the avocados ``` We can commit the change locally: ```bash -$ git add mars.txt -$ git commit -m "Add a line in my copy" +$ git add guacamole.md +$ git commit -m "Add first step" ``` ```output -[main 07ebc69] Add a line in my copy +[main 07ebc69] Add first step 1 file changed, 1 insertion(+) ``` @@ -115,9 +124,9 @@ $ git push origin main ``` ```output -To https://github.com/vlad/planets.git +To https://github.com/alflin/recipes.git ! [rejected] main -> main (fetch first) -error: failed to push some refs to 'https://github.com/vlad/planets.git' +error: failed to push some refs to 'https://github.com/alflin/recipes.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes @@ -143,14 +152,52 @@ remote: Counting objects: 100% (5/5), done. remote: Compressing objects: 100% (1/1), done. remote: Total 3 (delta 2), reused 3 (delta 2), pack-reused 0 Unpacking objects: 100% (3/3), done. -From https://github.com/vlad/planets +From https://github.com/alflin/recipes * branch main -> FETCH_HEAD 29aba7c..dabb4c8 main -> origin/main -Auto-merging mars.txt -CONFLICT (content): Merge conflict in mars.txt +Auto-merging guacamole.md +CONFLICT (content): Merge conflict in guacamole.md Automatic merge failed; fix conflicts and then commit the result. ``` +::::::::::::::::::::::::::::::::::::::::: callout + +## You may need to tell git what to do + +If you see the below in your output, git is asking what it should do. + +```output +hint: You have divergent branches and need to specify how to reconcile them. +hint: You can do so by running one of the following commands sometime before +hint: your next pull: +hint: +hint: git config pull.rebase false # merge (the default strategy) +hint: git config pull.rebase true # rebase +hint: git config pull.ff only # fast-forward only +hint: +hint: You can replace "git config" with "git config --global" to set a default +hint: preference for all repositories. You can also pass --rebase, --no-rebase, +hint: or --ff-only on the command line to override the configured default per +hint: invocation. +``` + +In newer versions of git it gives you the option of specifying different +behaviours when a pull would merge divergent branches. In our case we want +'the default strategy'. To use this strategy run the following command to +select it as the default thing git should do. + +```bash +$ git config pull.rebase false +``` + +Then attempt the pull again. + +```bash +$ git pull origin main +``` + +:::::::::::::::::::::::::::::::::::::::::::::::::: + The `git pull` command updates the local repository to include those changes already included in the remote repository. After the changes from remote branch have been fetched, Git detects that changes made to the local copy @@ -159,17 +206,20 @@ stop us from trampling on our previous work. The conflict is marked in in the affected file: ```bash -$ cat mars.txt +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity +# Guacamole +## Ingredients +* avocado +* lime +* salt +## Instructions <<<<<<< HEAD -We added a different line in the other copy +* peel the avocados ======= -This line added to Wolfman's copy +* put one avocado into a bowl. >>>>>>> dabb4c8c450e8475aee9b14b4383acc99f42af1d ``` @@ -187,22 +237,25 @@ or get rid of the change entirely. Let's replace both so that the file looks like this: ```bash -$ cat mars.txt +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity -We removed the conflict on this line +# Guacamole +## Ingredients +* avocado +* lime +* salt +## Instructions +* peel the avocados and put them into a bowl. ``` To finish merging, -we add `mars.txt` to the changes being made by the merge +we add `guacamole.md` to the changes being made by the merge and then commit: ```bash -$ git add mars.txt +$ git add guacamole.md $ git status ``` @@ -213,7 +266,7 @@ All conflicts fixed but you are still merging. Changes to be committed: - modified: mars.txt + modified: guacamole.md ``` @@ -239,7 +292,7 @@ Compressing objects: 100% (6/6), done. Writing objects: 100% (6/6), 645 bytes | 645.00 KiB/s, done. Total 6 (delta 4), reused 0 (delta 0) remote: Resolving deltas: 100% (4/4), completed with 2 local objects. -To https://github.com/vlad/planets.git +To https://github.com/alflin/recipes.git dabb4c8..2abf2b1 main -> main ``` @@ -257,26 +310,29 @@ remote: Counting objects: 100% (10/10), done. remote: Compressing objects: 100% (2/2), done. remote: Total 6 (delta 4), reused 6 (delta 4), pack-reused 0 Unpacking objects: 100% (6/6), done. -From https://github.com/vlad/planets +From https://github.com/alflin/recipes * branch main -> FETCH_HEAD dabb4c8..2abf2b1 main -> origin/main Updating dabb4c8..2abf2b1 Fast-forward - mars.txt | 2 +- + guacamole.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) ``` We get the merged file: ```bash -$ cat mars.txt +$ cat guacamole.md ``` ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman -But the Mummy will appreciate the lack of humidity -We removed the conflict on this line +# Guacamole +## Ingredients +* avocado +* lime +* salt +## Instructions +* peel the avocados and put them into a bowl. ``` We don't need to merge again because Git knows someone has already done that. @@ -328,49 +384,49 @@ that is stored in version control? ## Solution -Let's try it. Suppose Dracula takes a picture of Martian surface and -calls it `mars.jpg`. +Let's try it. Suppose Alfredo takes a picture of its guacamole and +calls it `guacamole.jpg`. -If you do not have an image file of Mars available, you can create +If you do not have an image file of guacamole available, you can create a dummy binary file like this: ```bash -$ head -c 1024 /dev/urandom > mars.jpg -$ ls -lh mars.jpg +$ head --bytes 1024 /dev/urandom > guacamole.jpg +$ ls -lh guacamole.jpg ``` ```output --rw-r--r-- 1 vlad 57095 1.0K Mar 8 20:24 mars.jpg +-rw-r--r-- 1 alflin 57095 1.0K Mar 8 20:24 guacamole.jpg ``` `ls` shows us that this created a 1-kilobyte file. It is full of random bytes read from the special file, `/dev/urandom`. -Now, suppose Dracula adds `mars.jpg` to his repository: +Now, suppose Alfredo adds `guacamole.jpg` to his repository: ```bash -$ git add mars.jpg -$ git commit -m "Add picture of Martian surface" +$ git add guacamole.jpg +$ git commit -m "Add picture of guacamole" ``` ```output -[main 8e4115c] Add picture of Martian surface +[main 8e4115c] Add picture of guacamole 1 file changed, 0 insertions(+), 0 deletions(-) - create mode 100644 mars.jpg + create mode 100644 guacamole.jpg ``` -Suppose that Wolfman has added a similar picture in the meantime. -His is a picture of the Martian sky, but it is *also* called `mars.jpg`. -When Dracula tries to push, he gets a familiar message: +Suppose that Jimmy has added a similar picture in the meantime. +His is a picture of a guacamole with nachos, but it is *also* called `guacamole.jpg`. +When Alfredo tries to push, he gets a familiar message: ```bash $ git push origin main ``` ```output -To https://github.com/vlad/planets.git +To https://github.com/alflin/recipes.git ! [rejected] main -> main (fetch first) -error: failed to push some refs to 'https://github.com/vlad/planets.git' +error: failed to push some refs to 'https://github.com/alflin/recipes.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes @@ -393,20 +449,20 @@ remote: Counting objects: 3, done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. -From https://github.com/vlad/planets.git +From https://github.com/alflin/recipes.git * branch main -> FETCH_HEAD 6a67967..439dc8c main -> origin/main -warning: Cannot merge binary files: mars.jpg (HEAD vs. 439dc8c08869c342438f6dc4a2b615b05b93c76e) -Auto-merging mars.jpg -CONFLICT (add/add): Merge conflict in mars.jpg +warning: Cannot merge binary files: guacamole.jpg (HEAD vs. 439dc8c08869c342438f6dc4a2b615b05b93c76e) +Auto-merging guacamole.jpg +CONFLICT (add/add): Merge conflict in guacamole.jpg Automatic merge failed; fix conflicts and then commit the result. ``` -The conflict message here is mostly the same as it was for `mars.txt`, but +The conflict message here is mostly the same as it was for `guacamole.md`, but there is one key additional line: ```output -warning: Cannot merge binary files: mars.jpg (HEAD vs. 439dc8c08869c342438f6dc4a2b615b05b93c76e) +warning: Cannot merge binary files: guacamole.jpg (HEAD vs. 439dc8c08869c342438f6dc4a2b615b05b93c76e) ``` Git cannot automatically insert conflict markers into an image as it does @@ -414,31 +470,31 @@ for text files. So, instead of editing the image file, we must check out the version we want to keep. Then we can add and commit this version. On the key line above, Git has conveniently given us commit identifiers -for the two versions of `mars.jpg`. Our version is `HEAD`, and Wolfman's +for the two versions of `guacamole.jpg`. Our version is `HEAD`, and Jimmy's version is `439dc8c0...`. If we want to use our version, we can use `git checkout`: ```bash -$ git checkout HEAD mars.jpg -$ git add mars.jpg -$ git commit -m "Use image of surface instead of sky" +$ git checkout HEAD guacamole.jpg +$ git add guacamole.jpg +$ git commit -m "Use image of just guacamole instead of with nachos" ``` ```output -[main 21032c3] Use image of surface instead of sky +[main 21032c3] Use image of just guacamole instead of with nachos ``` -If instead we want to use Wolfman's version, we can use `git checkout` with -Wolfman's commit identifier, `439dc8c0`: +If instead we want to use Jimmy's version, we can use `git checkout` with +Jimmy's commit identifier, `439dc8c0`: ```bash -$ git checkout 439dc8c0 mars.jpg -$ git add mars.jpg -$ git commit -m "Use image of sky instead of surface" +$ git checkout 439dc8c0 guacamole.jpg +$ git add guacamole.jpg +$ git commit -m "Use image of guacamole with nachos instead of just guacamole" ``` ```output -[main da21b34] Use image of sky instead of surface +[main da21b34] Use image of guacamole with nachos instead of just guacamole ``` We can also keep *both* images. The catch is that we cannot keep them @@ -447,29 +503,29 @@ and *rename* it, then add the renamed versions. First, check out each image and rename it: ```bash -$ git checkout HEAD mars.jpg -$ git mv mars.jpg mars-surface.jpg -$ git checkout 439dc8c0 mars.jpg -$ mv mars.jpg mars-sky.jpg +$ git checkout HEAD guacamole.jpg +$ git mv guacamole.jpg guacamole-only.jpg +$ git checkout 439dc8c0 guacamole.jpg +$ mv guacamole.jpg guacamole-nachos.jpg ``` -Then, remove the old `mars.jpg` and add the two new files: +Then, remove the old `guacamole.jpg` and add the two new files: ```bash -$ git rm mars.jpg -$ git add mars-surface.jpg -$ git add mars-sky.jpg -$ git commit -m "Use two images: surface and sky" +$ git rm guacamole.jpg +$ git add guacamole-only.jpg +$ git add guacamole-nachos.jpg +$ git commit -m "Use two images: just guacamole and with nachos" ``` ```output -[main 94ae08c] Use two images: surface and sky +[main 94ae08c] Use two images: just guacamole and with nachos 2 files changed, 0 insertions(+), 0 deletions(-) - create mode 100644 mars-sky.jpg - rename mars.jpg => mars-surface.jpg (100%) + create mode 100644 guacamole-nachos.jpg + rename guacamole.jpg => guacamole-only.jpg (100%) ``` -Now both images of Mars are checked into the repository, and `mars.jpg` +Now both images of guacamole are checked into the repository, and `guacamole.jpg` no longer exists. diff --git a/12-citation.md b/12-citation.md index ed2b75bee5..fa3bd229a1 100644 --- a/12-citation.md +++ b/12-citation.md @@ -23,18 +23,30 @@ Carpentry](https://github.com/swcarpentry/website/blob/gh-pages/CITATION) states: ```source -To reference Software Carpentry in publications, please cite: +To reference Software Carpentry in publications, please cite both of the following: -Greg Wilson: "Software Carpentry: Lessons Learned". F1000Research, -2016, 3:62 (doi: 10.12688/f1000research.3-62.v2). +Greg Wilson: "Software Carpentry: Getting Scientists to Write Better +Code by Making Them More Productive". Computing in Science & +Engineering, Nov-Dec 2006. -@online{wilson-software-carpentry-2016, +Greg Wilson: "Software Carpentry: Lessons Learned". arXiv:1307.5448, +July 2013. + +@article{wilson-software-carpentry-2006, + author = {Greg Wilson}, + title = {Software Carpentry: Getting Scientists to Write Better Code by Making Them More Productive}, + journal = {Computing in Science \& Engineering}, + month = {November--December}, + year = {2006}, +} + +@online{wilson-software-carpentry-2013, author = {Greg Wilson}, title = {Software Carpentry: Lessons Learned}, - version = {2}, - date = {2016-01-28}, - url = {http://f1000research.com/articles/3-62/v2}, - doi = {10.12688/f1000research.3-62.v2} + version = {1}, + date = {2013-07-20}, + eprinttype = {arxiv}, + eprint = {1307.5448} } ``` diff --git a/13-hosting.md b/13-hosting.md index 80c2a7ba2a..f17d34f554 100644 --- a/13-hosting.md +++ b/13-hosting.md @@ -16,8 +16,7 @@ exercises: 0 :::::::::::::::::::::::::::::::::::::::::::::::::: -After [choosing a license](11-licensing.md), -another big question for groups that want to open up their work is where to +The second big question for groups that want to open up their work is where to host their code and data. One option is for the lab, the department, or the university to provide a server, manage accounts and backups, and so on. The main benefit of this is that it clarifies who owns what, which is particularly diff --git a/14-supplemental-rstudio.md b/14-supplemental-rstudio.md index 24ced1988c..0b31e26c93 100644 --- a/14-supplemental-rstudio.md +++ b/14-supplemental-rstudio.md @@ -31,7 +31,7 @@ project with Git. To get started using Git in RStudio, we create a new project: ![](fig/RStudio_screenshot_newproject.png){alt='RStudio screenshot showing the file menu dropdown with "New Project..." selected'} This opens a dialog asking us how we want to create the project. We have -some options here. Let's say that we want to use RStudio with the planets +some options here. Let's say that we want to use RStudio with the recipes repository that we already made. Since that repository lives in a directory on our computer, we choose the option "Existing Directory": @@ -82,9 +82,9 @@ to accept the Xcode license if you are using macOS. Next, RStudio will ask which existing directory we want to use. Click "Browse..." and navigate to the correct directory, then click "Create Project": -![](fig/RStudio_screenshot_navigateexisting.png){alt='RStudio window showing the "Create Project From Existing Directory" dialog. In the dialog, the project working directory has been set to "~/Desktop/planets"'} +![](fig/RStudio_screenshot_navigateexisting.png){alt='RStudio window showing the "Create Project From Existing Directory" dialog. In the dialog, the project working directory has been set to "~/Desktop/recipes"'} -Ta-da! We have created a new project in RStudio within the existing planets +Ta-da! We have created a new project in RStudio within the existing recipes repository. Notice the vertical "Git" menu in the menu bar. RStudio has recognized that the current directory is a Git repository, and gives us a number of tools to use Git: @@ -93,7 +93,7 @@ number of tools to use Git: To edit the existing files in the repository, we can click on them in the "Files" panel on the lower right. Now let's add some additional information -about Pluto: +about Hummus: ![](fig/RStudio_screenshot_editfiles.png){alt='RStudio window demonstrating the use of the editor panel to modify the "pluto.txt" file'} diff --git a/discuss.md b/discuss.md index def35b113a..c1da4a0baf 100644 --- a/discuss.md +++ b/discuss.md @@ -22,8 +22,8 @@ $ cat ~/.gitconfig ```output [user] - name = Vlad Dracula - email = vlad@tran.sylvan.ia + name = Alfredo Linguini + email = a.linguini@ratatouille.fr [color] ui = true [core] @@ -54,13 +54,13 @@ $ git config --global alias.co checkout Now if we return to the example from [Exploring History](../episodes/05-history.md) where we ran: ```bash -$ git checkout f22b25e mars.txt +$ git checkout f22b25e guacamole.md ``` we could now instead type: ```bash -$ git co f22b25e mars.txt +$ git co f22b25e guacamole.md ``` ## Styling Git's Log @@ -131,37 +131,41 @@ This has various impacts on Git's performance and will make it difficult to compare different versions of your project. For a basic example to show the difference it makes, -we're going to go see what would have happened if Dracula had tried +we're going to go see what would have happened if Alfredo had tried using outputs from a word processor instead of plain text. Create a new directory and go into it: ```bash -$ mkdir planets-nontext -$ cd planets-nontext +$ mkdir recipes-nontext +$ cd recipes-nontext ``` Use a program such as Microsoft Word or LibreOffice Writer to create a new document. Enter the same text that we began with before: ```output -Cold and dry, but everything is my favorite color +# Ingredients +# Instructions ``` -Save the document into the `planets-nontext` directory with the name of `mars.doc`. +Save the document into the `recipes-nontext` directory with the name of `guacamole.doc`. Back in the terminal, run the usual commands for setting up a new Git repository: ```bash $ git init -$ git add mars.doc -$ git commit -m "Starting to think about Mars" +$ git add guacamole.doc +$ git commit -m "Create a template for recipe" ``` -Then make the same changes to `mars.doc` that we (or Vlad) previously made to `mars.txt`. +Then make the same changes to `guacamole.doc` that we (or Alfredo) previously made to `guacamole.md`. ```output -Cold and dry, but everything is my favorite color -The two moons may be a problem for Wolfman +# Ingredients +- avocado +- lemon +- salt +# Instructions ``` Save and close the word processor. @@ -172,21 +176,24 @@ $ git diff ``` ```output -diff --git a/mars.doc b/mars.doc +diff --git a/guacamole.doc b/guacamole.doc index 53a66fd..6e988e9 100644 -Binary files a/mars.doc and b/mars.doc differ +Binary files a/guacamole.doc and b/guacamole.doc differ ``` Compare this to the earlier `git diff` obtained when using text files: ```output -diff --git a/mars.txt b/mars.txt +diff --git a/guacamole.md b/guacamole.md index df0654a..315bf3a 100644 ---- a/mars.txt -+++ b/mars.txt -@@ -1 +1,2 @@ - Cold and dry, but everything is my favorite color -+The two moons may be a problem for Wolfman +--- a/guacamole.md ++++ b/guacamole.md +@@ -1,2 +1,5 @@ + # Ingredients ++- avocado ++- lemon ++- salt + # Instructions ``` Notice how plain text files give a much more informative diff. @@ -212,30 +219,30 @@ Adding and modifying files are not the only actions one might take when working on a project. It might be required to remove a file from the repository. -Create a new file for the planet Nibiru: +Create a new file for the invisible ink: ```bash -$ echo "This is another name for fake planet X" > nibiru.txt +$ echo "This is where we keep the secret sauce" > invisible.md ``` Now add to the repository like you have learned earlier: ```bash -$ git add nibiru.txt -$ git commit -m 'adding info on nibiru' +$ git add invisible.md +$ git commit -m 'adding secret sauce' $ git status ``` ```output On branch main -nothing to commit, working tree clean +nothing to commit, working directory clean ``` -Nibiru is not a real planet. That was a silly idea. Let us remove +Invisible ink is not a real food. That was a silly idea. Let us remove it from the disk and let Git know about it: ```bash -$ git rm nibiru.txt +$ git rm invisible.md $ git status ``` @@ -244,7 +251,7 @@ On branch main Changes to be committed: (use "git reset HEAD ..." to unstage) - deleted: nibiru.txt + deleted: invisible.md ``` @@ -254,7 +261,7 @@ in the new commit. The previous commit will still have the file, if you were to retrieve that specific commit. ```bash -$ git commit -m 'Removing info on Nibiru. It is not a real planet!' +$ git commit -m 'Removing info on Invisible ink. It is not an edible sauce!' ``` ## Removing a File with Unix @@ -265,15 +272,15 @@ Git is smart enough to notice the missing file. Let us recreate the file and commit it again. ```bash -$ echo "This is another name for fake planet X" > nibiru.txt -$ git add nibiru.txt -$ git commit -m 'adding nibiru again' +$ echo "This is anoher way to make invisible ink" > secret.md +$ git add secret.md +$ git commit -m 'adding invisible ink again' ``` Now we remove the file with Unix `rm`: ```bash -$ rm nibiru.txt +$ rm secret.md $ git status ``` @@ -283,18 +290,18 @@ Changes not staged for commit: (use "git add/rm ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) - deleted: nibiru.txt + deleted: secret.md no changes added to commit (use "git add" and/or "git commit -a") ``` -See how Git has noticed that the file `nibiru.txt` has been removed +See how Git has noticed that the file `secret.md` has been removed from the disk. The next step is to "stage" the removal of the file from the repository. This is done with the command `git rm` just as before. ```bash -$ git rm nibiru.txt +$ git rm secret.md $ git status ``` @@ -303,7 +310,7 @@ On branch main Changes to be committed: (use "git reset HEAD ..." to unstage) - deleted: nibiru.txt + deleted: secret.md ``` @@ -311,33 +318,32 @@ The change that was made in Unix has now been staged and needs to be committed. ```bash -$ git commit -m 'Removing info on Nibiru, again!' +$ git commit -m 'Removing info on invisible ink, again!' ``` ## Renaming a File Another common change when working on a project is to rename a file. -Create a file for the planet Krypton: +Create a file for the whitesauce recipe: ```bash -$ echo "Superman's home planet" > krypton.txt +$ echo "Very fun recipe to do" > whitesauce.md ``` Add it to the repository: ```bash -$ git add krypton.txt -$ git commit -m 'Adding planet Krypton' +$ git add whitesauce.md +$ git commit -m 'Adding white sauce recipe' ``` -We all know that Superman moved to Earth. Not that he had much -choice. Now his home planet is Earth. +We all know that white sauce has a more sophisticated name. -Rename the file `krypton.txt` to `earth.txt` with Git: +Rename the file `whitesauce.md` to `bechamel.md` with Git: ```bash -$ git mv krypton.txt earth.txt +$ git mv whitesauce.md bechamel.md $ git status ``` @@ -346,13 +352,13 @@ On branch main Changes to be committed: (use "git reset HEAD ..." to unstage) - renamed: krypton.txt -> earth.txt + renamed: whitesauce.md -> bechamel.md ``` The final step is commit our change to the repository: ```bash -$ git commit -m 'Superman's home is now Earth' +$ git commit -m 'Using the French name for the whitesauce' ``` ## Renaming a File with Unix @@ -364,15 +370,15 @@ this time with Unix `mv`. First, we need to recreate the `krypton.txt` file: ```bash -$ echo "Superman's home planet" > krypton.txt -$ git add krypton.txt -$ git commit -m 'Adding planet Krypton again.' +$ echo "Very fun recipe to do" > whitesauce.md +$ git add whitesauce.md +$ git commit -m 'Adding white sauce recipe' ``` Let us rename the file and see what Git can figured out by itself: ```bash -$ mv krypton.txt earth.txt +$ mv whitesauce.md bechamel.md $ git status ``` @@ -382,23 +388,23 @@ Changes not staged for commit: (use "git add/rm ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) - deleted: krypton.txt + deleted: whitesauce.md Untracked files: (use "git add ..." to include in what will be committed) - earth.txt + bechamel.md no changes added to commit (use "git add" and/or "git commit -a") ``` -Git has noticed that the file `krypton.txt` has disappeared from the -file system and a new file `earth.txt` has showed up. +Git has noticed that the file `whitesauce.md` has disappeared from the +file system and a new file `bechamel.md` has showed up. Add those changes to the staging area: ```bash -$ git add krypton.txt earth.txt +$ git add whitesauce.md bechamel.md $ git status ``` @@ -407,17 +413,17 @@ On branch main Changes to be committed: (use "git reset HEAD ..." to unstage) - renamed: krypton.txt -> earth.txt + renamed: whitesauce.md -> bechamel.md ``` -Notice how Git has now figured out that the `krypton.txt` has not +Notice how Git has now figured out that the `whitesauce.md` has not disappeared - it has simply been renamed. The final step, as before, is to commit our change to the repository: ```bash -$ git commit -m 'Superman's home is Earth, told you before.' +$ git commit -m 'Using the French name for the whitesauce' ``` ## Further .gitignore concepts diff --git a/fig/git-freshly-made-github-repo.svg b/fig/git-freshly-made-github-repo.svg index 2d70ffd175..aa497cf0d0 100644 --- a/fig/git-freshly-made-github-repo.svg +++ b/fig/git-freshly-made-github-repo.svg @@ -81,7 +81,7 @@ x="16" font-size="13.5" id="text3502" - style="font-size:13.5px;font-family:Helvetica">https://github.com/vlad/planets.git + style="font-size:13.5px;font-family:Helvetica">https://github.com/alflin/recipes.git ~/vlad/planets + y="28.707001">~/alflin/recipes git restore file1.txt + id="tspan300">git checkout HEAD file1.txt origin https://github.com/vlad/planets.git + style="font-size:10.80000019px;font-family:Consolas">origin https://github.com/alflin/recipes.git ~/vlad/planets + style="font-size:13.5px;font-family:Helvetica">~/alflin/recipes https://github.com/vlad/planets.git + y="278.707">https://github.com/alflin/recipes.git origin https://github.com/vlad/planets.git + x="0">origin https://github.com/alflin/recipes.git ~/wolfman/planets + transform="translate(16,28.707)">~/jimmy/recipes origin https://github.com/vlad/planets.git + style="font-size:10.80000019px;font-family:Consolas">origin https://github.com/alflin/recipes.git ~/vlad/planets + style="font-size:13.5px;font-family:Helvetica">~/alflin/recipes https://github.com/vlad/planets.git + style="font-size:13.5px;font-family:Helvetica">https://github.com/alflin/recipes.git