From ab4537df45be51bac21da588589cc2eb612f0a80 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:50:44 +0200 Subject: [PATCH 01/24] Updates editor config --- .editorconfig | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.editorconfig b/.editorconfig index e147748..c6e9ab1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,18 +1,19 @@ -# Top-most EditorConfig file root = true -# Unix-style newlines with a newline ending every file [*] +indent_style = space +indent_size = 2 end_of_line = lf -insert_final_newline = true charset = utf-8 -indent_size = 2 -indent_style = space +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 120 -# HTML [*.{html}] trim_trailing_whitespace = false -# YAML, CSS, JavaScript, JSON -[*.{yaml, yml, css, js, json}] -trim_trailing_whitespace = true +[*.json] +indent_size = 4 + +[*.jsonc] +indent_size = 4 From 9190536176eb838e50849d81d383e5572675d379 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:50:51 +0200 Subject: [PATCH 02/24] Updates CSpell --- .cspell/names.txt | 3 +++ cspell.json | 60 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 .cspell/names.txt diff --git a/.cspell/names.txt b/.cspell/names.txt new file mode 100644 index 0000000..63757c5 --- /dev/null +++ b/.cspell/names.txt @@ -0,0 +1,3 @@ +Czarnievicz +Hamedani +Shafer diff --git a/cspell.json b/cspell.json index bdce65a..aa012c1 100644 --- a/cspell.json +++ b/cspell.json @@ -1,14 +1,60 @@ { "version": "0.2", - "ignorePaths": [], - "dictionaryDefinitions": [], - "dictionaries": [], + "language": "en", + "ignorePaths": [ + ".gitattributes", + ".gitignore", + "**/.git/**", + ], + "dictionaryDefinitions": [ + { + "name": "names", + "path": "./.cspell/names.txt", + "addWords": true, + }, + ], + "dictionaries": [ + "names", + ], "words": [], "ignoreWords": [ - "Czarnievicz", "Dockerfiles", - "Hamedani", - "Shafer" ], - "import": [] + "overrides": [ + { + "filename": "**/*.py", + "languageId": "python", + }, + { + "filename": "**/*.yaml", + "languageId": "yaml", + }, + { + "filename": "**/*.yml", + "languageId": "yaml", + }, + { + "filename": "**/*.md", + "languageId": "markdown", + }, + { + "filename": "**/*.txt", + "languageId": "plaintext", + }, + { + "filename": "**/*.zsh", + "languageId": "shellscript", + }, + { + "filename": "**/*.toml", + "languageId": "toml", + }, + ], + "ignoreRegExpList": [ + // Ignores UUIDs + "\\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\\b", + // Ignores hashes in venv names + "\\b[A-Z0-9]{6,}\\b", + ], + "useGitignore": false, } From c28030cb7d3e8abd918c158e6987fbf8c28b03a2 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:52:48 +0200 Subject: [PATCH 03/24] Updates .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 597593f..0467917 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -# Mac files .DS_Store +.git/ From 7fafed73d91f9792c616a087f0be43259dec41da Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:54:37 +0200 Subject: [PATCH 04/24] Update index content --- index.html | 68 ++++++++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 45 deletions(-) diff --git a/index.html b/index.html index 6c39917..caa7e93 100644 --- a/index.html +++ b/index.html @@ -25,72 +25,54 @@

Notes on Git and GitHub

- On this page you can find some personal notes on the use of Git - and GitHub. Though the notes themselves were created by me, the - content in them is the result of courses that I've taken on the - subject, books I've read, and countless YouTube videos, blog posts - and StackOverflow questions. These notes should not be considered - as a replacement for engaging with those resources. + On this page you can find some personal notes on the use of Git and GitHub. Though the notes themselves + were created by me, the content in them is the result of courses that I've taken on the subject, books + I've read, and countless YouTube videos, blog posts and StackOverflow questions. These notes should not + be considered as a replacement for engaging with those resources.


- Some resources that I especially recommend and whose influence can - be found all across these notes are: + Some resources that I especially recommend and whose influence can be found all across these notes are:

@@ -451,8 +433,7 @@

Jump to...

- Read up! Enjoy! And when things don't work...worry not, for you - are not alone... + Read up! Enjoy! And when things don't work...worry not, for you are not alone...

@@ -463,9 +444,6 @@

Jump to...

- + From 9277dbfed2c6723061ddb73a4cc796c7449c91b7 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:57:55 +0200 Subject: [PATCH 05/24] Update index content --- index.html | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/index.html b/index.html index caa7e93..f17ef68 100644 --- a/index.html +++ b/index.html @@ -430,18 +430,6 @@

Jump to...

-
-
-

- Read up! Enjoy! And when things don't work...worry not, for you are not alone... -

-
-
-
-
- -
-
From 4cfed3d57583c1347ef292886bb95d1509ccb81e Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 22:06:05 +0200 Subject: [PATCH 06/24] Update pages 001 to 004 --- pages/001/what_is_git.html | 26 +++++------- pages/002/configuring_git.html | 38 +++++++----------- pages/003/getting_help.html | 24 +++++------- pages/004/initializing_a_repository.html | 50 +++++++++--------------- 4 files changed, 50 insertions(+), 88 deletions(-) diff --git a/pages/001/what_is_git.html b/pages/001/what_is_git.html index 6fcdb45..a307907 100644 --- a/pages/001/what_is_git.html +++ b/pages/001/what_is_git.html @@ -30,22 +30,17 @@

What is Git?

- Git is a version control system. A version control system records - the changes made to the project's code over time in a special - database called a repository. We can then look at the - database and see who's made changes and when. This way, if we made - a mistake we can easily go back to a previous state. + Git is a version control system. A version control system records the changes made to the project's code + over time in a special database called a repository. We can then look at the database and see + who's made changes and when. This way, if we made a mistake we can easily go back to a previous state.


- Version control systems can be classified into two categories: - Centralized and Distributed. In a centralized - system, all team members connect to a central server to get and - share code. The problem with these systems is that if the server - goes down, we can't save snapshots. In distributed systems, every - member of the team has a copy of the entire project on their - machine, and then share their code to a central copy of the - project. Git is a distributed control system. + Version control systems can be classified into two categories: Centralized and + Distributed. In a centralized system, all team members connect to a central server to get and + share code. The problem with these systems is that if the server goes down, we can't save snapshots. In + distributed systems, every member of the team has a copy of the entire project on their machine, and then + share their code to a central copy of the project. Git is a distributed control system.

@@ -54,9 +49,6 @@

What is Git?

- + diff --git a/pages/002/configuring_git.html b/pages/002/configuring_git.html index 6fb6b0e..40d6759 100644 --- a/pages/002/configuring_git.html +++ b/pages/002/configuring_git.html @@ -43,16 +43,13 @@

Configuring Git

Settings can be specified at three different levels

@@ -60,8 +57,7 @@

Configuring Git

- To configure the settings, open the Git Bash (Bash = "Bourne Again - Shell") or Terminal. You can specify the name with: + To configure the settings, open the terminal. You can specify the name with:

git config --global user.name "User Name" @@ -75,16 +71,15 @@

Configuring Git

git config --global core.editor "code --wait"

- All these configuration settings are stored in a text file that we - can access and edit with our default editor. You can open it with: + All these configuration settings are stored in a text file that we can access and edit with our default + editor. You can open it with:

git config --global -e

- This will open the .gitconfig file where you can edit - configurations. When you go back to Git Bash you'll see a message - that says + This will open the .gitconfig file where you can edit configurations. When you go back to the + terminal you'll see a message that says

hint: Waiting for your editor to close the file... @@ -95,13 +90,11 @@

Configuring Git

- Now we need to configure how Git will handle the end-of-line. On - Windows, the end-of-line are marked with two special characters: - \r for Carriage Return, - and \n for Line Feed. On - macOS and Linux, the end-of-line is indicated with - \n. We have to configure a - property called core.autocrlf. On Windows use: + Now we need to configure how Git will handle the end-of-line. On Windows, the end-of-line are marked with + two special characters: \r for Carriage Return, and + \n for Line Feed. On macOS and Linux, the end-of-line is + indicated with \n. We have to configure a property called + core.autocrlf. On Windows use:

git config --global core.autocrlf true @@ -117,9 +110,6 @@

Configuring Git

- + diff --git a/pages/003/getting_help.html b/pages/003/getting_help.html index 292fa9b..9e8265d 100644 --- a/pages/003/getting_help.html +++ b/pages/003/getting_help.html @@ -9,7 +9,7 @@ href="../../assets/favicon/favicon.png" type="image/x-icon" /> - Getting Help + Getting help
@@ -20,7 +20,7 @@
-

Getting Help

+

Getting help

- + diff --git a/pages/004/initializing_a_repository.html b/pages/004/initializing_a_repository.html index 6ba93f7..bec371b 100644 --- a/pages/004/initializing_a_repository.html +++ b/pages/004/initializing_a_repository.html @@ -32,68 +32,57 @@

Initializing a repository

- In order to start working with Git, the first thing we need to do - is creating a directory for our project (a folder in your - computer). You can put this directory anywhere on your computer. - To do so, open Git Bash and run: + In order to start working with Git, the first thing we need to do is creating a directory for + our project (a folder in your computer). You can put this directory anywhere on your computer. To do so, + open the terminal and run:

mkdir directory_name
- Now to move into the directory use + To move into the directory use
cd directory_name
- You can combine these two actions in one with - &&. So - mkdir and - cd become + You can combine these two actions in one with &&. So + mkdir and cd become
- mkdir directory_name && cd - directory_name + mkdir directory_name && cddirectory_name

- Now that we have a directory, we need to initialize a new empty - repository. To do this, we run + Now that we have a directory, we need to initialize a new empty repository. To do this, we run

git init

- You should see a message that says that an empty repository was - initialized and the path to the directory. Inside your directory, - you now have a sub-directory called - .git. This subdirectory is hidden - because you are not supposed to touch it. If you list all the - files in your directory with + You should see a message that says that an empty repository was initialized and the path to the + directory. Inside your directory, you now have a sub-directory called + .git. This subdirectory is hidden because you are not supposed to touch + it. If you list all the files in your directory with

ls

- you won't see the - .git sub-directory. To list it, - use + you won't see the .git sub-directory. To list it, use

ls -a

- you can now see it (the -a flag - stands for all). You can open this sub-directory with + you can now see it (the -a flag stands for all). You can open + this sub-directory with

start .git

- If you corrupt or remove this directory, you will lose your - project's history. If you need to remove it, just run + If you corrupt or remove this directory, you will lose your project's history. If you need to remove it, + just run

rm -rf .git @@ -105,9 +94,6 @@

Initializing a repository

- + From a0c3db5e49cb059e2335a41934611927dc829d08 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 22:12:39 +0200 Subject: [PATCH 07/24] Update CSpell --- .cspell/git.txt | 2 ++ .cspell/names.txt | 1 + cspell.json | 18 ++++++++++++------ 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 .cspell/git.txt diff --git a/.cspell/git.txt b/.cspell/git.txt new file mode 100644 index 0000000..72c67ee --- /dev/null +++ b/.cspell/git.txt @@ -0,0 +1,2 @@ +venv +Xours diff --git a/.cspell/names.txt b/.cspell/names.txt index 63757c5..57b779f 100644 --- a/.cspell/names.txt +++ b/.cspell/names.txt @@ -1,3 +1,4 @@ Czarnievicz Hamedani Shafer +miro diff --git a/cspell.json b/cspell.json index aa012c1..fdfbc77 100644 --- a/cspell.json +++ b/cspell.json @@ -7,14 +7,20 @@ "**/.git/**", ], "dictionaryDefinitions": [ - { - "name": "names", - "path": "./.cspell/names.txt", - "addWords": true, - }, + { + "name": "git", + "path": "./.cspell/git.txt", + "addWords": true, + }, + { + "name": "names", + "path": "./.cspell/names.txt", + "addWords": true, + }, ], "dictionaries": [ - "names", + "git", + "names", ], "words": [], "ignoreWords": [ From 1a60d911b11f5be1eb9b1a63e3e1dfdf1c7df848 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 22:12:44 +0200 Subject: [PATCH 08/24] Removes image --- assets/img/index-1.png | Bin 128339 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 assets/img/index-1.png diff --git a/assets/img/index-1.png b/assets/img/index-1.png deleted file mode 100644 index cf4aec5d55780e86bca170f99b66abcc665bcfda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128339 zcmcGVbx<7N_TX`Mf;%KYa0%|gEkJM?Gz9nH7ThgpfzD`hGg(+EoznMZ?j!aGe3P(`X{!-o#|?UUf6Qd-uM8fZz?&8`_r*{MrI- z@*w-&x|f2~->sv+JM!=8#i_KtlAL~HC`elWI+DQ8LYgm&B`sH-@b6JohEqxxE$wVk zBmVshwzO<0DEr+bp3d+Ti~ue5->Z9;Qmf}Y$@dX5|Gj7)CHU%UTFi=AC)1|Rp)V*- zI9yTY$n)%KZJk-s7=qB?3 z=Hq*Pn7PVmWAxrtalCIZSzLCGu2^1Ajop`cdCs8mq1+01Z8>|)a<~|oXkt#%p4?m} zBTcn{^75VH1|5ygjS_{EPdUE7bTlR$;ue4B)(TUXh{M6xPgfvw&E22xq5I2@wiQA^ z_7f{#i#F~QvX?MZC)5!{__D%$9U4v*5gBq%t~O%zkl84s_+xD@tZh__vlT-mbBYl) z%~=PRMXTyjVT6#BPvTaRFR7tI$qOj+H3l|Tew7TB+U|{FliePA4blAouFGH$yB1SB zTwv~}fGc(|q#&1=gWYVu4;ZP7-=x~h9_1wz|>m-aF!9#uL$EH&CLa%lz9=Qj3UXVnnu7tJ)3!c zE$?Q3c$EJ9RO?W~N$q^$N`~Yp=C0q$7ZY2%Th+nc>T*z}J4IVlgRW7-NOXS$&kBx{ z9mq)l1hOwAJU2!Cp&LwE23;H7VVPT=upZ^gH zNrg!DMdz&N*jcrvIGxUUh~u3sjTBYi3{N^|Nw6e>{$#7A3DXh-b=z7oOFu~)c^4ki z2tOwAR#c@$r&G3ICPG}3ZlXA!(mE%!i;S~8xG8;hKT92d$++IZ3i^=7Fo7UCKks=d zPJqW|z}A=^f#>VL-0pTied4Xitd0I|_f8LJKv{RhTe!Eha2Q?QAC*)3UgPcrRJ9bQ z>O|huR9`LElje3pOzzA$vvgY@ju}K^&OalK<5>6;0|iYoIxDp&Y~K9CMwsm!-ldR` zinf#rIjRdp{us1-TS(cUB~Z}BMlmxI9*cq>;7)?3S*dAaMSw#ZVkxrGP<1ZdcIFF4 zOcWBsevty{7cT;x;rWt~DF0cmVXe2rOLZDop3W45c5L(d&8sDOKif|IuIvGJ`lweO zZc`d=!2+2hg$4vLl{xy_#yM^P`z!eBA)2 z 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\M^LFnD-*6Mfeha?Q*V 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 Date: Sat, 27 Sep 2025 22:14:41 +0200 Subject: [PATCH 09/24] Adds CODEOWNERS --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..4fa04fc --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @daczarne From f4409537f897bfbb7e31ff837e6233ee583d4fb0 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 22:19:04 +0200 Subject: [PATCH 10/24] Adds recommended extensions --- .vscode/extensions.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .vscode/extensions.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..adacf74 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,13 @@ +{ + "recommendations": [ + "aaron-bond.better-comments", + "davidanson.vscode-markdownlint", + "editorconfig.editorconfig", + "esbenp.prettier-vscode", + "pranaygp.vscode-css-peek", + "redhat.vscode-yaml", + "ritwickdey.liveserver", + "streetsidesoftware.code-spell-checker", + "yzhang.markdown-all-in-one", + ] +} From 3234d773bfee33870960a32da9ca5f2e3fc530ca Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sat, 27 Sep 2025 22:19:11 +0200 Subject: [PATCH 11/24] Adds LICENSE --- LICENSE | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From 2d3efadf81aa1432c3b288bf54b276daec1a5c1f Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 14:30:22 +0200 Subject: [PATCH 12/24] Updates pages --- pages/005/git_workflow.html | 57 +++++++------------- pages/006/staging_files.html | 60 ++++++++------------- pages/007/committing_changes.html | 43 ++++++--------- pages/008/removing_files.html | 41 ++++++-------- pages/009/renaming_or_moving_files.html | 24 ++++----- pages/010/ignoring_files.html | 72 ++++++++++--------------- 6 files changed, 108 insertions(+), 189 deletions(-) diff --git a/pages/005/git_workflow.html b/pages/005/git_workflow.html index 6c0e133..3455055 100644 --- a/pages/005/git_workflow.html +++ b/pages/005/git_workflow.html @@ -32,21 +32,16 @@

Git workflow

- When working with Git the normal workflow starts with making - changes to files, or adding new files, or deleting old files that - are no longer needed. Once we are done making changes, we - add these files to the - Staging Area. If we are satisfied with the changes, we - will commit those changes to the - Repository. + When working with Git the normal workflow starts with making changes to files, or adding new files, or + deleting old files that are no longer needed. Once we are done making changes, we + add these files to the Staging Area. If we are satisfied with + the changes, we will commit those changes to the Repository.


- Creating a commit is like taking - a snapshot of our project. These snapshots are permanently stored - in our repository. If there are changes that we don't want to add - to the snapshot, we can un-stage them and add them to a later - snapshot. + Creating a commit is like taking a snapshot of our project. These + snapshots are permanently stored in our repository. If there are changes that we don't want to add to the + snapshot, we can un-stage them and add them to a later snapshot.


To add a file to the staging area we use

@@ -54,16 +49,14 @@

Git workflow

git add file_name.ext

- Once we've reviewed the files and are sure that we want to take a - snapshot, we use + Once we've reviewed the files and are sure that we want to take a snapshot, we use

git commit -m "commit message"

- Every commit should contain a - meaningful message that explains what changes were made in that - snapshot. + Every commit should contain a meaningful message that explains what + changes were made in that snapshot.

@@ -80,26 +73,21 @@

Git workflow

- Once we commit some changes the - Staging Area does not get emptied. Think of it as the - staging server of an application. Once we release a new version, - the live and staging versions are the same, but that does not mean - that there is no staging version. + Once we commit some changes the Staging Area does not get + emptied. Think of it as the staging server of an application. Once we release a new version, the live and + staging versions are the same, but that does not mean that there is no staging version.


- If we make some new changes to a file, we need to - stage the files again. The same - is true when deleting files. If we delete a file from our working - directory, we need to stage the - deletion. To do it we use + If we make some new changes to a file, we need to stage the files again. + The same is true when deleting files. If we delete a file from our working directory, we need to + stage the deletion. To do it we use

git add name_of_the_deleted_file

- Then we can permanently record this deletion by committing it with - the following command: + Then we can permanently record this deletion by committing it with the following command:

git commit -m "commit message" @@ -115,13 +103,11 @@

Git workflow

  • Date and time of the commit
  • Author
  • - A complete snapshot of the project at the time the - commit was created + A complete snapshot of the project at the time the commit was created
  • - Git can store the complete project snapshot because it compresses - the files and doesn’t store duplicates. + Git can store the complete project snapshot because it compresses the files and doesn't store duplicates.

    @@ -130,9 +116,6 @@

    Git workflow

    - + diff --git a/pages/006/staging_files.html b/pages/006/staging_files.html index c7aabed..7f5362d 100644 --- a/pages/006/staging_files.html +++ b/pages/006/staging_files.html @@ -34,18 +34,15 @@

    Staging files

    - Before we can stage a file, we - need to create one. To do so, we run + Before we can stage a file, we need to create one. To do so, we run

    echo hello > file1.txt

    - This will create a new file called file1.txt and write - the word hello into this file. - echo is not a Git command, it's - just a good ol' system command. Now let's create a second file, - using the same command + This will create a new file called file1.txt and write the word hello into this file. + echo is not a Git command, it's just a good ol' system command. Now + let's create a second file, using the same command

    echo hello > file2.txt @@ -55,22 +52,17 @@

    Staging files

    - Git will not start tracking your files on its own. To check the - status of the project's files run + Git will not start tracking your files on its own. To check the status of the project's files run

    git status

    - Here we can see that our two files are un-tracked. We also see - that they are not in the Staging Area because they are - red. In order to add them to the - Staging Area, we use the - git add command and the name of - the file(s). Here we can pass one file or more, separated by a - space. We can also use patterns (all files matching this pattern - will be added), or a period (all files in the directory will be - added). + Here we can see that our two files are un-tracked. We also see that they are not in the + Staging Area because they are red. In order to add them to the + Staging Area, we use the git add command and the name of the + file(s). Here we can pass one file or more, separated by a space. We can also use patterns (all files + matching this pattern will be added), or a period (all files in the directory will be added).

    git add *.txt @@ -94,34 +86,27 @@

    Staging files

    - Now if we run git status again, - you'll see that the files changed to - green because they are in the - Staging Area. + Now if we run git status again, you'll see that the files changed to + green because they are in the Staging Area.

    - Now let's modify file1.txt by appending the word - world to it. To do this, we run the same command as for - creating it but with a double greater-than symbol: + Now let's modify file1.txt by appending the word world to it. To do this, we run the + same command as for creating it but with a double greater-than symbol:

    echo world >> file1.txt

    - And let's run git status again. - See that now file1.txt is both in the - Staging Area and in the Working Directory. This - is because when we staged the - files, Git took a snapshot of file1.txt and placed it in - the Staging Area. So the version of - file1.txt that exists in the - Staging Area differs from the one that exists in the - Working Directory. We can sync them up by running - git add file1.txt again. + And let's run git status again. See that now file1.txt is both + in the Staging Area and in the Working Directory. This is because when we + staged the files, Git took a snapshot of file1.txt and placed + it in the Staging Area. So the version of file1.txt that exists in the + Staging Area differs from the one that exists in the Working Directory. We can sync + them up by running git add file1.txt again.

    @@ -137,9 +122,6 @@

    Staging files

    - + diff --git a/pages/007/committing_changes.html b/pages/007/committing_changes.html index 9af6bc6..9208310 100644 --- a/pages/007/committing_changes.html +++ b/pages/007/committing_changes.html @@ -32,19 +32,16 @@

    Committing changes

    - Now we have a snapshot in the Staging Area that is ready - to be permanently saved in the Repository. To do this we - run + Now we have a snapshot in the Staging Area that is ready to be permanently saved in the + Repository. To do this we run

    git commit -m "Commit Message"

    - Here the -m flag means that we - are providing a message. The message itself is what we type in - quotes. This will only let us write a short one-line message. If - we need longer messages we omit the flag, and Git will open our - text editor, where we can enter a more detailed message. + Here the -m flag means that we are providing a message. The message + itself is what we type in quotes. This will only let us write a short one-line message. If we need longer + messages we omit the flag, and Git will open our text editor, where we can enter a more detailed message.

    git commit @@ -62,32 +59,25 @@

    Committing changes

    - Now on VS Code, we can write our - commit message. On the first - line, we should write the title of our commit or a short - description of it. This description should not exceed 80 + Now on VS Code, we can write our commit message. On the first line, we + should write the title of our commit or a short description of it. This description should not exceed 80 characters.


    - Then we write a long description that explains what was changed, - deleted, or added in this commit. - When done, we save the changes and close VS Code. Keep in mind - that when we close VS Code the - commit command is executed, so - make sure to double-check your message and make sure you included - everything that needs to be included. + Then we write a long description that explains what was changed, deleted, or added in this + commit. When done, we save the changes and close VS Code. Keep in mind + that when we close VS Code the commit command is executed, so make sure + to double-check your message and make sure you included everything that needs to be included.

    - Back in Git Bash, we'll see a message with basic statistics of - what was changed. Here it says that two files were changed: - file1.txt and file2.txt. It also says that there - were three insertions (one for each time we added - hello to each file and one for when we added + Back in Git Bash, we'll see a message with basic statistics of what was changed. Here it says that two + files were changed: file1.txt and file2.txt. It also says that there were three + insertions (one for each time we added hello to each file and one for when we added world to file1.txt).

    @@ -104,9 +94,6 @@

    Committing changes

    - + diff --git a/pages/008/removing_files.html b/pages/008/removing_files.html index d64aae9..0e577ba 100644 --- a/pages/008/removing_files.html +++ b/pages/008/removing_files.html @@ -34,43 +34,37 @@

    Removing files

    - To remove a file (say file2.txt) from our repository we - could use rm file2.txt. The - problem with this command is that is not a - git command. So the file will be - removed from the Working Directory, but not from the - Staging Area. It's OK to do it this way, just remember - that since the file is still in the Staging Area, you'll - need to git add it and then - git commit it. Since this is such - a common operation, there's a Git version of the remove command - that does everything in one step. + To remove a file (say file2.txt) from our repository we could use + rm file2.txt. The problem with this command is that is not a + git command. So the file will be removed from the + Working Directory, but not from the Staging Area. It's OK to do it this way, just + remember that since the file is still in the Staging Area, you'll need to + git add it and then git commit it. + Since this is such a common operation, there's a Git version of the remove command that does everything + in one step.

    - You can check which files are in the Staging Area by - running + You can check which files are in the Staging Area by running

    git ls-files

    - You should see both files in there: file1.txt and - file2.txt. Now to delete file2.txt we use + You should see both files in there: file1.txt and file2.txt. Now to delete + file2.txt we use

    git rm file2.txt

    - If you run git ls-files again, - you should see that file2.txt is no longer in the - Staging Area. And if you run - ls you'll see that neither is - file2.txt in the Working Directory. We have - successfully delete file2.txt in one command. + If you run git ls-files again, you should see that file2.txt is + no longer in the Staging Area. And if you run ls you'll see + that neither is file2.txt in the Working Directory. We have successfully delete + file2.txt in one command.

    @@ -86,9 +80,6 @@

    Removing files

    - + diff --git a/pages/009/renaming_or_moving_files.html b/pages/009/renaming_or_moving_files.html index 4cd5a36..4ec5cd7 100644 --- a/pages/009/renaming_or_moving_files.html +++ b/pages/009/renaming_or_moving_files.html @@ -32,33 +32,30 @@

    Renaming or moving files

    - Just as with removing; renaming or moving files can be two-step - operations if we don't use Git commands. Keep in mind here that - for your OS, the complete name of a file includes the path to it, - so moving is like renaming. + Just as with removing; renaming or moving files can be two-step operations if we don't use Git commands. + Keep in mind here that for your OS, the complete name of a file includes the path to it, so moving is + like renaming.

    - Suppose we want to change the name of file1.txt to - main.txt. To do this in one command we use + Suppose we want to change the name of file1.txt to main.txt. To do this in one command + we use

    git mv file1.txt main.txt

    - Now that our file has been renamed, we can check that it's already - in the Staging Area by running + Now that our file has been renamed, we can check that it's already in the Staging Area by running

    git status

    - See that Git already realized that what we are doing is renaming a - file. Now we can commit our - changes. + See that Git already realized that what we are doing is renaming a file. Now we can + commit our changes.

    @@ -74,9 +71,6 @@

    Renaming or moving files

    - + diff --git a/pages/010/ignoring_files.html b/pages/010/ignoring_files.html index 87bbffb..73e64ed 100644 --- a/pages/010/ignoring_files.html +++ b/pages/010/ignoring_files.html @@ -32,25 +32,23 @@

    Ignoring files

    - Sometimes we don't want Git to track certain files. To handle this - we use a special file "called" .gitignore. This file has - no name, only an extension. We should place it at the root of our + Sometimes we don't want Git to track certain files. To handle this we use a special file called + .gitignore. This file has no name, only an extension. We should place it at the root of our project. To create it we run

    touch .gitignore

    - If at the time of creating it we already have a file or - sub-directory that we want to add to it, we can use + If at the time of creating it we already have a file or sub-directory that we want to add to it, we can + use

    echo file_name.ext > .gitignore

    - If we already have a .gitignore file and we want to add a - new file to it (i.e. we want to append the - .gitignore file), we run + If we already have a .gitignore file and we want to add a new file to it (i.e. we want to append + the .gitignore file), we run

    echo new_file_name.ext >> .gitignore @@ -60,8 +58,7 @@

    Ignoring files

    echo sub-dir_name/ >> .gitignore

    - Once we've created our .gitignore file, we can inspect it - with VS Code by running + Once we've created our .gitignore file, we can inspect it with VS Code by running

    code .gitignore @@ -72,31 +69,27 @@

    Ignoring files

    - As an example, let's create a logs sub-directory and add - it to our .gitignore file. First, we create the sub-dir - and a file inside that sub-dir with + As an example, let's create a logs sub-directory and add it to our .gitignore file. + First, we create the sub-dir and a file inside that sub-dir with

    mkdir logs && echo hello > logs/dev.log

    - Next, we add it to (and create) the .gitignore file by - running + Next, we add it to (and create) the .gitignore file by running

    echo logs/ > .gitignore

    - Now, if we run a git status, - we'll see that the .gitignore file is only in the - Working Directory, so we'll + Now, if we run a git status, we'll see that the .gitignore file + is only in the Working Directory, so we'll

    git add .gitignore

    and

    git commit -m "Add .gitignore file"

    - to commit it to our Repository. But notice that we didn't stage - nor committed our logs sub-dir. + to commit it to our Repository. But notice that we didn't stage nor committed our logs sub-dir.

    @@ -111,38 +104,30 @@

    Ignoring files

    - Inside our .gitignore we can have as many items as we - want. We can add new files as file_name.ext, we can add - entire sub-directories as sub-dir_name/, or we can use - patterns. So, for example, adding config.py will cause - Git to ignore the file named config.py. Adding - *.js will cause Git to ignore all files with a - .js extension in our project. Adding - logs/*.log will cause Git to ignore all files with - extension .log in the logs/ sub-dir, but not - other files in that sub-dir, nor files with the - .log extension in other directories inside our project. + Inside our .gitignore we can have as many items as we want. We can add new files as + file_name.ext, we can add entire sub-directories as sub-dir_name/, or we can use + patterns. So, for example, adding config.py will cause Git to ignore the file named + config.py. Adding *.js will cause Git to ignore all files with a .js extension + in our project. Adding logs/*.log will cause Git to ignore all files with extension .log + in the logs/ sub-dir, but not other files in that sub-dir, nor files with the .log + extension in other directories inside our project.

    - Keep in mind that all of this only works if you haven't added a - file to the repository already. If you have, Git will keep on - tracking it. If you added a file to the repository and you now - want Git to stop tracking it, you need to remove it from the - staging area. To do this we'll use + Keep in mind that all of this only works if you haven't added a file to the repository already. If you + have, Git will keep on tracking it. If you added a file to the repository and you now want Git to stop + tracking it, you need to remove it from the staging area. To do this we'll use

    git rm --cached -r file_name

    - Now you can commit this deletion and Git will stop tracking the - file. Do not forget the - --cached option or Git will - remove the file both from the staging area and the working - directory!! + Now you can commit this deletion and Git will stop tracking the file. Do not forget the + --cached option or Git will remove the file both from the staging area + and the working directory!

    @@ -151,9 +136,6 @@

    Ignoring files

    - + From 40a6506d57988669d33ba33d4b15230f70e33bfe Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 14:57:05 +0200 Subject: [PATCH 13/24] Updates pages --- pages/011/short_status.html | 72 +++++-------- pages/012/viewing_changes.html | 128 +++++++++--------------- pages/013/viewing_history.html | 24 ++--- pages/014/viewing_a_commit.html | 64 +++++------- pages/015/unstaging_files.html | 35 +++---- pages/016/discarding_local_changes.html | 34 +++---- pages/017/restoring_a_file.html | 36 +++---- pages/018/viewing_the_history.html | 41 +++----- 8 files changed, 160 insertions(+), 274 deletions(-) diff --git a/pages/011/short_status.html b/pages/011/short_status.html index 5fe8cce..c601f80 100644 --- a/pages/011/short_status.html +++ b/pages/011/short_status.html @@ -32,28 +32,22 @@

    Short status

    - We can get a less verbose version of the status of our project by - running + We can get a less verbose version of the status of our project by running

    git status -s

    - To show how this works, suppose that we've created a new file - file2.txt and modified an existing file, - file1.txt. In the short version of the status each file - name is preceded by two columns: the left column represents the - staging area, and the right column represents the working - directory. + To show how this works, suppose that we've created a new file file2.txt and modified an existing + file, file1.txt. In the short version of the status each file name is preceded by two columns: + the left column represents the staging area, and the right column represents the working directory.


    - In this example, file1.txt is shown with a red - M. Git is telling us that this file - has been modified, but that this modification is not in the - staging area, only in the working directory. - file1.txt has nothing in the left column since there are - no changes in this file affecting its staging area status. + In this example, file1.txt is shown with a red M. Git is telling us + that this file has been modified, but that this modification is not in the staging area, only in the + working directory. file1.txt has nothing in the left column since there are no changes in this + file affecting its staging area status.

    @@ -74,13 +68,10 @@

    Short status

    - If we stage file1.txt and run - git status -s again, we see that - now file1.txt has a green - M on the left column. This means - that all the changes we had in the working area are now in the - staging area. The right column is now empty because we don't have - any other changes to add. + If we stage file1.txt and run git status -s again, we see that + now file1.txt has a green M on the left column. This means that + all the changes we had in the working area are now in the staging area. The right column is now empty + because we don't have any other changes to add.

    @@ -88,12 +79,10 @@

    Short status

    Now let's make some more changes to file1.txt and run - git status -s one more time. Git - is now showing a green M on the - left-hand column and a red M on the - right-hand column. This means that there are staged changes and - un-staged changes. To add the new changes to the staging area we - just run + git status -s one more time. Git is now showing a green + M on the left-hand column and a red M on the + right-hand column. This means that there are staged changes and un-staged changes. To add the new changes + to the staging area we just run

    git add file1.txt @@ -117,14 +106,11 @@

    Short status

    - Now let's take a look at file2.txt. This file has two red - ?? because it's a new file. To add it - to the staging area we just run - git add file2.txt. Now the Git - status has a green A on the - left-hand side column. This means that the file is new, and it's - in the staging area. We can go ahead and commit it if we are - satisfied with the changes by running + Now let's take a look at file2.txt. This file has two red ?? because + it's a new file. To add it to the staging area we just run + git add file2.txt. Now the Git status has a green + A on the left-hand side column. This means that the file is new, and it's + in the staging area. We can go ahead and commit it if we are satisfied with the changes by running

    git commit -m "Add file2.txt" @@ -134,16 +120,13 @@

    Short status

    - If we now delete both files, Git will show them with a green - D on the left-hand column. This - means that they are both going to be deleted. + If we now delete both files, Git will show them with a green D on the + left-hand column. This means that they are both going to be deleted.


    - If at any time you run - git status -s and there are no - changes to neither the working nor the staging area, Git will show - an empty line. + If at any time you run git status -s and there are no changes to neither + the working nor the staging area, Git will show an empty line.

    @@ -159,9 +142,6 @@

    Short status

    - + diff --git a/pages/012/viewing_changes.html b/pages/012/viewing_changes.html index ff5ebd5..2b3a86f 100644 --- a/pages/012/viewing_changes.html +++ b/pages/012/viewing_changes.html @@ -32,32 +32,24 @@

    Viewing changes

    - The git status -s only tells us - which files have changed. To explore what we have in the staging - area we use + The git status -s only tells us which files have changed. To explore + what we have in the staging area we use

    git diff --staged

    - The first line of this output tells us that the - diff utility was called to - compare two versions of file1.txt. The copy prefixed with - a is the old copy (the one we had - in the last commit). The copy prefixed with - b is the one we have in the - staging area. Next, we have a legend with the IDs. After that, - there's a line with - --- a/file1.txt and another one - with +++ b/file1.txt. Changes to - the old copy are prefixed with minus signs and changes to the new - copy are prefixed with plus signs. After that, there's a header - with information about which parts of the files have changed. This - is because Git will not show the entire file (if it's too long), - just a chunk. Each chunk has a header that looks like that. The - first part of the header says - -1,3. This means Git is showing - lines 1 through 3 of the old copy. + The first line of this output tells us that the diff utility was called + to compare two versions of file1.txt. The copy prefixed with a + is the old copy (the one we had in the last commit). The copy prefixed with + b is the one we have in the staging area. Next, we have a legend with + the IDs. After that, there's a line with --- a/file1.txt and another one + with +++ b/file1.txt. Changes to the old copy are prefixed with minus + signs and changes to the new copy are prefixed with plus signs. After that, there's a header with + information about which parts of the files have changed. This is because Git will not show the entire + file (if it's too long), just a chunk. Each chunk has a header that looks like that. The first part of + the header says -1,3. This means Git is showing lines 1 through 3 of the + old copy.

    @@ -71,12 +63,9 @@

    Viewing changes

    - The second part of the header says - +1,5. This means Git is showing - us lines 1 through 5 of the new copy. Below that we can see the - difference between the two of them. The - +sky and - +ocean mean that those two lines + The second part of the header says +1,5. This means Git is showing us + lines 1 through 5 of the new copy. Below that we can see the difference between the two of them. The + +sky and +ocean mean that those two lines are new lines that are being added in the new version of the file.

    @@ -84,12 +73,10 @@

    Viewing changes

    - Now we'll compare two versions of file2.txt. In this - case, Git is showing - --- /dev/null along with a header - of -0,0 because the file is new. - So, from the "previous" (none-existing) version is pulling lines 0 - through 0. + Now we'll compare two versions of file2.txt. In this case, Git is showing + --- /dev/null along with a header of + -0,0 because the file is new. So, from the "previous" (none-existing) + version is pulling lines 0 through 0.

    @@ -103,17 +90,15 @@

    Viewing changes

    - If instead, we wish to compare files in the working area to files - in the staging area, we use the same command but without the - --staged option. So, + If instead, we wish to compare files in the working area to files in the staging area, we use the same + command but without the --staged option. So,

    git diff

    - Here Git is telling us that in file1.txt the first two - lines (hello and - world) were removed and replaced with + Here Git is telling us that in file1.txt the first two lines + (hello and world) were removed and replaced with a new line (hello world).

    @@ -121,18 +106,16 @@

    Viewing changes

    - As you may have probably guessed already, this is not how we - inspect changes. To inspect changes we use a diff tool. - Here we'll use VS Code. So first we need to set VS Code as our - default diff tool. To do that, we run + As you may have probably guessed already, this is not how we inspect changes. To inspect changes we use a + diff tool. Here we'll use VS Code. So first we need to set VS Code as our default diff tool. To + do that, we run

    git config --global diff.tool vscode

    - With this command, we are just giving a name to our default - diff tool. Now we need to tell Git how to launch our diff - tool. To do this we run + With this command, we are just giving a name to our default diff tool. Now we need to tell Git + how to launch our diff tool. To do this we run

    @@ -141,18 +124,13 @@

    Viewing changes

    - For this to work remember that you must have added VS Code to your - system path. If you forgot about that, the easiest way is to just - reinstall VS Code and check the add to PATH checkbox on the - installation wizard. code just - tells the command prompt that it needs to open VS Code. The - --wait option tells the command - prompt that it needs to wait until we are done with VS Code. The - --diff option tells VS Code that - we want to use it for diffing files. Lastly, - $LOCAL and - $REMOTE are placeholders for the - older and newer versions of the file. + For this to work remember that you must have added VS Code to your system path. If you forgot about that, + the easiest way is to just reinstall VS Code and check the add to PATH checkbox on the installation + wizard. code just tells the command prompt that it needs to open VS + Code. The --wait option tells the command prompt that it needs to wait + until we are done with VS Code. The --diff option tells VS Code that + we want to use it for diffing files. Lastly, $LOCAL and + $REMOTE are placeholders for the older and newer versions of the file.

    @@ -163,12 +141,10 @@

    Viewing changes

    git config --global -e

    - This will open the Git settings in VS Code. You should see the - commands we just run at the bottom of the file. Make sure that - they are just as we typed them. So tool = vscode and - cmd = "code --wait --diff $LOCAL $REMOTE". If there are - any mistakes, you can correct them there. Just remember to save - your changes before closing. + This will open the Git settings in VS Code. You should see the commands we just run at the bottom of the + file. Make sure that they are just as we typed them. So tool = vscode and + cmd = "code --wait --diff $LOCAL $REMOTE". If there are any mistakes, you can correct them there. + Just remember to save your changes before closing.

    @@ -182,13 +158,10 @@

    Viewing changes

    - Now, all we need to do is to change the - diff part of our command with - difftool and select - Y when prompted by Git Bash. This - will open VS Code with both versions of our file placed side by - side. The old copy that we have in the staging area is shown on - the left-hand side panel, and the new copy that we have in the + Now, all we need to do is to change the diff part of our command with + difftool and select Y when prompted by + Git Bash. This will open VS Code with both versions of our file placed side by side. The old copy that we + have in the staging area is shown on the left-hand side panel, and the new copy that we have in the working directory is shown on the right-hand side panel.

    @@ -213,11 +186,9 @@

    Viewing changes

    git difftool --staged

    - In this case, the old copy (left) is what we had on the last - commit, and the new copy (right) is what we have on the staging - area. If more than one file is affected then, once we are done - with the first one and close VS Code, Git Bash will ask us if we - want to look at the other one. + In this case, the old copy (left) is what we had on the last commit, and the new copy (right) is what we + have on the staging area. If more than one file is affected then, once we are done with the first one and + close VS Code, Git Bash will ask us if we want to look at the other one.

    @@ -226,9 +197,6 @@

    Viewing changes

    - + diff --git a/pages/013/viewing_history.html b/pages/013/viewing_history.html index ea6ff5e..8628678 100644 --- a/pages/013/viewing_history.html +++ b/pages/013/viewing_history.html @@ -36,15 +36,13 @@

    Viewing history

    git log

    - This will print the last commits done on our repository starting - from the newest one. The first line is the commit ID, then it - shows us the author of that commit, the date and time at which the - commit was done, and the one-line description for the commit. + This will print the last commits done on our repository starting from the newest one. The first line is + the commit ID, then it shows us the author of that commit, the date and time at which the commit was done, + and the one-line description for the commit.


    - To see more commits press the space bar. This will print the next - page in the commit log. To quit, press + To see more commits press the space bar. This will print the next page in the commit log. To quit, press q.

    @@ -66,15 +64,12 @@

    Viewing history

    - We can add the --oneline option - to tell Git to print a summary of the history. Git will show the - last 7 characters of the commit ID, followed by the commit - message. + We can add the --oneline option to tell Git to print a summary of the + history. Git will show the last 7 characters of the commit ID, followed by the commit message.


    - If we want the commit history to be printed in reverse order - (oldest first), we just need to add the + If we want the commit history to be printed in reverse order (oldest first), we just need to add the --reverse option to our command.

    @@ -84,9 +79,6 @@

    Viewing history

    - + diff --git a/pages/014/viewing_a_commit.html b/pages/014/viewing_a_commit.html index 59da034..225d906 100644 --- a/pages/014/viewing_a_commit.html +++ b/pages/014/viewing_a_commit.html @@ -32,20 +32,16 @@

    Viewing a commit

    - Suppose now that we want to look at one specific commit in our - history. To do this we'll use the - git show command. We need to - specify the commit that we want to inspect. There are two ways in - which we can reference a commit: 1) by the commit ID, 2) as the - number of commits before the - HEAD pointer of our repository. + Suppose now that we want to look at one specific commit in our history. To do this we'll use the + git show command. We need to specify the commit that we want to inspect. + There are two ways in which we can reference a commit: 1) by the commit ID, 2) as the number of commits + before the HEAD pointer of our repository.


    - Here's an example (image). If we want to view the commit previous - to the - HEAD pointer of our repository we - can run either one of the following commands + Here's an example (image). If we want to view the commit previous to the + HEAD pointer of our repository we can run either one of the following + commands

    git show 292c34d @@ -54,12 +50,10 @@

    Viewing a commit

    git show HEAD~1

    - If we use the commit ID we don't have to pass all the first 7 - characters of the ID. We can pass fewer characters as long as it - doesn't generate ambiguity. If we instead go with the second - option, the number after the tilde is how many steps back from the - HEAD pointer we wish to go. Not - including the tilde and number means that we wish Git to show the + If we use the commit ID we don't have to pass all the first 7 characters of the ID. We can pass fewer + characters as long as it doesn't generate ambiguity. If we instead go with the second option, the number + after the tilde is how many steps back from the HEAD pointer we wish to + go. Not including the tilde and number means that we wish Git to show the HEAD.

    @@ -74,10 +68,9 @@

    Viewing a commit

    - Regardless of which one we use, Git will print the commit - information along with the diff. If instead of seeing the diff we - want to inspect the state of a specific file at that point in the - repository's history we run + Regardless of which one we use, Git will print the commit information along with the diff. If instead of + seeing the diff we want to inspect the state of a specific file at that point in the repository's history + we run

    git show HEAD~1:file_name.ext @@ -98,23 +91,20 @@

    Viewing a commit

    - If instead of browsing the commits we want to inspect the state of - our entire repository at the time of a specific commit we run + If instead of browsing the commits we want to inspect the state of our entire repository at the time of a + specific commit we run

    git ls-tree HEAD~1

    - This will print the list of the objects that were present in our - repository at the time of the commit that we specified. Elements - of type blob are files and - elements of type tree are - sub-directories within our project. + This will print the list of the objects that were present in our repository at the time of the commit + that we specified. Elements of type blob are files and elements of type + tree are sub-directories within our project.


    - Now we can ask Git to show us the content of a specific file by - running + Now we can ask Git to show us the content of a specific file by running

    git show file_id @@ -124,16 +114,15 @@

    Viewing a commit

    - For example, if we want to inspect the main.txt file - inside the src sub-directory, we run + For example, if we want to inspect the main.txt file inside the src sub-directory, we + run

    git ls-tree HEAD~1:src/

    - This tells Git that we want to inspect the - ls-tree of the - src subdirectory. Now we can pick our file by its ID + This tells Git that we want to inspect the ls-tree of the src + subdirectory. Now we can pick our file by its ID

    git show 31e0f @@ -152,9 +141,6 @@

    Viewing a commit

    - + diff --git a/pages/015/unstaging_files.html b/pages/015/unstaging_files.html index 676b636..0684f0b 100644 --- a/pages/015/unstaging_files.html +++ b/pages/015/unstaging_files.html @@ -34,9 +34,8 @@

    Un-staging files

    - Suppose that we've added some changes to the staging area, but we - now realize that we shouldn't have. We want to un-stage our - file(s) and get it back to the working area. To solve this we run + Suppose that we've added some changes to the staging area, but we now realize that we shouldn't have. We + want to un-stage our file(s) and get it back to the working area. To solve this we run

    git restore --staged file_name.ext @@ -53,16 +52,13 @@

    Un-staging files

    - We can pass one filename, multiple files separated by a space, - patterns such as *.txt, or a - period to indicate all files. This tells Git to take the changes - that are already in the staging area and revert them to the - working directory. What Git is doing here under the hood is taking - the last version of our file from the next environment. So, if we - restore a file that is in the - staging area, the last version from the next environment is the - state of the file in the last commit. Git will take this version - and place it in the staging area. + We can pass one filename, multiple files separated by a space, patterns such as + *.txt, or a period to indicate all files. This tells Git to take the + changes that are already in the staging area and revert them to the working directory. What Git is doing + here under the hood is taking the last version of our file from the next environment. So, if we + restore a file that is in the staging area, the last version from the + next environment is the state of the file in the last commit. Git will take this version and place it in + the staging area.

    @@ -76,11 +72,9 @@

    Un-staging files

    - Now suppose the file we want to restore is a new file, so it - didn't exist at the last commit. If we - restore this file, Git will take - the staging area version of it, and place it in the working - directory as a new un-tracked file. + Now suppose the file we want to restore is a new file, so it didn't exist at the last commit. If we + restore this file, Git will take the staging area version of it, and + place it in the working directory as a new un-tracked file.

    @@ -89,9 +83,6 @@

    Un-staging files

    - + diff --git a/pages/016/discarding_local_changes.html b/pages/016/discarding_local_changes.html index 7d197c1..c66e4fc 100644 --- a/pages/016/discarding_local_changes.html +++ b/pages/016/discarding_local_changes.html @@ -32,23 +32,21 @@

    Discarding local changes

    - To discard local changes (i.e. changes in our working directory) - from a file that is already been tracked, we run + To discard local changes (i.e. changes in our working directory) from a file that is already been + tracked, we run

    git restore file_name.ext

    - Same as before, Git will take the version of this file that is in - the next environment. Since we are on the working directory now, - the next environment is the staging area. + Same as before, Git will take the version of this file that is in the next environment. Since we are on + the working directory now, the next environment is the staging area.


    - Note that file3.txt was not restored to its previous - state. This is because this file is new, so there is no previous - state. Going back to the "previous version" of this file means - deleting it. To do this we run + Note that file3.txt was not restored to its previous state. This is because this file is new, so + there is no previous state. Going back to the "previous version" of this file means deleting it. To do + this we run

    git clean -fd @@ -65,14 +63,11 @@

    Discarding local changes

    - The -fd switch is necessary - because by default Git will not allow us to delete un-tracked - files (since they can not be recovered). The - f switch is mandatory here and it - means force. So we are forcing - Git to go ahead with the removal. The - d switch is necessary for - deleting entire un-tracked sub-directories. + The -fd switch is necessary because by default Git will not allow us to + delete un-tracked files (since they can not be recovered). The f switch + is mandatory here and it means force. So we are forcing Git to go ahead + with the removal. The d switch is necessary for deleting entire + un-tracked sub-directories.

    @@ -81,9 +76,6 @@

    Discarding local changes

    - + diff --git a/pages/017/restoring_a_file.html b/pages/017/restoring_a_file.html index 76ff2dc..dc640de 100644 --- a/pages/017/restoring_a_file.html +++ b/pages/017/restoring_a_file.html @@ -34,8 +34,7 @@

    Restoring a file

    - If we deleted a file and we want to restore it to the previous - state we run + If we deleted a file and we want to restore it to the previous state we run

    @@ -43,10 +42,8 @@

    Restoring a file

    - Here we are restoring a deleted file to the version that was - available in the commit previous to deleting it. But we can use - this strategy to for file from any point in the history of our - repository. + Here we are restoring a deleted file to the version that was available in the commit previous to deleting + it. But we can use this strategy to for file from any point in the history of our repository.

    @@ -68,27 +65,21 @@

    Restoring a file

    - As an example, take a look at the image on the left. - file2.txt has only one line in it, - sky. Then we add - hello and commit the changes, and - finally we add world and commit - the changes. + As an example, take a look at the image on the left. file2.txt has only one line in it, + sky. Then we add hello and commit the + changes, and finally we add world and commit the changes.


    - file2.txt has not been deleted. It still exists in our - working directory. So, say we want to revert file2.txt to - a previous state when it only had the word + file2.txt has not been deleted. It still exists in our working directory. So, say we want to + revert file2.txt to a previous state when it only had the word sky in it. To do this we run

    git restore --source=HEAD~2 file2.txt

    - With this, Git will restore it to two steps behind the - HEAD pointer of our repository, - when the file only said sky. If - we want to keep the changes as they were at this point in time, we - can commit file2.txt to our repository. + With this, Git will restore it to two steps behind the HEAD pointer of + our repository, when the file only said sky. If we want to keep the + changes as they were at this point in time, we can commit file2.txt to our repository.

    @@ -97,9 +88,6 @@

    Restoring a file

    - + diff --git a/pages/018/viewing_the_history.html b/pages/018/viewing_the_history.html index a408c6a..9873417 100644 --- a/pages/018/viewing_the_history.html +++ b/pages/018/viewing_the_history.html @@ -34,23 +34,19 @@

    Viewing the history

    - We already covered the basic use of the - git log command and of the - --oneline option. We can use - other options with this command. For example, the - --stat will produce stats about - the files that were changed in each commit. + We already covered the basic use of the git log command and of the + --oneline option. We can use other options with this command. For + example, the --stat will produce stats about the files that were changed + in each commit.

    git log --oneline --stat

    - Take a look at the last commit. Here Git is telling us that on - this commit, 5 files were changed. There were a total of 7 - insertions and 4 deletions. Of those, 3 insertions and 1 deletion - were made to audience.txt, 1 insertion was done to the - file objectives.txt, and one deletion and one insertion - were done to each of the other files. + Take a look at the last commit. Here Git is telling us that on this commit, 5 files were changed. There + were a total of 7 insertions and 4 deletions. Of those, 3 insertions and 1 deletion were made to + audience.txt, 1 insertion was done to the file objectives.txt, and one deletion and one + insertion were done to each of the other files.

    @@ -75,11 +71,9 @@

    Viewing the history

    git log --online --patch

    - Here we can see that, for example, in the - audience.txt file, four lines were inserted: 1) a line at - the top with the AUDIENCE title, - followed by 2) a blank line, and - finally 3) a line with the text + Here we can see that, for example, in the audience.txt file, four lines were inserted: 1) a line + at the top with the AUDIENCE title, followed by 2) a + blank line, and finally 3) a line with the text No prior experience is required..


    @@ -88,8 +82,7 @@

    Viewing the history

    - If you find this view confusing, you can always open the file with - VS Code. Just open VS Code by running + If you find this view confusing, you can always open the file with VS Code. Just open VS Code by running

    code . @@ -99,9 +92,8 @@

    Viewing the history

    - Now navigate to the file and click on the - TIMELINE tab at the bottom of the - navigation panel. + Now navigate to the file and click on the TIMELINE tab at the bottom of + the navigation panel.

    @@ -120,9 +112,6 @@

    Viewing the history

    - + From 09f9daa7f943ab1704951de3a5ade10be64ce43f Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 15:42:08 +0200 Subject: [PATCH 14/24] Updates pages --- pages/001/what_is_git.html | 9 +- pages/002/configuring_git.html | 23 +-- pages/003/getting_help.html | 9 +- pages/004/initializing_a_repository.html | 9 +- pages/005/git_workflow.html | 20 +- pages/006/staging_files.html | 27 +-- pages/007/committing_changes.html | 23 +-- pages/008/removing_files.html | 15 +- pages/009/renaming_or_moving_files.html | 15 +- pages/010/ignoring_files.html | 15 +- pages/011/short_status.html | 39 +--- pages/012/viewing_changes.html | 33 +--- pages/013/viewing_history.html | 21 +- pages/014/viewing_a_commit.html | 27 +-- pages/015/unstaging_files.html | 21 +- pages/016/discarding_local_changes.html | 15 +- pages/017/restoring_a_file.html | 21 +- pages/018/viewing_the_history.html | 29 +-- pages/019/filtering_the_history.html | 110 ++++------- pages/020/aliases.html | 60 ++---- pages/021/viewing_a_commit.html | 54 ++---- .../viewing_the_changes_across_commits.html | 40 ++-- pages/023/checking_out_a_commit.html | 183 ++++++------------ pages/039/aborting_a_merge.html | 14 +- pages/081/executable_files.html | 20 +- 25 files changed, 266 insertions(+), 586 deletions(-) diff --git a/pages/001/what_is_git.html b/pages/001/what_is_git.html index a307907..0410997 100644 --- a/pages/001/what_is_git.html +++ b/pages/001/what_is_git.html @@ -1,16 +1,14 @@ + - + What is Git? +
    @@ -51,4 +49,5 @@

    What is Git?

    + diff --git a/pages/002/configuring_git.html b/pages/002/configuring_git.html index 40d6759..95eeee9 100644 --- a/pages/002/configuring_git.html +++ b/pages/002/configuring_git.html @@ -1,16 +1,14 @@ + - + Configuring Git +
    @@ -42,15 +40,9 @@

    Configuring Git

    Settings can be specified at three different levels

      -
    • - System: settings at the system level apply to all users of the computer. -
    • -
    • - Global: the settings here apply to all repositories of the current user. -
    • -
    • - Local: the settings here apply to the current repository. -
    • +
    • System: settings at the system level apply to all users of the computer.
    • +
    • Global: the settings here apply to all repositories of the current user.
    • +
    • Local: the settings here apply to the current repository.
    @@ -110,6 +102,7 @@

    Configuring Git

    - + + diff --git a/pages/003/getting_help.html b/pages/003/getting_help.html index 9e8265d..74363f5 100644 --- a/pages/003/getting_help.html +++ b/pages/003/getting_help.html @@ -1,16 +1,14 @@ + - + Getting help +
    @@ -64,4 +62,5 @@

    Getting help

    + diff --git a/pages/004/initializing_a_repository.html b/pages/004/initializing_a_repository.html index bec371b..7449c0d 100644 --- a/pages/004/initializing_a_repository.html +++ b/pages/004/initializing_a_repository.html @@ -1,16 +1,14 @@ + - + Initializing a repository +
    @@ -96,4 +94,5 @@

    Initializing a repository

    + diff --git a/pages/005/git_workflow.html b/pages/005/git_workflow.html index 3455055..d1d056a 100644 --- a/pages/005/git_workflow.html +++ b/pages/005/git_workflow.html @@ -1,16 +1,14 @@ + - + Git Workflow +
    @@ -33,8 +31,8 @@

    Git workflow

    When working with Git the normal workflow starts with making changes to files, or adding new files, or - deleting old files that are no longer needed. Once we are done making changes, we - add these files to the Staging Area. If we are satisfied with + deleting old files that are no longer needed. Once we are done making changes, we add these files to the Staging Area. If we are satisfied with the changes, we will commit those changes to the Repository.


    @@ -62,12 +60,7 @@

    Git workflow

    - Git workflow 1 + Git workflow 1
    @@ -118,4 +111,5 @@

    Git workflow

    + diff --git a/pages/006/staging_files.html b/pages/006/staging_files.html index 7f5362d..3676719 100644 --- a/pages/006/staging_files.html +++ b/pages/006/staging_files.html @@ -1,16 +1,14 @@ + - + Staging files +
    @@ -69,20 +67,12 @@

    Staging files

    - Staging files 1 + Staging files 1
    - Staging files 2 + Staging files 2

    @@ -110,11 +100,7 @@

    Staging files

    - Staging files 3 + Staging files 3
    @@ -124,4 +110,5 @@

    Staging files

    + diff --git a/pages/007/committing_changes.html b/pages/007/committing_changes.html index 9208310..8cb6f88 100644 --- a/pages/007/committing_changes.html +++ b/pages/007/committing_changes.html @@ -1,16 +1,14 @@ + - + Committing changes +
    @@ -50,12 +48,8 @@

    Committing changes

    - Committing changes 1 + Committing changes 1

    @@ -82,11 +76,7 @@

    Committing changes

    - Committing changes 2 + Committing changes 2
    @@ -96,4 +86,5 @@

    Committing changes

    + diff --git a/pages/008/removing_files.html b/pages/008/removing_files.html index 0e577ba..ede8f4f 100644 --- a/pages/008/removing_files.html +++ b/pages/008/removing_files.html @@ -1,16 +1,14 @@ + - + Removing files +
    @@ -68,11 +66,7 @@

    Removing files

    - Removing files 1 + Removing files 1
    @@ -82,4 +76,5 @@

    Removing files

    + diff --git a/pages/009/renaming_or_moving_files.html b/pages/009/renaming_or_moving_files.html index 4ec5cd7..8293ea8 100644 --- a/pages/009/renaming_or_moving_files.html +++ b/pages/009/renaming_or_moving_files.html @@ -1,16 +1,14 @@ + - + Renaming or moving files +
    @@ -59,11 +57,7 @@

    Renaming or moving files

    - Renaming or moving files 1 + Renaming or moving files 1
    @@ -73,4 +67,5 @@

    Renaming or moving files

    + diff --git a/pages/010/ignoring_files.html b/pages/010/ignoring_files.html index 73e64ed..3998559 100644 --- a/pages/010/ignoring_files.html +++ b/pages/010/ignoring_files.html @@ -1,16 +1,14 @@ + - + Ignoring files +
    @@ -93,11 +91,7 @@

    Ignoring files

    - Ignoring files 1 + Ignoring files 1
    @@ -138,4 +132,5 @@

    Ignoring files

    + diff --git a/pages/011/short_status.html b/pages/011/short_status.html index c601f80..5901689 100644 --- a/pages/011/short_status.html +++ b/pages/011/short_status.html @@ -1,16 +1,14 @@ + - + Short status +
    @@ -51,20 +49,12 @@

    Short status

    - Short status 1 + Short status 1
    - Short status 2 + Short status 2

    @@ -89,20 +79,12 @@

    Short status

    - Short status 3 + Short status 3
    - Short status 4 + Short status 4

    @@ -130,11 +112,7 @@

    Short status

    - Short status 5 + Short status 5
    @@ -144,4 +122,5 @@

    Short status

    + diff --git a/pages/012/viewing_changes.html b/pages/012/viewing_changes.html index 2b3a86f..e10d650 100644 --- a/pages/012/viewing_changes.html +++ b/pages/012/viewing_changes.html @@ -1,16 +1,14 @@ + - + Viewing changes +
    @@ -53,11 +51,7 @@

    Viewing changes

    - Viewing changes 1 + Viewing changes 1
    @@ -82,11 +76,7 @@

    Viewing changes

    - Viewing changes 2 + Viewing changes 2

    @@ -148,11 +138,7 @@

    Viewing changes

    - Viewing changes 3 + Viewing changes 3
    @@ -169,11 +155,7 @@

    Viewing changes

    - Viewing changes 4 + Viewing changes 4
    @@ -199,4 +181,5 @@

    Viewing changes

    + diff --git a/pages/013/viewing_history.html b/pages/013/viewing_history.html index 8628678..875a6f1 100644 --- a/pages/013/viewing_history.html +++ b/pages/013/viewing_history.html @@ -1,16 +1,14 @@ + - + Viewing history +
    @@ -47,20 +45,12 @@

    Viewing history

    - Viewing history 1 + Viewing history 1
    - Viewing history 2 + Viewing history 2

    @@ -81,4 +71,5 @@

    Viewing history

    + diff --git a/pages/014/viewing_a_commit.html b/pages/014/viewing_a_commit.html index 225d906..ec568c9 100644 --- a/pages/014/viewing_a_commit.html +++ b/pages/014/viewing_a_commit.html @@ -1,16 +1,14 @@ + - + Viewing a commit +
    @@ -58,11 +56,7 @@

    Viewing a commit

    - Viewing a commit 1 + Viewing a commit 1
    @@ -83,11 +77,7 @@

    Viewing a commit

    - Viewing a commit 2 + Viewing a commit 2

    @@ -129,11 +119,7 @@

    Viewing a commit

    - Viewing a commit 3 + Viewing a commit 3
    @@ -143,4 +129,5 @@

    Viewing a commit

    + diff --git a/pages/015/unstaging_files.html b/pages/015/unstaging_files.html index 0684f0b..9f87f8d 100644 --- a/pages/015/unstaging_files.html +++ b/pages/015/unstaging_files.html @@ -1,16 +1,14 @@ + - + Un-staging files +
    @@ -42,11 +40,7 @@

    Un-staging files

    - Un-staging files 1 + Un-staging files 1
    @@ -64,11 +58,7 @@

    Un-staging files

    - Un-staging files 2 + Un-staging files 2

    @@ -85,4 +75,5 @@

    Un-staging files

    + diff --git a/pages/016/discarding_local_changes.html b/pages/016/discarding_local_changes.html index c66e4fc..6850e29 100644 --- a/pages/016/discarding_local_changes.html +++ b/pages/016/discarding_local_changes.html @@ -1,16 +1,14 @@ + - + Discarding local changes +
    @@ -53,11 +51,7 @@

    Discarding local changes

    - Discarding local changes 1 + Discarding local changes 1
    @@ -78,4 +72,5 @@

    Discarding local changes

    + diff --git a/pages/017/restoring_a_file.html b/pages/017/restoring_a_file.html index dc640de..e70c95b 100644 --- a/pages/017/restoring_a_file.html +++ b/pages/017/restoring_a_file.html @@ -1,16 +1,14 @@ + - + Restoring a file +
    @@ -47,21 +45,13 @@

    Restoring a file

    - Restoring a file 1 + Restoring a file 1
    - Restoring a file 2 + Restoring a file 2

    @@ -90,4 +80,5 @@

    Restoring a file

    + diff --git a/pages/018/viewing_the_history.html b/pages/018/viewing_the_history.html index 9873417..da954cf 100644 --- a/pages/018/viewing_the_history.html +++ b/pages/018/viewing_the_history.html @@ -1,16 +1,14 @@ + - + Viewing the history +
    @@ -50,20 +48,12 @@

    Viewing the history

    - Viewing the history 1 + Viewing the history 1
    - Viewing the history 2 + Viewing the history 2

    To see the actual changes in each commit we use

    @@ -99,12 +89,8 @@

    Viewing the history

    - Viewing the history 3 + Viewing the history 3
    @@ -114,4 +100,5 @@

    Viewing the history

    + diff --git a/pages/019/filtering_the_history.html b/pages/019/filtering_the_history.html index ad6aa71..5009152 100644 --- a/pages/019/filtering_the_history.html +++ b/pages/019/filtering_the_history.html @@ -1,16 +1,14 @@ + - + Filtering the history +
    @@ -32,54 +30,42 @@

    Filtering the history

    - When browsing the history of a repository we'll usually want to - filter commits. There are several filters that we can use along - with the git log command. For - example, to see the last 3 commits we run + When browsing the history of a repository we'll usually want to filter commits. There are several filters + that we can use along with the git log command. For example, to see the + last 3 commits we run

    git log --online -3

    - To filter by author we use the - --author option and pass the name - of the author. We can short the name in an unambiguous way. + To filter by author we use the --author option and pass the name of the + author. We can short the name in an unambiguous way.

    git log --oneline --author="Daniel"
    - Filtering the history 1 + Filtering the history 1
    - Filtering the history 2 + Filtering the history 2

    - We have several ways of filtering by date. We use the - --before or - --after options. As a value we - can pass a date, or a relative date. So, for example, if we run + We have several ways of filtering by date. We use the --before or + --after options. As a value we can pass a date, or a relative date. So, + for example, if we run

    git log --oneline --before="2020-08-17"

    - Git will show us all commits done on or prior to August 17, 2020. - When using relative dates there are multiple options that Git will - understand. For example, if we run + Git will show us all commits done on or prior to August 17, 2020. When using relative dates there are + multiple options that Git will understand. For example, if we run

    git log --oneline --after="yesterday" @@ -96,85 +82,65 @@

    Filtering the history

    - To find all commits that have a specific pattern in its message we - use the --grep option. For - example, if we want to find all commits that mention + To find all commits that have a specific pattern in its message we use the + --grep option. For example, if we want to find all commits that mention app.py we run

    git log --oneline --grep="app.py"

    - The --grep option will search for - the pattern in the commit message. Keep in mind that the search is - case sensitive. + The --grep option will search for the pattern in the commit message. Keep + in mind that the search is case sensitive.


    - Now suppose we want to find all commits that have added or removed - the declaration of the hello() function. To achieve this - we run + Now suppose we want to find all commits that have added or removed the declaration of the hello() + function. To achieve this we run

    git log --oneline -S"hello()"

    - We can also add the - --patch option to see what was - done in each of the involved commits. + We can also add the --patch option to see what was done in each of the + involved commits.

    - Filtering the history 3 + Filtering the history 3
    - Filtering the history 4 + Filtering the history 4

    - We can also filter the history by a specific range of commits. - First we need to get the IDs for the two commits. Then we run + We can also filter the history by a specific range of commits. First we need to get the IDs for the two + commits. Then we run

    git log --oneline oldest_commit..newest_commit

    - Keep in mind that Git will look for commits greater than - oldest_commit and less than or - equal to newest_commit. + Keep in mind that Git will look for commits greater than oldest_commit + and less than or equal to newest_commit.

    - We can find all commits that touch a particular file or group of - files. To do so we just pass the name or names of the files to - git log. When doing this it's - recommended to separate the last option passed to the - git log command with - -- so that Git does not confuse - options from filenames. Also, keep in mind that all options must - be supplied before the filenames. + We can find all commits that touch a particular file or group of files. To do so we just pass the name or + names of the files to git log. When doing this it's recommended to + separate the last option passed to the git log command with + -- so that Git does not confuse options from filenames. Also, keep in + mind that all options must be supplied before the filenames.

    - Filtering the history 5 + Filtering the history 5
    @@ -182,9 +148,7 @@

    Filtering the history

    - + + diff --git a/pages/020/aliases.html b/pages/020/aliases.html index 3f37c93..66066da 100644 --- a/pages/020/aliases.html +++ b/pages/020/aliases.html @@ -1,16 +1,14 @@ + - + Aliases +
    @@ -32,12 +30,10 @@

    Aliases

    - We can create personal Git commands using aliases. First, let's - take a look at how to format the output. For this, suppose you - don't like the output of neither the - git log command, nor the output - of git log --oneline. We can - create a personalized output like this: + We can create personal Git commands using aliases. First, let's take a look at how to format the output. + For this, suppose you don't like the output of neither the git log + command, nor the output of git log --oneline. We can create a + personalized output like this:

    @@ -46,17 +42,11 @@

    Aliases

    - Here %an stands for - author name, %h stands - for short hash, and - %cd stands for - commit date. %C is for - setting and resetting the color. You can check the complete list - of possible placeholders and styles - - here - - . + Here %an stands for author name, + %h stands for short hash, and + %cd stands for commit date. %C + is for setting and resetting the color. You can check the complete list of possible placeholders and + styles here.

    @@ -69,24 +59,19 @@

    Aliases

    - Of course typing all of this every time we want to use the command - is very time consuming. But in Git we can set up aliases for any - command we want (even the built in ones). First we need to define - a new property in the - alias section of the Git - configuration. So we run: + Of course typing all of this every time we want to use the command is very time consuming. But in Git we + can set up aliases for any command we want (even the built in ones). First we need to define a new + property in the alias section of the Git configuration. So we run:

    - git config --global alias.lg "log - --pretty=format:'%Cgreen%an%Creset committed %Cgreen%h%Creset on + git config --global alias.lg "log --pretty=format:'%Cgreen%an%Creset committed %Cgreen%h%Creset on %Cgreen%cd%Creset'"

    - Here lg will be the name of our - custom command, and in between quotes we type our command. We can - see (and edit) our command in VS Code. + Here lg will be the name of our custom command, and in between quotes we + type our command. We can see (and edit) our command in VS Code.

    @@ -104,8 +89,7 @@

    Aliases

    - With it we can restore all the files in the staging area with one - simple command. + With it we can restore all the files in the staging area with one simple command.

    git unstage @@ -120,9 +104,7 @@

    Aliases

    - + + diff --git a/pages/021/viewing_a_commit.html b/pages/021/viewing_a_commit.html index b0e085c..e9f83c4 100644 --- a/pages/021/viewing_a_commit.html +++ b/pages/021/viewing_a_commit.html @@ -1,16 +1,14 @@ + - + Viewing a commit +
    @@ -32,58 +30,44 @@

    Viewing a commit

    - We can view commits with the - git show command. When doing so, - we can reference a commit hash, or we can use the - HEAD pointer. For example, to see - the commit twice removed from the repository - HEAD we run + We can view commits with the git show command. When doing so, we can + reference a commit hash, or we can use the HEAD pointer. For example, to + see the commit twice removed from the repository HEAD we run

    git show HEAD~2

    - Git will show all the information about that commit. If instead we - only want to see the final version of a file in the that commit we - run + Git will show all the information about that commit. If instead we only want to see the final version of a + file in the that commit we run

    git show HEAD~2:file_path/file_name.ext

    - Keep in mind that if the file is not in the root of our project, - we need to supply the entire path and the filename. + Keep in mind that if the file is not in the root of our project, we need to supply the entire path and the + filename.

    - Viewing a commit 1 + Viewing a commit 1
    - Viewing a commit 2 + Viewing a commit 2

    - If we only want to see the files that were modified in a commit, - we use the --name-only option + If we only want to see the files that were modified in a commit, we use the --name-only option

    git show HEAD~2 --name-only

    - With this option, we can only see the names of the files. If we - also want to see what was done to those files (added, delete, - modified), we use the - --name-status option + With this option, we can only see the names of the files. If we also want to see what was done to those + files (added, delete, modified), we use the --name-status option

    git show HEAD~2 --name-status @@ -95,9 +79,7 @@

    Viewing a commit

    - + + diff --git a/pages/022/viewing_the_changes_across_commits.html b/pages/022/viewing_the_changes_across_commits.html index b2fb768..fee9064 100644 --- a/pages/022/viewing_the_changes_across_commits.html +++ b/pages/022/viewing_the_changes_across_commits.html @@ -1,16 +1,14 @@ + - + Viewing changes across commits +
    @@ -34,43 +32,33 @@

    Viewing changes across commits

    - Suppose we want to see what has changed over the last 3 commits. - To do that we use the + Suppose we want to see what has changed over the last 3 commits. To do that we use the git diff command

    git diff HEAD~3 HEAD

    - If we only want to see the changes to a particular file, we can - add the filename at the end of the command + If we only want to see the changes to a particular file, we can add the filename at the end of the command

    git diff HEAD~3 HEAD file_path/file_name.ext
    - Viewing the changes across commits + Viewing the changes across commits
    - Viewing the changes across commits 2 + Viewing the changes across commits 2

    - Here too we can use options like - --name-only or - --name-status to see only the - list of files that have been changed. + Here too we can use options like --name-only or + --name-status to see only the list of files that have been changed.

    git diff HEAD~5 HEAD~2 --name-only @@ -85,9 +73,7 @@

    Viewing changes across commits

    - + + diff --git a/pages/023/checking_out_a_commit.html b/pages/023/checking_out_a_commit.html index 8a38d16..8f175b8 100644 --- a/pages/023/checking_out_a_commit.html +++ b/pages/023/checking_out_a_commit.html @@ -1,24 +1,19 @@ + - + Checking out a commit +
    @@ -35,10 +30,9 @@

    Checking out a commit

    - Suppose we want to see the snapshot of the complete project at a - certain point in time. We can - checkout a specific commit, and - Git will restore our project to that point in time. + Suppose we want to see the snapshot of the complete project at a certain point in time. We can + checkout a specific commit, and Git will restore our project to that + point in time.

    git checkout commit_hash @@ -49,194 +43,129 @@

    Checking out a commit

    - Checking out a commit 1 + Checking out a commit 1
    - Checking out a commit 2 + Checking out a commit 2

    - Imagine the image to our left represents our repository. The way - Git can keep track of things is by using pointers. If your - background is not in software engineering, just think about - pointers like...well...that...things that point to other things. - An instruction a program needs (in this case Git) that tells him - where he needs to go to find something. Each commit points to its - previous commit. + Imagine the image to our left represents our repository. The way Git can keep track of things is by using + pointers. If your background is not in software engineering, just think about pointers + as...well...that...things that point to other things. An instruction a program needs (in this case Git) + that tells him where he needs to go to find something. Each commit points to its previous commit.

    - All the commits that we've created so far are part of the - master branch. Side note here: - Git started calling this branch the - main branch in mid-2020, but - there are still lots (probably most) repositories that haven't - been changed yet. + All the commits that we've created so far are part of the master branch. + Side note here: Git started calling this branch the main branch in + mid-2020, but there are still lots (probably most) repositories that haven't been changed yet.


    - The way Git keeps track of the different branches is with pointers - too. So, in this example, the - master branch (i.e. the pointer - that tells Git where the - master branch is) is pointing at - our last commit. + The way Git keeps track of the different branches is with pointers too. So, in this example, the + master branch (i.e. the pointer that tells Git where the + master branch is) is pointing at our last commit.

    - Checking out a commit 3 + Checking out a commit 3
    - Checking out a commit 4 + Checking out a commit 4

    - Because we can work in different branches, Git also needs to know - in which branch we are working on. To do this, Git uses another - pointer called HEAD. + Because we can work in different branches, Git also needs to know in which branch we are working on. To do + this, Git uses another pointer called HEAD.

    - This is why when we run, for example, - git log --oneline the last commit - (the first one shown) starts with - (HEAD -> - master). That's just Git's way of telling us that the - master branch is pointing to our - last commit and that we are currently (the - HEAD) pointing to it. + This is why when we run, for example, git log --oneline the last commit + (the first one shown) starts with (HEAD -> + master). That's just Git's way of telling us that the + master branch is pointing to our last commit and that we are currently + (the HEAD) pointing to it.

    - Checking out a commit 5 + Checking out a commit 5
    - Checking out a commit 6 + Checking out a commit 6

    - So, long story short, what that - 'detached HEAD' state message is - telling us is that our HEAD is - not attached to a branch anymore, but pointing to a specific - commit. + So, long story short, what that 'detached HEAD' state message is telling + us is that our HEAD is not attached to a branch anymore, but pointing to + a specific commit.

    - You can see this in the image to the right. While - master is at commit - 8eec1d2, HEAD is at - commit fa1b75e (the one we checked out to). Also, notice - that Git Bash no longer says - (master), but is instead displaying - the commit hash. + You can see this in the image to the right. While master is at commit + 8eec1d2, HEAD is at commit fa1b75e (the one we checked + out to). Also, notice that Git Bash no longer says (master), but is instead + displaying the commit hash.


    - Side note here. When inspecting the log while in a - detached HEAD we need to add the - --all option. Otherwise, Git will - only show us the commits prior to the commit where our - HEAD is at. + Side note here. When inspecting the log while in a detached HEAD we need + to add the --all option. Otherwise, Git will only show us the commits + prior to the commit where our HEAD is at.

    - Checking out a commit 7 + Checking out a commit 7
    - Checking out a commit 8 + Checking out a commit 8

    - One very important consequence of this that we need to always keep - in mind is that we shouldn't create new commits in this state. If - we do so, that new commit will point to our old commit, and our - HEAD will now point to the new - commit. + One very important consequence of this that we need to always keep in mind is that we shouldn't create new + commits in this state. If we do so, that new commit will point to our old commit, and our + HEAD will now point to the new commit.

    - But once we move our HEAD back to - the master (or any other branch), - this commit will not be reachable from any commit or pointer. It's - a dead commit. Git checks for commits like this and deletes them. - So all changes left there will be lost. + But once we move our HEAD back to the + master (or any other branch), this commit will not be reachable from any + commit or pointer. It's a dead commit. Git checks for commits like this and deletes them. So all changes + left there will be lost.

    - Checking out a commit 9 + Checking out a commit 9
    - Checking out a commit 10 + Checking out a commit 10

    - To take the HEAD back to the - master we just run + To take the HEAD back to the master we + just run

    git checkout master @@ -248,9 +177,7 @@

    Checking out a commit

    - + + diff --git a/pages/039/aborting_a_merge.html b/pages/039/aborting_a_merge.html index e6d7135..52769ae 100644 --- a/pages/039/aborting_a_merge.html +++ b/pages/039/aborting_a_merge.html @@ -1,16 +1,14 @@ + - + Aborting a merge +
    @@ -46,9 +44,7 @@

    Aborting a merge

    - + + diff --git a/pages/081/executable_files.html b/pages/081/executable_files.html index 127c4e9..bdc46f8 100644 --- a/pages/081/executable_files.html +++ b/pages/081/executable_files.html @@ -1,16 +1,14 @@ + - + Executable files +
    @@ -41,11 +39,7 @@

    Executable files

    - Executable files 1 + Executable files 1
    @@ -53,9 +47,7 @@

    Executable files

    - + + From 2fdd5cc9716aacf7237c052e951ef580c3118695 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 15:57:26 +0200 Subject: [PATCH 15/24] Adds settings file --- .vscode/settings.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1 @@ +{} From 0e7416ce08f7aff378394f5fd64f196352fa9c3c Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 16:00:43 +0200 Subject: [PATCH 16/24] Updates pages --- pages/024/bisect.html | 116 ++++++++++++++---------------------- pages/025/contributors.html | 36 ++++------- 2 files changed, 57 insertions(+), 95 deletions(-) diff --git a/pages/024/bisect.html b/pages/024/bisect.html index 134664b..be93d0e 100644 --- a/pages/024/bisect.html +++ b/pages/024/bisect.html @@ -1,16 +1,14 @@ + - + Bisect +
    @@ -32,18 +30,15 @@

    Bisect

    - Suppose our project looks like the one on the right and we found a - bug we didn't know existed or what caused it. We could check every - single commit one-by-one until we find it, but that is - time-consuming. bisect is a Git - tool for finding bugs in our code. + Suppose our project looks like the one on the right and we found a bug we didn't know existed or what + caused it. We could check every single commit one-by-one until we find it, but that is time-consuming. + bisect is a Git tool for finding bugs in our code.


    - In a nutshell, it works by doing a binary search throughout our - repository. We'll tell Git of a good commit, and a - bad commit and Git will help us zero-in the commit that - caused the bug so that we can fix it. + In a nutshell, it works by doing a binary search throughout our repository. We'll tell Git of a + good commit, and a bad commit and Git will help us zero-in the commit that caused the + bug so that we can fix it.

    @@ -53,10 +48,9 @@

    Bisect

    - So, imagine 8eec1d2 (our - HEAD) is a bad commit (we found a - bug here), and ca49180 (our initial commit) will be our - first good commit (a commit that we know did not have the issue). + So, imagine 8eec1d2 (our HEAD) is a bad commit (we found a bug + here), and ca49180 (our initial commit) will be our first good commit (a commit that we know did + not have the issue).


    @@ -66,31 +60,25 @@

    Bisect

    git bisect start

    - Notice that Git Bash changed from - (master) to - (master | BISECTING). Right now our - HEAD is at the bad commit (the - last one), so we need to tell Git that this is a bad commit. To do - that, we run + Notice that Git Bash changed from (master) to + (master | BISECTING). Right now our HEAD is + at the bad commit (the last one), so we need to tell Git that this is a bad commit. To do that, we run

    git bisect bad

    - Now we need to give Git a good commit. If you didn't write down - the hash for a good commit before starting the - bisect process don't worry, you - can run git log --oneline and get - it now. So we run + Now we need to give Git a good commit. If you didn't write down the hash for a good commit before starting + the bisect process don't worry, you can run + git log --oneline and get it now. So we run

    git bisect good ca49180

    - Now Git is telling us that we have 7 revisions left (7 commits to - check instead of the total 16), and it's also telling us that we - can get it done in 3 steps. Notice that Git Bash changed again and - is not at commit 24e86ee anymore. + Now Git is telling us that we have 7 revisions left (7 commits to check instead of the total 16), and it's + also telling us that we can get it done in 3 steps. Notice that Git Bash changed again and is not at + commit 24e86ee anymore.

    @@ -100,21 +88,14 @@

    Bisect

    - If we now run - git log --oneline --all we see - that master is at the top and it's - referenced as a bad commit. At the bottom of the log, we see that - there's a second reference for our bad commit. Our - HEAD is at commit 24e86ee. - This means that our working directory has been restored to this - point in time. Therefore, we can test and see if the bug is here - already. If it is, that means that the bug was introduced - somewhere between ca49180 and - HEAD. If it is not, then the bug was - introduced somewhere between - HEAD and - master. Either way, we eliminated - half of all possible commits in one try. + If we now run git log --oneline --all we see that + master is at the top and it's referenced as a bad commit. At the bottom of + the log, we see that there's a second reference for our bad commit. Our HEAD + is at commit 24e86ee. This means that our working directory has been restored to this point in + time. Therefore, we can test and see if the bug is here already. If it is, that means that the bug was + introduced somewhere between ca49180 and HEAD. If it is not, then + the bug was introduced somewhere between HEAD and + master. Either way, we eliminated half of all possible commits in one try.


    For this demo, let's tell Git that this is a good commit

    @@ -129,44 +110,39 @@

    Bisect

    - Now Git is telling us that there are 3 revisions left and that it - will take 2 steps to inspect them. Our - HEAD has now moved to commit - 50db987. If we look at the log again, we see that it has - moved up. Our repository has once again been checked out to this - commit. So we can test our application here and see if the bug is - there or not. Again for this demo, we'll tell Git that this is a - good commit. So again we run + Now Git is telling us that there are 3 revisions left and that it will take 2 steps to inspect them. Our + HEAD has now moved to commit 50db987. If we look at the log again, + we see that it has moved up. Our repository has once again been checked out to this commit. So we can test + our application here and see if the bug is there or not. Again for this demo, we'll tell Git that this is + a good commit. So again we run

    git bisect good

    - And we'll do it one more time so that it moves to the commit prior - to master. + And we'll do it one more time so that it moves to the commit prior to + master.

    - Now we are at commit e22efe7 and suppose that we found - the bug here. We'll tell Git that this is a bad commit + Now we are at commit e22efe7 and suppose that we found the bug here. We'll tell Git that this is + a bad commit

    git bisect bad

    - Now Git knows which one was the first bad commit and it's giving - us all the information about that commit: author, date, a summary - of changes. + Now Git knows which one was the first bad commit and it's giving us all the information about that commit: + author, date, a summary of changes.


    - Now we can inspect and test our code here and find the bug. Once - we know how to fix it, we can move our - HEAD back to - master and implement the fix. + Now we can inspect and test our code here and find the bug. Once we know how to fix it, we can move our + HEAD back to master and implement the + fix.

    git bisect reset @@ -181,9 +157,7 @@

    Bisect

    - + + diff --git a/pages/025/contributors.html b/pages/025/contributors.html index ff28645..2dcb8bb 100644 --- a/pages/025/contributors.html +++ b/pages/025/contributors.html @@ -1,16 +1,14 @@ + - + Contributors +
    @@ -32,35 +30,27 @@

    Contributors

    - If we want find all the people who have contributed to our project - we use, + If we want find all the people who have contributed to our project we use,

    git shortlog

    - This command can take several options. For example, - -n will sort the output according - to the number of commits, -s will - suppress commit descriptions, - -e will show the contributors’ - email address, etc. You can check the entire list by running + This command can take several options. For example, -n will sort the + output according to the number of commits, -s will suppress commit + descriptions, -e will show the contributors' email address, etc. You can + check the entire list by running

    git shortlog -h

    - We can also filter the output using the - --before and + We can also filter the output using the --before and --after options.

    - Contributors 1 + Contributors 1
    @@ -68,9 +58,7 @@

    Contributors

    - + + From bb0b1e9ecaa8d6b4d3dc6f2bc2eac679efdd115c Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 19:40:23 +0200 Subject: [PATCH 17/24] Removes netlify batch --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 627247a..735e9f1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ # Notes on Git and GitHub -[![Netlify Status](https://api.netlify.com/api/v1/badges/acc2c4d6-8f51-4092-8a87-5defa52f7e54/deploy-status)](https://app.netlify.com/sites/notes-on-git-and-github/deploys) - Personal notes on what I've learned so far about the use of Git and GitHub. Use at your own risk. Issues and PRs welcome! From 9e5872f457e2458e93a5f0aff9c456743f9b2f8f Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 19:52:30 +0200 Subject: [PATCH 18/24] Update pages --- pages/026/viewing_the_history_of_a_file.html | 21 +- pages/027/restoring_a_deleted_file.html | 20 +- pages/028/blaming.html | 14 +- pages/029/tagging.html | 14 +- pages/030/what_are_branches.html | 26 +-- pages/031/working_with_branches.html | 32 +-- pages/032/comparing_branches.html | 26 +-- pages/033/stashing.html | 20 +- pages/034/merging.html | 14 +- pages/035/fast_forward_merging.html | 32 +-- pages/036/three_way_merges.html | 26 +-- pages/037/viewing_branches.html | 14 +- pages/038/merge_conflicts.html | 45 +---- pages/040/undoing_a_merge.html | 191 ++++++------------ pages/041/squash_merging.html | 93 +++------ pages/042/rebasing.html | 45 ++--- pages/043/cherry_picking.html | 42 +--- .../picking_a_file_from_another_branch.html | 21 +- pages/045/collaboration_workflows.html | 37 +--- pages/046/creating_a_github_repository.html | 38 +--- pages/047/cloning_a_repository.html | 44 +--- pages/048/fetching.html | 14 +- pages/049/pulling.html | 14 +- pages/050/pushing.html | 14 +- pages/051/storing_credentials.html | 14 +- pages/052/sharing_tags.html | 20 +- pages/053/releases.html | 26 +-- pages/054/sharing_branches.html | 66 ++---- pages/055/pull_requests.html | 98 ++------- pages/056/github_issues.html | 68 ++----- pages/057/forks.html | 14 +- pages/058/rewriting_history.html | 21 +- pages/059/undoing_commits.html | 38 +--- pages/060/reverting_commits.html | 32 +-- pages/061/recovering_commits.html | 32 +-- pages/062/amending_last_commit.html | 32 +-- pages/063/amending_earlier_commits.html | 44 +--- pages/064/dropping_commits.html | 44 +--- pages/065/rewording_commits.html | 38 +--- pages/066/reordering_commits.html | 32 +-- pages/067/squashing_commits.html | 56 ++--- pages/068/splitting_a_commit.html | 44 +--- pages/069/introduction_to_github_actions.html | 42 ++-- pages/070/triggers.html | 63 ++---- pages/071/shells.html | 14 +- pages/072/running_jobs_in_series.html | 26 +-- pages/073/actions.html | 14 +- pages/074/the_checkout_action.html | 20 +- pages/075/environment_variables.html | 52 ++--- pages/076/expressions_and_contexts.html | 87 +++----- pages/077/continue_on_error.html | 20 +- pages/078/timeout_minutes.html | 20 +- pages/079/matrix_and_strategy.html | 32 +-- pages/080/docker.html | 14 +- pages/082/building_github_actions.html | 20 +- pages/083/javascript_actions.html | 26 +-- pages/084/github_toolkit.html | 72 ++----- pages/085/docker_actions.html | 45 +---- 58 files changed, 574 insertions(+), 1569 deletions(-) diff --git a/pages/026/viewing_the_history_of_a_file.html b/pages/026/viewing_the_history_of_a_file.html index 4e9284e..55708cd 100644 --- a/pages/026/viewing_the_history_of_a_file.html +++ b/pages/026/viewing_the_history_of_a_file.html @@ -1,16 +1,14 @@ + - + Viewing the history of a file +
    @@ -48,11 +46,8 @@

    Viewing the history of a file

    - Viewing the history of a file 1 + Viewing the history of a file 1
    @@ -60,9 +55,7 @@

    Viewing the history of a file

    - + + diff --git a/pages/027/restoring_a_deleted_file.html b/pages/027/restoring_a_deleted_file.html index e168297..b0f5a0f 100644 --- a/pages/027/restoring_a_deleted_file.html +++ b/pages/027/restoring_a_deleted_file.html @@ -1,16 +1,14 @@ + - + Restoring a deleted file +
    @@ -60,11 +58,7 @@

    Restoring a deleted file

    - Restoring a deleted file 1 + Restoring a deleted file 1
    @@ -72,9 +66,7 @@

    Restoring a deleted file

    - + + diff --git a/pages/028/blaming.html b/pages/028/blaming.html index 485d8e4..bd7d416 100644 --- a/pages/028/blaming.html +++ b/pages/028/blaming.html @@ -1,16 +1,14 @@ + - + Blaming +
    @@ -66,9 +64,7 @@

    Blaming

    - + + diff --git a/pages/029/tagging.html b/pages/029/tagging.html index b76e0e5..598469b 100644 --- a/pages/029/tagging.html +++ b/pages/029/tagging.html @@ -1,16 +1,14 @@ + - + Tagging +
    @@ -151,9 +149,7 @@

    Tagging

    - + + diff --git a/pages/030/what_are_branches.html b/pages/030/what_are_branches.html index 7a85e49..a95149f 100644 --- a/pages/030/what_are_branches.html +++ b/pages/030/what_are_branches.html @@ -1,16 +1,14 @@ + - + What are branches? +
    @@ -46,20 +44,12 @@

    What are branches?

    - What are branches 1 + What are branches 1
    - What are branches 2 + What are branches 2

    @@ -74,9 +64,7 @@

    What are branches?

    - + + diff --git a/pages/031/working_with_branches.html b/pages/031/working_with_branches.html index d88246f..76acd83 100644 --- a/pages/031/working_with_branches.html +++ b/pages/031/working_with_branches.html @@ -1,16 +1,14 @@ + - + Working with branches +
    @@ -58,20 +56,12 @@

    Working with branches

    - Working with branches 1 + Working with branches 1
    - Working with branches 2 + Working with branches 2

    @@ -107,11 +97,7 @@

    Working with branches

    - Working with branches 3 + Working with branches 3
    @@ -119,9 +105,7 @@

    Working with branches

    - + + diff --git a/pages/032/comparing_branches.html b/pages/032/comparing_branches.html index 3d191ce..2b564f3 100644 --- a/pages/032/comparing_branches.html +++ b/pages/032/comparing_branches.html @@ -1,16 +1,14 @@ + - + Comparing branches +
    @@ -47,20 +45,12 @@

    Comparing branches

    - Comparing branches 1 + Comparing branches 1
    - Comparing branches 2 + Comparing branches 2

    @@ -99,9 +89,7 @@

    Comparing branches

    - + + diff --git a/pages/033/stashing.html b/pages/033/stashing.html index 8fde019..98b1a0a 100644 --- a/pages/033/stashing.html +++ b/pages/033/stashing.html @@ -1,16 +1,14 @@ + - + Stashing +
    @@ -96,10 +94,8 @@

    Stashing

    stash from where it can access that new commit (technically there are several commits involved depending on what we are stashing, you can read all about it - + here ). @@ -229,9 +225,7 @@

    Stashing

    - + + diff --git a/pages/034/merging.html b/pages/034/merging.html index 5cbc81b..33a895a 100644 --- a/pages/034/merging.html +++ b/pages/034/merging.html @@ -1,16 +1,14 @@ + - + Merging +
    @@ -89,9 +87,7 @@

    Merging

    - + + diff --git a/pages/035/fast_forward_merging.html b/pages/035/fast_forward_merging.html index 3f16510..6986092 100644 --- a/pages/035/fast_forward_merging.html +++ b/pages/035/fast_forward_merging.html @@ -1,16 +1,14 @@ + - + Fast-forward merging +
    @@ -42,20 +40,12 @@

    Fast-forward merging

    - Fast-forward merging 1 + Fast-forward merging 1
    - Fast-forward merging 2 + Fast-forward merging 2

    @@ -103,11 +93,7 @@

    Fast-forward merging

    - Fast-forward merging 3 + Fast-forward merging 3
    @@ -128,9 +114,7 @@

    Fast-forward merging

    - + + diff --git a/pages/036/three_way_merges.html b/pages/036/three_way_merges.html index d578dc2..ae9d7d6 100644 --- a/pages/036/three_way_merges.html +++ b/pages/036/three_way_merges.html @@ -1,16 +1,14 @@ + - + Three-way merging +
    @@ -67,20 +65,12 @@

    Three-way merging

    - Three-way merges 1 + Three-way merges 1
    - Three-way merges 2 + Three-way merges 2

    @@ -120,9 +110,7 @@

    Three-way merging

    - + + diff --git a/pages/037/viewing_branches.html b/pages/037/viewing_branches.html index 426a10b..e7e7e07 100644 --- a/pages/037/viewing_branches.html +++ b/pages/037/viewing_branches.html @@ -1,16 +1,14 @@ + - + Viewing merged and unmerged branches +
    @@ -59,9 +57,7 @@

    Viewing merged and unmerged branches

    - + + diff --git a/pages/038/merge_conflicts.html b/pages/038/merge_conflicts.html index 2d0d8f0..fd4cbce 100644 --- a/pages/038/merge_conflicts.html +++ b/pages/038/merge_conflicts.html @@ -1,16 +1,14 @@ + - + Merge conflicts +
    @@ -87,20 +85,12 @@

    Merge conflicts

    - Merge conflicts 1 + Merge conflicts 1
    - Merge conflicts 2 + Merge conflicts 2

    First, let's run

    @@ -130,21 +120,12 @@

    Merge conflicts

    - Merge conflicts 3 + Merge conflicts 3
    - Merge conflicts 4 + Merge conflicts 4

    @@ -211,11 +192,7 @@

    Merge conflicts

    - Merge conflicts 5 + Merge conflicts 5
    @@ -236,9 +213,7 @@

    Merge conflicts

    - + + diff --git a/pages/040/undoing_a_merge.html b/pages/040/undoing_a_merge.html index aee2ac1..70182d0 100644 --- a/pages/040/undoing_a_merge.html +++ b/pages/040/undoing_a_merge.html @@ -1,16 +1,14 @@ + - + Undoing a merge +
    @@ -32,50 +30,36 @@

    Undoing a merge

    - Sometimes we do a merge and realize that our program stopped - working and we want to undo it. Here we have two options: 1) - undoing the commit as if it had never been there (called - resetting), 2) create a new commit that cancels out all the - changes in our merge commit (called reverting). + Sometimes we do a merge and realize that our program stopped working and we want to undo it. Here we have + two options: 1) undoing the commit as if it had never been there (called resetting), 2) create a new + commit that cancels out all the changes in our merge commit (called reverting).


    - When resetting we have to be very careful because we are - re-writing history. If the changes only exist on our local - repository that is OK. But if we have already shared the changes - with the rest of our team we should - NEVER re-write history. + When resetting we have to be very careful because we are re-writing history. If the changes only exist on + our local repository that is OK. But if we have already shared the changes with the rest of our team we + should NEVER re-write history.


    - The diagrams below explain the two situations. In both of them, we - begin from the same starting point: a merger commit has taken - place, merging a branch called - new-feature into - master. The difference is that when - we use reset we move the - master pointer back to its parent - commit (the commit with a red border that is before the merge - commit, and in the master branch). - Because there are now no commits or pointers pointing to our - merger commit, Git will Garbage Collect this commit and - throw it away. + The diagrams below explain the two situations. In both of them, we begin from the same starting point: a + merger commit has taken place, merging a branch called new-feature into + master. The difference is that when we use reset we move the + master pointer back to its parent commit (the commit with a red border that + is before the merge commit, and in the master branch). Because there are + now no commits or pointers pointing to our merger commit, Git will Garbage Collect this commit + and throw it away.


    - On the other hand, when we use a revert we are creating a - new commit that comes after the merge commit, and moving the - HEAD pointer onto this new commit - (shown in blue with white border on the diagram). This commit - makes all the opposite changes as those that were done on the - merge commit. One thing to consider when reverting mergers is that - the merge commit actually has two parent commits: one on - master and one on - new-feature. We'll have to specify - Git which commit to revert to and, since we'll do it from the - master branch (because it's the - branch that was modified with the merger), we'll revert to the - parent commit on this branch. + On the other hand, when we use a revert we are creating a new commit that comes after the merge + commit, and moving the HEAD pointer onto this new commit (shown in blue + with white border on the diagram). This commit makes all the opposite changes as those that were done on + the merge commit. One thing to consider when reverting mergers is that the merge commit actually has two + parent commits: one on master and one on + new-feature. We'll have to specify Git which commit to revert to and, since + we'll do it from the master branch (because it's the branch that was + modified with the merger), we'll revert to the parent commit on this branch.

    @@ -83,32 +67,16 @@

    Undoing a merge

    - Undoing a merge 1 + Undoing a merge 1
    - Undoing a merge 2 + Undoing a merge 2
    - Undoing a merge 3 + Undoing a merge 3
    - Undoing a merge 4 + Undoing a merge 4
    @@ -116,110 +84,80 @@

    Undoing a merge

    - Before we start with an example, let's take a look at our log. - We'll do both operations on commit 3a485a4, which is our - last merge commit. Before starting an operation like this, it's - always recommended that you write down the ID for the commit you - are going to revert or reset. You can delete it once done. + Before we start with an example, let's take a look at our log. We'll do both operations on commit + 3a485a4, which is our last merge commit. Before starting an operation like this, it's always + recommended that you write down the ID for the commit you are going to revert or reset. You can delete it + once done.

    - Undoing a merge 5 + Undoing a merge 5

    - We'll start with the reset option. But before we do we - need to clarify some terminology. The - git reset command has three - options: + We'll start with the reset option. But before we do we need to clarify some terminology. The + git reset command has three options:

    • - --soft: Git will have our - repository point to a different commit, but our index and - working tree will not be affected. + --soft: Git will have our repository point to a different commit, but + our index and working tree will not be affected.
    • - --mixed: Git will take the new - snapshot and put it in the index as well. This is the default - option so we don't need to specify it. + --mixed: Git will take the new snapshot and put it in the index as + well. This is the default option so we don't need to specify it.
    • - --hard: Git will take the new - snapshot and copy it to both the index and the working tree. - This means that all environments will look the same. It also - means that all local changes in our working-tree will be lost, - so make sure to stash them before resetting. + --hard: Git will take the new snapshot and copy it to both the index + and the working tree. This means that all environments will look the same. It also means that all local + changes in our working-tree will be lost, so make sure to stash them before resetting.
    - Undoing a merge 6 + Undoing a merge 6

    - To reset our repository, index, and working tree in the - master branch to the commit previous - to the merge we run + To reset our repository, index, and working tree in the master branch to the + commit previous to the merge we run

    git reset --hard HEAD~1

    - We can see that both HEAD and - master are now at commit - b03190d, and the merge commit has disappeared from our - tree. The commit is still in our repository thou, and we can - recover it (until the Garbage Collector takes it away for - good). + We can see that both HEAD and master are now + at commit b03190d, and the merge commit has disappeared from our tree. The commit is still in our + repository thou, and we can recover it (until the Garbage Collector takes it away for good).

    - If we want to reset to the point before resetting (i.e. a point - where the merge is still there) we run + If we want to reset to the point before resetting (i.e. a point where the merge is still there) we run

    git reset --hard 3a485a4

    - We can now check our log and see that our merge commit is back. - Keep in mind that if you close Git Bash, the - Garbage Collector will be run and the commit will be lost - forever. + We can now check our log and see that our merge commit is back. Keep in mind that if you close Git Bash, + the Garbage Collector will be run and the commit will be lost forever.

    - Undoing a merge 7 + Undoing a merge 7
    - Undoing a merge 8 + Undoing a merge 8

    Now let's take a look at reverting. To do so we run

    @@ -227,22 +165,19 @@

    Undoing a merge

    git revert -m 1 HEAD

    - Here we are telling Git that it should revert the - HEAD pointer to the previous - commit on the master branch. The - -m 1 means - first parent commit. + Here we are telling Git that it should revert the HEAD pointer to the + previous commit on the master branch. The + -m 1 means first parent commit.


    - Git will open VS Code so that we can edit our message, but here - we'll accept the default and close it. When we do, Git will - complete the reverting process. + Git will open VS Code so that we can edit our message, but here we'll accept the default and close it. + When we do, Git will complete the reverting process.


    - We can check our log now and see that a new commit has been added - and its message says that it has reverted the merge. + We can check our log now and see that a new commit has been added and its message says that it has + reverted the merge.

    @@ -251,9 +186,7 @@

    Undoing a merge

    - + + diff --git a/pages/041/squash_merging.html b/pages/041/squash_merging.html index c776727..85ff6c6 100644 --- a/pages/041/squash_merging.html +++ b/pages/041/squash_merging.html @@ -1,16 +1,14 @@ + - + Squash merging +
    @@ -32,66 +30,46 @@

    Squash merging

    - Suppose we have a branch called - bugfix where we fixed a bug in a - hurry. In this branch, we did two commits: B1 and - B2. But because we were in a hurry, these are not very - good commits. So now we need to merge them into - master but instead of using a - three-way merge, we are going to create a squash merge. - In this type of merge, we create a new commit which is the - combination of all the commits in our branch but has no ancestry - to the tip of the branch (in this example, commit B2). + Suppose we have a branch called bugfix where we fixed a bug in a hurry. In + this branch, we did two commits: B1 and B2. But because we were in a hurry, these are + not very good commits. So now we need to merge them into master but instead + of using a three-way merge, we are going to create a squash merge. In this type of merge, we + create a new commit which is the combination of all the commits in our branch but has no ancestry to the + tip of the branch (in this example, commit B2).


    - Once we squash merge we can (and should) delete the - bugfix branch. Though this technique - produces clean linear histories on the - master branch, it should only be - used for short-lived branches with small changes and dirty commit - histories. + Once we squash merge we can (and should) delete the bugfix branch. Though + this technique produces clean linear histories on the master branch, it + should only be used for short-lived branches with small changes and dirty commit histories.

    - Squash merging 1 + Squash merging 1
    - Squash merging 2 + Squash merging 2

    - As an example, let's create a new branch called - bugfix. In this branch, we'll create - two new commits, one that modifies audience.txt and one - that modifies toc.txt. + As an example, let's create a new branch called bugfix. In this branch, + we'll create two new commits, one that modifies audience.txt and one that modifies + toc.txt.


    - Now we switch onto the - master branch. In order to merge the - bugfix branch onto - master, we run + Now we switch onto the master branch. In order to merge the + bugfix branch onto master, we run

    git merge --squash bugfix

    - If we check the status of our repository we see that our changes - are now available on master, but - they are not committed. We need to create a commit with these + If we check the status of our repository we see that our changes are now available on + master, but they are not committed. We need to create a commit with these changes, and give it a meaningful message that explains the merge.

    @@ -99,29 +77,20 @@

    Squash merging

    - If we check the log now, we will see that our - bugfix branch has two commits: - 3accc2f and 2de4c95. Our - master branch is at commit - 6166e28 which is our squash merge commit, but this commit - is not connected to the tip of the + If we check the log now, we will see that our bugfix branch has two commits: + 3accc2f and 2de4c95. Our master branch is at commit + 6166e28 which is our squash merge commit, but this commit is not connected to the tip of the bugfix branch.


    - Since the branch was not merged on to - master, it is very important that we - delete it. Otherwise, it will cause confusion in the future once - we have moved on from this bug and no one even remembers what that - branch was supposed to do. + Since the branch was not merged on to master, it is very important that we + delete it. Otherwise, it will cause confusion in the future once we have moved on from this bug and no one + even remembers what that branch was supposed to do.

    - Squash merging 3 + Squash merging 3
    @@ -129,9 +98,7 @@

    Squash merging

    - + + diff --git a/pages/042/rebasing.html b/pages/042/rebasing.html index 216ec05..b69df75 100644 --- a/pages/042/rebasing.html +++ b/pages/042/rebasing.html @@ -1,16 +1,14 @@ + - + Rebasing +
    @@ -39,11 +37,10 @@

    Rebasing

    commit of a branch (that is the parent commit of F1). The problem with rebasing is that this is not true. Commits are immutable. So what Git actually does is to create new commits (in - this example, F1* and F2*) that come after the + this example, F1* and F2*) that come after the master pointer, and moves the branch - pointer from F2 to F2*. Now there are no pointers or commits pointing to F2 so + pointer from F2 to F2*. Now there are no pointers or commits pointing to + F2 so Git will delete them on the next Garbage Collection cycle. This might be OK if this branch is local (only you have it on your computer), but if other people @@ -59,32 +56,16 @@

    Rebasing

    Rebasing

    - Rebasing 1 + Rebasing 1
    - Rebasing 2 + Rebasing 2
    - Rebasing 3 + Rebasing 3
    - Rebasing 4 + Rebasing 4
    @@ -246,9 +227,7 @@

    Rebasing

    - + + diff --git a/pages/043/cherry_picking.html b/pages/043/cherry_picking.html index 97e3251..53530f0 100644 --- a/pages/043/cherry_picking.html +++ b/pages/043/cherry_picking.html @@ -1,16 +1,14 @@ + - + Cherry picking +
    @@ -49,18 +47,10 @@

    Cherry picking

    Cherry-picking

    - Cherry-picking 1 + Cherry-picking 1
    - Cherry-picking 2 + Cherry-picking 2
    @@ -70,9 +60,7 @@

    Cherry picking

    As an example, take a look at the git log. Here I've added two - commits to the feature branch (f88ecdc + commits to the feature branch (f88ecdc and fc6e687), and one commit to the master branch (88c4524). Now suppose that we want to get the changes made in commit @@ -90,20 +78,12 @@

    Cherry picking

    - Cherry-picking 3 + Cherry-picking 3
    - Cherry-picking 4 + Cherry-picking 4

    @@ -129,9 +109,7 @@

    Cherry picking

    - + + diff --git a/pages/044/picking_a_file_from_another_branch.html b/pages/044/picking_a_file_from_another_branch.html index 64c8201..efcb806 100644 --- a/pages/044/picking_a_file_from_another_branch.html +++ b/pages/044/picking_a_file_from_another_branch.html @@ -1,16 +1,14 @@ + - + Picking a file from another branch +
    @@ -53,11 +51,8 @@

    Picking a file from another branch

    - Picking a file from another branch 1 + Picking a file from another branch 1
    @@ -65,9 +60,7 @@

    Picking a file from another branch

    - + + diff --git a/pages/045/collaboration_workflows.html b/pages/045/collaboration_workflows.html index 95df9ac..211b171 100644 --- a/pages/045/collaboration_workflows.html +++ b/pages/045/collaboration_workflows.html @@ -1,24 +1,19 @@ + - + Collaboration workflows +
    @@ -82,16 +77,10 @@

    Collaboration workflows

    - +
    - +
    @@ -141,12 +130,8 @@

    Collaboration workflows

    - Collaboration workflows 3 + Collaboration workflows 3
    @@ -154,9 +139,7 @@

    Collaboration workflows

    - + + diff --git a/pages/046/creating_a_github_repository.html b/pages/046/creating_a_github_repository.html index c33cec9..7ba7c80 100644 --- a/pages/046/creating_a_github_repository.html +++ b/pages/046/creating_a_github_repository.html @@ -1,16 +1,14 @@ + - + Creating a GitHub repository +
    @@ -45,29 +43,17 @@

    Creating a GitHub repository

    To create a new repository on GitHub, login, and on the home page click the - New button + New button icon on the left-hand side panel.

    - Creating a GitHub repository 1 + Creating a GitHub repository 1
    - Creating a GitHub repository 3 + Creating a GitHub repository 3

    @@ -122,11 +108,7 @@

    Creating a GitHub repository

    - Creating a GitHub repository 4 + Creating a GitHub repository 4
    @@ -144,9 +126,7 @@

    Creating a GitHub repository

    - + + diff --git a/pages/047/cloning_a_repository.html b/pages/047/cloning_a_repository.html index 6fda861..6a8e5a3 100644 --- a/pages/047/cloning_a_repository.html +++ b/pages/047/cloning_a_repository.html @@ -1,16 +1,14 @@ + - + Cloning a repository +
    @@ -34,29 +32,17 @@

    Cloning a repository

    To start working on our repository, we first need to clone it to our local machine. To do so, click on the - Clone repository icon + Clone repository icon button and copy the URL.

    - Cloning a repository 1 + Cloning a repository 1
    - Cloning a repository 3 + Cloning a repository 3

    Now, open the Git Bash and run

    @@ -97,11 +83,7 @@

    Cloning a repository

    - Cloning a repository 4 + Cloning a repository 4
    @@ -116,11 +98,7 @@

    Cloning a repository

    - Cloning a repository 5 + Cloning a repository 5

    You can check the list of remotes by running

    @@ -141,9 +119,7 @@

    Cloning a repository

    - + + diff --git a/pages/048/fetching.html b/pages/048/fetching.html index 21b05d0..1e1e7d8 100644 --- a/pages/048/fetching.html +++ b/pages/048/fetching.html @@ -1,16 +1,14 @@ + - + Fetching +
    @@ -144,9 +142,7 @@

    Fetching

    - + + diff --git a/pages/049/pulling.html b/pages/049/pulling.html index e6b53c1..be0ea59 100644 --- a/pages/049/pulling.html +++ b/pages/049/pulling.html @@ -1,16 +1,14 @@ + - + Pulling +
    @@ -124,9 +122,7 @@

    Pulling

    - + + diff --git a/pages/050/pushing.html b/pages/050/pushing.html index 8a99d5b..3a49335 100644 --- a/pages/050/pushing.html +++ b/pages/050/pushing.html @@ -1,16 +1,14 @@ + - + Pushing +
    @@ -98,9 +96,7 @@

    Pushing

    - + + diff --git a/pages/051/storing_credentials.html b/pages/051/storing_credentials.html index 1511cd8..a5f4605 100644 --- a/pages/051/storing_credentials.html +++ b/pages/051/storing_credentials.html @@ -1,16 +1,14 @@ + - + Storing credentials +
    @@ -51,9 +49,7 @@

    Storing credentials

    - + + diff --git a/pages/052/sharing_tags.html b/pages/052/sharing_tags.html index cf9b0db..0b489f2 100644 --- a/pages/052/sharing_tags.html +++ b/pages/052/sharing_tags.html @@ -1,16 +1,14 @@ + - + Sharing tags +
    @@ -50,11 +48,7 @@

    Sharing tags

    - Sharing tags 1 + Sharing tags 1
    @@ -62,9 +56,7 @@

    Sharing tags

    - + + diff --git a/pages/053/releases.html b/pages/053/releases.html index ed44696..5293773 100644 --- a/pages/053/releases.html +++ b/pages/053/releases.html @@ -1,16 +1,14 @@ + - + Releases +
    @@ -63,11 +61,7 @@

    Releases

    - Releases 1 + Releases 1
    @@ -87,11 +81,7 @@

    Releases

    - Releases 2 + Releases 2

    @@ -120,9 +110,7 @@

    Releases

    - + + diff --git a/pages/054/sharing_branches.html b/pages/054/sharing_branches.html index cca423f..3d665ac 100644 --- a/pages/054/sharing_branches.html +++ b/pages/054/sharing_branches.html @@ -1,16 +1,14 @@ + - + Sharing branches +
    @@ -33,9 +31,7 @@

    Sharing branches

    By default, the branches we create locally, stay local. If we try to push a local branch onto the remote repository, Git will throw an error saying that - the current branch has no upstream branch. If we run + the current branch has no upstream branch. If we run

    git branch -vv @@ -51,20 +47,12 @@

    Sharing branches

    - Sharing branches 1 + Sharing branches 1
    - Sharing branches 2 + Sharing branches 2

    @@ -108,20 +96,12 @@

    Sharing branches

    - Sharing branches 3 + Sharing branches 3
    - Sharing branches 4 + Sharing branches 4

    @@ -152,20 +132,12 @@

    Sharing branches

    - Sharing branches 5 + Sharing branches 5
    - Sharing branches 6 + Sharing branches 6

    @@ -203,20 +175,12 @@

    Sharing branches

    - Sharing branches 7 + Sharing branches 7
    - Sharing branches 8 + Sharing branches 8

    @@ -286,9 +250,7 @@

    Sharing branches

    - + + diff --git a/pages/055/pull_requests.html b/pages/055/pull_requests.html index 04397a7..cb02486 100644 --- a/pages/055/pull_requests.html +++ b/pages/055/pull_requests.html @@ -1,16 +1,14 @@ + - + Pull requests +
    @@ -53,11 +51,7 @@

    Pull requests

    - Pull requests 1 + Pull requests 1
    @@ -88,11 +82,7 @@

    Pull requests

    - Pull requests 2 + Pull requests 2
    @@ -117,11 +107,7 @@

    Pull requests

    - Pull requests 3 + Pull requests 3
    @@ -146,20 +132,12 @@

    Pull requests

    - Pull requests 4 + Pull requests 4
    - Pull requests 5 + Pull requests 5

    @@ -179,26 +157,14 @@

    Pull requests

    - Pull requests 6 + Pull requests 6
    - Pull requests 7 + Pull requests 7
    - Pull requests 8 + Pull requests 8

    @@ -227,20 +193,12 @@

    Pull requests

    - Pull requests 9 + Pull requests 9
    - Pull requests 10 + Pull requests 10

    @@ -261,20 +219,12 @@

    Pull requests

    - Pull requests 11 + Pull requests 11
    - Pull requests 12 + Pull requests 12

    @@ -309,21 +259,13 @@

    Pull requests

    - Pull requests 13 + Pull requests 13
    - Pull requests 14 + Pull requests 14

    @@ -342,9 +284,7 @@

    Pull requests

    - + + diff --git a/pages/056/github_issues.html b/pages/056/github_issues.html index cfcd880..312434e 100644 --- a/pages/056/github_issues.html +++ b/pages/056/github_issues.html @@ -1,16 +1,14 @@ + - + GitHub issues +
    @@ -44,11 +42,7 @@

    GitHub issues

    - GitHub issues 1 + GitHub issues 1
    @@ -64,27 +58,15 @@

    GitHub issues

    the issue thread.


    - GitHub issues 3 + GitHub issues 3
    - GitHub issues 2 + GitHub issues 2
    - GitHub issues 4 + GitHub issues 4

    @@ -103,11 +85,7 @@

    GitHub issues


    - GitHub issues 5 + GitHub issues 5
    @@ -133,20 +111,12 @@

    GitHub issues

    We can assign more than one label per issue.

    - GitHub issues 6 + GitHub issues 6
    - GitHub issues 7 + GitHub issues 7

    @@ -167,20 +137,12 @@

    GitHub issues

    - GitHub issues 8 + GitHub issues 8
    - GitHub issues 9 + GitHub issues 9

    @@ -194,9 +156,7 @@

    GitHub issues

    - + + diff --git a/pages/057/forks.html b/pages/057/forks.html index c0fb6af..a436f9e 100644 --- a/pages/057/forks.html +++ b/pages/057/forks.html @@ -1,16 +1,14 @@ + - + Forks +
    @@ -312,9 +310,7 @@

    Forks

    - + + diff --git a/pages/058/rewriting_history.html b/pages/058/rewriting_history.html index c90734b..31d2f0a 100644 --- a/pages/058/rewriting_history.html +++ b/pages/058/rewriting_history.html @@ -1,16 +1,14 @@ + - + Rewriting History +
    @@ -62,12 +60,7 @@

    Rewriting History

    - Rewriting history 1 + Rewriting history 1
    @@ -120,9 +113,7 @@

    Rewriting History

    - + + diff --git a/pages/059/undoing_commits.html b/pages/059/undoing_commits.html index f9680cb..e8f205b 100644 --- a/pages/059/undoing_commits.html +++ b/pages/059/undoing_commits.html @@ -1,16 +1,14 @@ + - + Undoing commits +
    @@ -41,11 +39,7 @@

    Undoing commits

    - Undoing commits 1 + Undoing commits 1
    @@ -75,11 +69,7 @@

    Undoing commits

    - Undoing commits 2 + Undoing commits 2

    @@ -118,20 +108,12 @@

    Undoing commits

    - Undoing commits 3 + Undoing commits 3
    - Undoing commits 4 + Undoing commits 4

    @@ -155,9 +137,7 @@

    Undoing commits

    - + + diff --git a/pages/060/reverting_commits.html b/pages/060/reverting_commits.html index 4055e4c..2cfefe0 100644 --- a/pages/060/reverting_commits.html +++ b/pages/060/reverting_commits.html @@ -1,16 +1,14 @@ + - + Reverting commits +
    @@ -63,20 +61,12 @@

    Reverting commits

    - Reverting commits 1 + Reverting commits 1
    - Reverting commits 2 + Reverting commits 2

    We can revert ranges of commits by running, for example

    @@ -129,11 +119,7 @@

    Reverting commits

    - Reverting commits 3 + Reverting commits 3
    @@ -141,9 +127,7 @@

    Reverting commits

    - + + diff --git a/pages/061/recovering_commits.html b/pages/061/recovering_commits.html index 7fb338f..3f78732 100644 --- a/pages/061/recovering_commits.html +++ b/pages/061/recovering_commits.html @@ -1,16 +1,14 @@ + - + Recovering commits +
    @@ -43,20 +41,12 @@

    Recovering commits

    - Recovering commits 1 + Recovering commits 1
    - Recovering commits 2 + Recovering commits 2

    To view the reflog, we run

    @@ -98,11 +88,7 @@

    Recovering commits

    - Recovering commits 3 + Recovering commits 3
    @@ -130,9 +116,7 @@

    Recovering commits

    - + + diff --git a/pages/062/amending_last_commit.html b/pages/062/amending_last_commit.html index f61ba76..8504427 100644 --- a/pages/062/amending_last_commit.html +++ b/pages/062/amending_last_commit.html @@ -1,16 +1,14 @@ + - + Amending the last commit +
    @@ -56,20 +54,12 @@

    Amending the last commit

    - Amending the last commit 1 + Amending the last commit 1
    - Amending the last commit 2 + Amending the last commit 2

    @@ -93,11 +83,7 @@

    Amending the last commit

    - Amending the last commit 3 + Amending the last commit 3
    @@ -105,9 +91,7 @@

    Amending the last commit

    - + + diff --git a/pages/063/amending_earlier_commits.html b/pages/063/amending_earlier_commits.html index 0903fa6..ce10805 100644 --- a/pages/063/amending_earlier_commits.html +++ b/pages/063/amending_earlier_commits.html @@ -1,16 +1,14 @@ + - + Amending earlier commits +
    @@ -49,11 +47,7 @@

    Amending earlier commits

    - Amending earlier commits + Amending earlier commits
    @@ -78,11 +72,7 @@

    Amending earlier commits

    - Amending earlier commits 2 + Amending earlier commits 2
    @@ -110,20 +100,12 @@

    Amending earlier commits

    just as we would if we were amending the last commit.

    - Amending earlier commits 3 + Amending earlier commits 3
    - Amending earlier commits 4 + Amending earlier commits 4

    @@ -162,11 +144,7 @@

    Amending earlier commits

    - Amending earlier commits 5 + Amending earlier commits 5
    @@ -189,9 +167,7 @@

    Amending earlier commits

    - + + diff --git a/pages/064/dropping_commits.html b/pages/064/dropping_commits.html index 0b9ebdc..e696d5c 100644 --- a/pages/064/dropping_commits.html +++ b/pages/064/dropping_commits.html @@ -1,16 +1,14 @@ + - + Dropping commits +
    @@ -67,11 +65,7 @@

    Dropping commits

    - Dropping commits 1 + Dropping commits 1
    @@ -89,20 +83,12 @@

    Dropping commits

    - Dropping commits 2 + Dropping commits 2
    - Dropping commits 3 + Dropping commits 3

    @@ -154,20 +140,12 @@

    Dropping commits

    Git takes care of rebasing all other involved commits.

    - Dropping commits 4 + Dropping commits 4
    - Dropping commits 5 + Dropping commits 5

    @@ -187,9 +165,7 @@

    Dropping commits

    - + + diff --git a/pages/065/rewording_commits.html b/pages/065/rewording_commits.html index ed9b245..66e3ad9 100644 --- a/pages/065/rewording_commits.html +++ b/pages/065/rewording_commits.html @@ -1,16 +1,14 @@ + - + Rewording commits +
    @@ -50,11 +48,7 @@

    Rewording commits

    - Rewording commits 1 + Rewording commits 1
    @@ -67,20 +61,12 @@

    Rewording commits

    - Rewording commits 2 + Rewording commits 2
    - Rewording commits 3 + Rewording commits 3

    @@ -101,11 +87,7 @@

    Rewording commits

    - Rewording commits 4 + Rewording commits 4
    @@ -113,9 +95,7 @@

    Rewording commits

    - + + diff --git a/pages/066/reordering_commits.html b/pages/066/reordering_commits.html index a580c13..0ca7d67 100644 --- a/pages/066/reordering_commits.html +++ b/pages/066/reordering_commits.html @@ -1,16 +1,14 @@ + - + Reordering commits +
    @@ -48,11 +46,7 @@

    Reordering commits

    - Reordering commits 1 + Reordering commits 1
    @@ -67,20 +61,12 @@

    Reordering commits

    - Reordering commits 2 + Reordering commits 2
    - Reordering commits 3 + Reordering commits 3

    @@ -96,9 +82,7 @@

    Reordering commits

    - + + diff --git a/pages/067/squashing_commits.html b/pages/067/squashing_commits.html index 5a9a2fa..f779a44 100644 --- a/pages/067/squashing_commits.html +++ b/pages/067/squashing_commits.html @@ -1,16 +1,14 @@ + - + Squashing commits +
    @@ -50,11 +48,7 @@

    Squashing commits

    - Squashing commits 1 + Squashing commits 1
    @@ -76,20 +70,12 @@

    Squashing commits

    - Squashing commits 2 + Squashing commits 2
    - Squashing commits 3 + Squashing commits 3

    @@ -130,20 +116,12 @@

    Squashing commits

    - Squashing commits 4 + Squashing commits 4
    - Squashing commits 5 + Squashing commits 5

    Now we use

    @@ -170,20 +148,12 @@

    Squashing commits

    - Squashing commits 6 + Squashing commits 6
    - Squashing commits 7 + Squashing commits 7

    @@ -200,9 +170,7 @@

    Squashing commits

    - + + diff --git a/pages/068/splitting_a_commit.html b/pages/068/splitting_a_commit.html index 2001b23..b26bec5 100644 --- a/pages/068/splitting_a_commit.html +++ b/pages/068/splitting_a_commit.html @@ -1,16 +1,14 @@ + - + Splitting a commit +
    @@ -45,11 +43,7 @@

    Splitting a commit

    - Splitting a commit 1 + Splitting a commit 1
    @@ -66,11 +60,7 @@

    Splitting a commit

    - Splitting a commit 2 + Splitting a commit 2
    @@ -98,20 +88,12 @@

    Splitting a commit

    - Splitting a commit 3 + Splitting a commit 3
    - Splitting a commit 4 + Splitting a commit 4

    @@ -132,11 +114,7 @@

    Splitting a commit

    - Splitting a commit 5 + Splitting a commit 5
    @@ -144,9 +122,7 @@

    Splitting a commit

    - + + diff --git a/pages/069/introduction_to_github_actions.html b/pages/069/introduction_to_github_actions.html index 327d3cc..e9f37f4 100644 --- a/pages/069/introduction_to_github_actions.html +++ b/pages/069/introduction_to_github_actions.html @@ -1,16 +1,14 @@ + - + GitHub Actions +
    @@ -84,21 +82,14 @@

    Introduction to GitHub Actions


    - Introduction to GitHub Actions 1 + Introduction to GitHub Actions 1
    - Introduction to GitHub Actions 2 + Introduction to GitHub Actions 2

    @@ -177,20 +168,13 @@

    Introduction to GitHub Actions

    - Introduction to GitHub Actions 3 + Introduction to GitHub Actions 3
    - Introduction to GitHub Actions + Introduction to GitHub Actions
    @@ -198,9 +182,7 @@

    Introduction to GitHub Actions

    - + + diff --git a/pages/070/triggers.html b/pages/070/triggers.html index 4ac5b23..f5dd338 100644 --- a/pages/070/triggers.html +++ b/pages/070/triggers.html @@ -1,16 +1,14 @@ + - + Triggers +
    @@ -39,22 +37,12 @@

    Triggers

    - Triggers 1 + Triggers 1
    - Triggers 2 + Triggers 2

    @@ -86,35 +74,22 @@

    Triggers

    - Triggers 3 + Triggers 3

    The complete list of events and activity types can be found - here. + here.


    - Triggers 4 + Triggers 4

    @@ -163,11 +138,8 @@

    Triggers

    You can find all possible patters - here. + here.

    @@ -187,12 +159,7 @@

    Triggers

    - Triggers 5 + Triggers 5
    @@ -259,9 +226,7 @@

    Triggers

    - + + diff --git a/pages/071/shells.html b/pages/071/shells.html index cb3b0a0..140fb52 100644 --- a/pages/071/shells.html +++ b/pages/071/shells.html @@ -1,16 +1,14 @@ + - + Shells +
    @@ -50,9 +48,7 @@

    Shells

    - + + diff --git a/pages/072/running_jobs_in_series.html b/pages/072/running_jobs_in_series.html index c2d5766..a6dd87c 100644 --- a/pages/072/running_jobs_in_series.html +++ b/pages/072/running_jobs_in_series.html @@ -1,16 +1,14 @@ + - + Running jobs in series +
    @@ -37,11 +35,7 @@

    Running jobs in series

    - Running jobs in series + Running jobs in series
    @@ -65,11 +59,7 @@

    Running jobs in series

    - Running jobs in series 2 + Running jobs in series 2
    @@ -77,9 +67,7 @@

    Running jobs in series

    - + + diff --git a/pages/073/actions.html b/pages/073/actions.html index ae96970..400e45b 100644 --- a/pages/073/actions.html +++ b/pages/073/actions.html @@ -1,16 +1,14 @@ + - + Actions +
    @@ -70,9 +68,7 @@

    Actions

    - + + diff --git a/pages/074/the_checkout_action.html b/pages/074/the_checkout_action.html index 11b5dd2..71fbaa4 100644 --- a/pages/074/the_checkout_action.html +++ b/pages/074/the_checkout_action.html @@ -1,16 +1,14 @@ + - + The checkout action +
    @@ -57,11 +55,7 @@

    The checkout action

    - Checkout action 1 + Checkout action 1
    @@ -69,9 +63,7 @@

    The checkout action

    - + + diff --git a/pages/075/environment_variables.html b/pages/075/environment_variables.html index bcf6084..b21233e 100644 --- a/pages/075/environment_variables.html +++ b/pages/075/environment_variables.html @@ -1,16 +1,14 @@ + - + Environment variables +
    @@ -59,11 +57,8 @@

    Environment variables


    You can see the complete list of built-in environment variables - here. + here.

    @@ -98,22 +93,14 @@

    Environment variables

    - Environment variables 1 + Environment variables 1
    - Environment variables 2 + Environment variables 2

    @@ -148,11 +135,7 @@

    Environment variables

    - Environment variables 3 + Environment variables 3
    @@ -172,11 +155,8 @@

    Environment variables

    GPG. For details on how to use this tool, refer to the encrypted secrets documentation - here. Since this files require a passphrase to be decrypted, that + here. + Since this files require a passphrase to be decrypted, that passphrase needs to be added as a repository secret. And since the encrypted file itself needs to be available in the runner, workflows that require them must first include a checkout step. @@ -185,11 +165,7 @@

    Environment variables

    - Environment variables 4 + Environment variables 4
    @@ -197,9 +173,7 @@

    Environment variables

    - + + diff --git a/pages/076/expressions_and_contexts.html b/pages/076/expressions_and_contexts.html index 2574b54..5955be9 100644 --- a/pages/076/expressions_and_contexts.html +++ b/pages/076/expressions_and_contexts.html @@ -1,16 +1,14 @@ + - + Expressions and contexts +
    @@ -35,24 +33,16 @@

    Expressions and contexts

    - We've been using the ${{ }} syntax. Whatever we write - inside the ${{ }} is called an expression. These - expressions can be anything that needs to be evaluated, included - literals like numbers, booleans, strings, and even operators (=, - >, &ge, <, &le). + We've been using the ${{ }} syntax. Whatever we write inside the ${{ }} is called an + expression. These expressions can be anything that needs to be evaluated, included literals like + numbers, booleans, strings, and even operators (=, >, &ge, <, &le).


    - Objects that contain some information about the workflow are - called contexts. For example, the github context - contains information about the GitHub repository, the - secrets context contains all repository secrets. You can - find all the contexts - here. + Objects that contain some information about the workflow are called contexts. For example, the + github context contains information about the GitHub repository, the secrets context + contains all repository secrets. You can find all the contexts + here.

    @@ -61,24 +51,16 @@

    Expressions and contexts

    - GitHub comes with a list of functions for some basic operations. - Expressions can be GitHub functions. You can find the complete - list of available functions - here. + GitHub comes with a list of functions for some basic operations. Expressions can be GitHub functions. You + can find the complete list of available functions + here.

    - Expressions and contexts 1 + Expressions and contexts 1
    @@ -86,42 +68,31 @@

    Expressions and contexts

    - One group of GitHub functions that are particularly useful are the - Job status functions. These return information on what - the status of a job is (at the moment of their invocation). They - are commonly used with the if key. This will cause the - steps in the job (or a certain step) to only run if a certain - expression evaluates to true (like, for example, a previous job - being successful). GitHub will treat anything in the - if key as an expression already, so we don't need to use - the ${{ }} syntax. + One group of GitHub functions that are particularly useful are the Job status functions. These + return information on what the status of a job is (at the moment of their invocation). They are commonly + used with the if key. This will cause the steps in the job (or a certain step) to only run if a + certain expression evaluates to true (like, for example, a previous job being successful). GitHub will + treat anything in the if key as an expression already, so we don't need to use the + ${{ }} syntax.


    - The default Job check status is - success() and it will be applied - unless other functions are specified. + The default Job check status is success() and it will be applied unless + other functions are specified.

    - Expressions and contexts + Expressions and contexts

    You can find all Job status functions - here. + here.

    @@ -130,9 +101,7 @@

    Expressions and contexts

    - + + diff --git a/pages/077/continue_on_error.html b/pages/077/continue_on_error.html index c97e0e7..43a1595 100644 --- a/pages/077/continue_on_error.html +++ b/pages/077/continue_on_error.html @@ -1,16 +1,14 @@ + - + Continue on error +
    @@ -44,11 +42,7 @@

    Continue on error

    - Continue on error 1 + Continue on error 1
    @@ -56,9 +50,7 @@

    Continue on error

    - + + diff --git a/pages/078/timeout_minutes.html b/pages/078/timeout_minutes.html index 4f3f551..ba0033b 100644 --- a/pages/078/timeout_minutes.html +++ b/pages/078/timeout_minutes.html @@ -1,16 +1,14 @@ + - + Timeout minutes +
    @@ -44,11 +42,7 @@

    Timeout minutes

    - Timeout minutes 1 + Timeout minutes 1
    @@ -56,9 +50,7 @@

    Timeout minutes

    - + + diff --git a/pages/079/matrix_and_strategy.html b/pages/079/matrix_and_strategy.html index 0e4b081..cb5ff86 100644 --- a/pages/079/matrix_and_strategy.html +++ b/pages/079/matrix_and_strategy.html @@ -1,16 +1,14 @@ + - + Matrix and strategy +
    @@ -67,20 +65,12 @@

    Matrix and strategy

    - Matrix and strategy 1 + Matrix and strategy 1
    - Matrix and strategy 2 + Matrix and strategy 2

    @@ -101,11 +91,7 @@

    Matrix and strategy

    - Matrix and strategy 3 + Matrix and strategy 3
    @@ -113,9 +99,7 @@

    Matrix and strategy

    - + + diff --git a/pages/080/docker.html b/pages/080/docker.html index 33e208c..c7bc0db 100644 --- a/pages/080/docker.html +++ b/pages/080/docker.html @@ -1,16 +1,14 @@ + - + Docker +
    @@ -79,9 +77,7 @@

    Docker

    - + + diff --git a/pages/082/building_github_actions.html b/pages/082/building_github_actions.html index d7834ad..46a3de4 100644 --- a/pages/082/building_github_actions.html +++ b/pages/082/building_github_actions.html @@ -1,16 +1,14 @@ + - + Building GitHub Actions +
    @@ -47,11 +45,7 @@

    Building GitHub Actions

    - Building GitHub Actions 1 + Building GitHub Actions 1
    @@ -59,9 +53,7 @@

    Building GitHub Actions

    - + + diff --git a/pages/083/javascript_actions.html b/pages/083/javascript_actions.html index 129e48b..1f9872a 100644 --- a/pages/083/javascript_actions.html +++ b/pages/083/javascript_actions.html @@ -1,16 +1,14 @@ + - + JavaScript actions +
    @@ -32,11 +30,7 @@

    JavaScript actions

    - JavaScript actions 1 + JavaScript actions 1

    @@ -90,11 +84,7 @@

    JavaScript actions

    - JavaScript actions 2 + JavaScript actions 2
    @@ -102,9 +92,7 @@

    JavaScript actions

    - + + diff --git a/pages/084/github_toolkit.html b/pages/084/github_toolkit.html index 5fb0786..12f0dc6 100644 --- a/pages/084/github_toolkit.html +++ b/pages/084/github_toolkit.html @@ -1,16 +1,14 @@ + - + GitHub toolkit +
    @@ -33,9 +31,7 @@

    GitHub toolkit

    GitHub provides a - toolkit + toolkit to help facilitate building actions that we can use. This toolkit is composed of several packages, each specialized in one group of tools. @@ -43,89 +39,53 @@

    GitHub toolkit

    • The - core + core package provides functions for inputs, outputs, results, logging, secrets, and variables.
    • The - exec + exec package provides functions to execute CLI tools and process output.
    • The - glob + glob package provides functions to search for files matching glob patterns.
    • The - http-client + http-client package provides a lightweight HTTP client optimized for building actions.
    • The - io + io package provides disk i/o functions (like cp, mv, rmRF, which, etc).
    • The - tool-cache + tool-cache package provides functions for downloading and caching tools.
    • The - github + github package provides an Octokit client hydrated with the context that the current action is being run in.
    • The - artifact + artifact package provides functions to interact with actions artifacts.
    • The - cache + cache package provides functions to cache dependencies and build outputs to improve workflow execution time.
    • @@ -143,9 +103,7 @@

      GitHub toolkit

      - + + diff --git a/pages/085/docker_actions.html b/pages/085/docker_actions.html index 6178217..9ac6c53 100644 --- a/pages/085/docker_actions.html +++ b/pages/085/docker_actions.html @@ -1,16 +1,14 @@ + - + Docker actions +
      @@ -47,20 +45,12 @@

      Docker actions

      - Docker actions 1 + Docker actions 1
    - Docker actions 2 + Docker actions 2

    @@ -84,25 +74,14 @@

    Docker actions

    Dockerfiles in Github actions do have certain limitations. You can check them - here. + here.

    - Docker actions 3 + Docker actions 3
    - Docker actions 3 + Docker actions 3
    @@ -122,9 +101,7 @@

    Docker actions

    - + + From 48446f176b0d2445d59e2790f0084a8908aab968 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 20:34:24 +0200 Subject: [PATCH 19/24] Update pages --- pages/061/recovering_commits.html | 45 +++---- pages/062/amending_last_commit.html | 26 ++-- pages/063/amending_earlier_commits.html | 76 +++++------ pages/064/dropping_commits.html | 85 +++++------- pages/065/rewording_commits.html | 29 ++-- pages/066/reordering_commits.html | 24 ++-- pages/067/squashing_commits.html | 79 +++++------ pages/068/splitting_a_commit.html | 45 +++---- pages/069/introduction_to_github_actions.html | 126 +++++++----------- pages/070/triggers.html | 118 +++++++--------- pages/071/shells.html | 8 +- pages/072/running_jobs_in_series.html | 22 ++- pages/073/actions.html | 29 ++-- pages/074/the_checkout_action.html | 16 +-- pages/075/environment_variables.html | 90 +++++-------- pages/077/continue_on_error.html | 11 +- pages/078/timeout_minutes.html | 8 +- pages/079/matrix_and_strategy.html | 51 +++---- pages/080/docker.html | 28 ++-- pages/081/executable_files.html | 8 +- pages/082/building_github_actions.html | 14 +- pages/083/javascript_actions.html | 42 +++--- pages/084/github_toolkit.html | 50 +++---- pages/085/docker_actions.html | 36 ++--- 24 files changed, 416 insertions(+), 650 deletions(-) diff --git a/pages/061/recovering_commits.html b/pages/061/recovering_commits.html index 3f78732..f06be54 100644 --- a/pages/061/recovering_commits.html +++ b/pages/061/recovering_commits.html @@ -32,12 +32,10 @@

    Recovering commits

    - Sometimes you might make a mistake while resetting the - HEAD and erase a commit you did not - mean to erase. As an example, look at the Git Bash image. Here - I've used a reset hard to 6 commits before the - HEAD pointer. To recover everything, - we'll use the git reflog command. + Sometimes you might make a mistake while resetting the HEAD and erase a + commit you did not mean to erase. As an example, look at the Git Bash image. Here I've used a reset hard + to 6 commits before the HEAD pointer. To recover everything, we'll use the + git reflog command.

    @@ -54,34 +52,27 @@

    Recovering commits

    git reflog

    - If we don't supply any other options, Git will show us how our - HEAD pointer has moved throughout - the history of our repository. Every entry in the log has a unique - identifier, starting from - HEAD@{0} (the last position of - the pointer) and moving up one each time the pointer moved. Next - to the identifier, there's a description of what happened in that - entry. The commit ID to the left is the commit to which the - pointer was pointing, after the operation in that entry. So, for - example, after the last operation (which was a reset) the pointer - is at commit af26a96. + If we don't supply any other options, Git will show us how our HEAD pointer + has moved throughout the history of our repository. Every entry in the log has a unique identifier, + starting from HEAD@{0} (the last position of the pointer) and moving up + one each time the pointer moved. Next to the identifier, there's a description of what happened in that + entry. The commit ID to the left is the commit to which the pointer was pointing, after the operation in + that entry. So, for example, after the last operation (which was a reset) the pointer is at commit + af26a96.

    - In this case, to recover our lost commits, we can reset the - HEAD pointer to commit - 3e3b5ed (the second entry in our reflog). To do this, we - run + In this case, to recover our lost commits, we can reset the HEAD pointer to + commit 3e3b5ed (the second entry in our reflog). To do this, we run

    git reset --hard 3e3b5ed

    - We could also use the entry identifier. In that case, we should - have used + We could also use the entry identifier. In that case, we should have used

    git reset --hast HEAD@{0} @@ -98,16 +89,14 @@

    Recovering commits

    git reflog show pointer_name

    - and Git will show us its history. Remember that each branch is a - pointer in Git, so we could use it for branches. We can also use - reflogs with time indications. So, for example + and Git will show us its history. Remember that each branch is a pointer in Git, so we could use it for + branches. We can also use reflogs with time indications. So, for example

    git reflog master@{one.week.ago}

    - will show us where master was, one - week ago. + will show us where master was, one week ago.

    diff --git a/pages/062/amending_last_commit.html b/pages/062/amending_last_commit.html index 8504427..d54e47c 100644 --- a/pages/062/amending_last_commit.html +++ b/pages/062/amending_last_commit.html @@ -32,25 +32,22 @@

    Amending the last commit

    - Suppose we make a commit and then realize that we made a mistake. - If we haven't yet pushed that commit onto a remote repository, we - can make the new changes and then run + Suppose we make a commit and then realize that we made a mistake. If we haven't yet pushed that commit + onto a remote repository, we can make the new changes and then run

    git commit --amend

    - Git will open VS Code and we can write a new message or keep the - original one. If we already know that we want to change the - message, we can run + Git will open VS Code and we can write a new message or keep the original one. If we already know that we + want to change the message, we can run

    git commit --amend -m "New commit message"

    - Keep in mind that we are not really changing the last commit, we - are creating a new one and dropping the last one. So don't amend - commits that you have already pushed onto a remote repository. + Keep in mind that we are not really changing the last commit, we are creating a new one and dropping the + last one. So don't amend commits that you have already pushed onto a remote repository.

    @@ -63,8 +60,7 @@

    Amending the last commit

    - Amending also works if we forgot to include a file in the last - commit. Just stage the changes and then run + Amending also works if we forgot to include a file in the last commit. Just stage the changes and then run

    git commit --amend @@ -75,11 +71,9 @@

    Amending the last commit

    - If, on the other hand, we included a file that we shouldn't have, - then we can use a --mixed reset. - This will undo the last commit, and place all changes in our - working directory. We can now choose which files we want to - include and commit again. + If, on the other hand, we included a file that we shouldn't have, then we can use a + --mixed reset. This will undo the last commit, and place all changes in + our working directory. We can now choose which files we want to include and commit again.

    diff --git a/pages/063/amending_earlier_commits.html b/pages/063/amending_earlier_commits.html index ce10805..c0b86f9 100644 --- a/pages/063/amending_earlier_commits.html +++ b/pages/063/amending_earlier_commits.html @@ -30,17 +30,14 @@

    Amending earlier commits

    - Now suppose we want to amend a previous commit. To do this we need - to use interactive rebasing. Remember that with rebasing - we can replay a bunch of commits on top of other commits. The - interactive part of the name means that we want to give Git - instructions while doing it. + Now suppose we want to amend a previous commit. To do this we need to use interactive rebasing. + Remember that with rebasing we can replay a bunch of commits on top of other commits. The interactive part + of the name means that we want to give Git instructions while doing it.


    - As an example, suppose we want to amend commit 8441b05. - To do so, we need to supply its parent commit to Git. That is - 8527033. So we run + As an example, suppose we want to amend commit 8441b05. To do so, we need to supply its parent + commit to Git. That is 8527033. So we run

    git rebase -i 8527033 @@ -53,20 +50,16 @@

    Amending earlier commits

    - Git will open VS Code in a script that looks like the one below. - In this script we can tell Git which operation we want to do for - each commit. If you are using the GitLens extension then commits - will appear in the same order as they would when running - git log. So at the top you'll see - the latest commit and at the bottom the commit we want to edit. - Otherwise, at the top you'll see the commit that we want to edit - and, at the bottom, the latest commit in this branch. + Git will open VS Code in a script that looks like the one below. In this script we can tell Git which + operation we want to do for each commit. If you are using the GitLens extension then commits will appear + in the same order as they would when running git log. So at the top + you'll see the latest commit and at the bottom the commit we want to edit. Otherwise, at the top you'll + see the commit that we want to edit and, at the bottom, the latest commit in this branch.


    - For each commit you can give an instruction. For this demo, we'll - just edit one commit. So, we select the edit option from the - dropdown menu. + For each commit you can give an instruction. For this demo, we'll just edit one commit. So, we select the + edit option from the dropdown menu.

    @@ -78,21 +71,18 @@

    Amending earlier commits

    - When we close the VS Code window (or click on - Start Rebase if you are using GitLens) the rebase + When we close the VS Code window (or click on Start Rebase if you are using GitLens) the rebase operation will start.


    - Because we told Git that we wanted to edit commit - 8441b05, Git stopped at that commit so that we can make - our changes. We can amend this commit now. + Because we told Git that we wanted to edit commit 8441b05, Git stopped at that commit so that we + can make our changes. We can amend this commit now.


    - In this case, we are just making changes to one file, but we could - add or delete files if we needed to. When we are done, we stage - our changes and commit them by running + In this case, we are just making changes to one file, but we could add or delete files if we needed to. + When we are done, we stage our changes and commit them by running

    git commit --amend @@ -109,18 +99,15 @@

    Amending earlier commits

    - If we take a look at the log, we see that we now have two - branches. One with all the old commits that we are now rebasing - (at its tip you can see the - master pointer). The other branch is - the one that we are creating with the interactive rebase. + If we take a look at the log, we see that we now have two branches. One with all the old commits that we + are now rebasing (at its tip you can see the master pointer). The other + branch is the one that we are creating with the interactive rebase.


    - Because we told Git that we wanted to edit this commit, the - rebasing operation is waiting for us to tell it to continue. When - we do, Git will replay all the other commits involved in the - rebase on top of the new commit. + Because we told Git that we wanted to edit this commit, the rebasing operation is waiting for us to tell + it to continue. When we do, Git will replay all the other commits involved in the rebase on top of the new + commit.


    To continue with the rebase, we run

    @@ -132,15 +119,13 @@

    Amending earlier commits

    - Since at the start of the rebase we told Git that we only wanted - to edit that one commit, when we run continue, Git automatically - took care of the other commits. + Since at the start of the rebase we told Git that we only wanted to edit that one commit, when we run + continue, Git automatically took care of the other commits.


    - Once done rebasing all commits, Git moved the pointer of our - branch (in this case master) to the - tip of the new branch. + Once done rebasing all commits, Git moved the pointer of our branch (in this case + master) to the tip of the new branch.

    @@ -150,15 +135,14 @@

    Amending earlier commits

    - If at any pause during the rebase operation you decide that you - don't want to go through with it, you can run + If at any pause during the rebase operation you decide that you don't want to go through with it, you can + run

    git rebase --abort

    - and Git will restore everything to the state before starting the - rebase. + and Git will restore everything to the state before starting the rebase.

    diff --git a/pages/064/dropping_commits.html b/pages/064/dropping_commits.html index e696d5c..d088288 100644 --- a/pages/064/dropping_commits.html +++ b/pages/064/dropping_commits.html @@ -32,27 +32,22 @@

    Dropping commits

    - Now suppose that we want to drop commit 1736531. To do - this, we'll use interactive rebasing. As always, we should start - our rebase process with the parent of that commit. + Now suppose that we want to drop commit 1736531. To do this, we'll use interactive rebasing. As + always, we should start our rebase process with the parent of that commit.


    - If we take a look at the content of that commit, we see that in - that commit we introduced a new file called terms.txt. - When we drop this commit we have two possible scenarios that we - need to be careful of. If a commit after that one touches that - file, and we drop the commit where the file was introduced, then - we will get a conflict when the rebasing operation reaches that - point in which the file is edited and we will have to resolve it. + If we take a look at the content of that commit, we see that in that commit we introduced a new file + called terms.txt. When we drop this commit we have two possible scenarios that we need to be + careful of. If a commit after that one touches that file, and we drop the commit where the file was + introduced, then we will get a conflict when the rebasing operation reaches that point in which the file + is edited and we will have to resolve it.


    - The worst-case scenario is when no other commits touch that file, - but our program needs it. In this case, we will never get a - conflict while rebasing, but we will be introducing a bug in our - program (possibly even a breaking bug). So be very careful when - dropping commits. + The worst-case scenario is when no other commits touch that file, but our program needs it. In this case, + we will never get a conflict while rebasing, but we will be introducing a bug in our program (possibly + even a breaking bug). So be very careful when dropping commits.


    To start the interactive rebase process we run

    @@ -60,8 +55,7 @@

    Dropping commits

    git rebase -i 1736531^

    - The caret (^) means that we want to start at the parent of that - commit. + The caret (^) means that we want to start at the parent of that commit.

    @@ -71,13 +65,10 @@

    Dropping commits

    - Git will now open VS Code so that we can select the operation that - we want to perform on each commit. Here we select the - drop option for the commit that we want to drop. If you - are now using GitLens, you can also just delete the line for that - commit. Once we selected all the appropriate options for our - commits, we save the file and close it. Here let's start by - deleting the first WIP commit. + Git will now open VS Code so that we can select the operation that we want to perform on each commit. Here + we select the drop option for the commit that we want to drop. If you are now using GitLens, you + can also just delete the line for that commit. Once we selected all the appropriate options for our + commits, we save the file and close it. Here let's start by deleting the first WIP commit.

    @@ -92,19 +83,16 @@

    Dropping commits

    - When we close the file, Git will move forward with the rebase - operation. Take a look at the Git Bash image. It's telling us that - we are at step 2 of 5 during the rebase process. So the commit - that we wanted to drop has been dropped. The next commit edited - that file, which now does not exist, so we get a conflict. + When we close the file, Git will move forward with the rebase operation. Take a look at the Git Bash + image. It's telling us that we are at step 2 of 5 during the rebase process. So the commit that we wanted + to drop has been dropped. The next commit edited that file, which now does not exist, so we get a + conflict.


    - If we check the status, we can see that the - terms.txt file is been deleted (hence the red - D) and modified (hence the red - U) at the same time. This is what's - creating the conflict. + If we check the status, we can see that the terms.txt file is been deleted (hence the red + D) and modified (hence the red U) at the same + time. This is what's creating the conflict.

    @@ -115,22 +103,17 @@

    Dropping commits

    git mergetool

    - Because I haven't configured a merge tool, Git will use one of the - default ones. Git is now asking to choose between one of the two - states of the file. In the local commit (the one we are moving out - of) the file is deleted. In the remote commit (the one we are - trying to move into) the file is modified. Here we choose to keep - the file with the modifications, so we select - m. + Because I haven't configured a merge tool, Git will use one of the default ones. Git is now asking to + choose between one of the two states of the file. In the local commit (the one we are moving out of) the + file is deleted. In the remote commit (the one we are trying to move into) the file is modified. Here we + choose to keep the file with the modifications, so we select m.


    - If we now check the status, we see that the - terms.txt file is been added (since it was deleted in the - previous commit). Notice that there's a new file called - terms.txt.orig. This is a file created by the merge tool. - Some delete them automatically, but even if the merge tool we are - using does not, we can always do so ourselves. + If we now check the status, we see that the terms.txt file is been added (since it was deleted in + the previous commit). Notice that there's a new file called terms.txt.orig. This is a file + created by the merge tool. Some delete them automatically, but even if the merge tool we are using does + not, we can always do so ourselves.


    Since all conflicts have been resolved, when we run

    @@ -149,14 +132,12 @@

    Dropping commits

    - If we check the log, we can see that the commit is now gone and we - have a much cleaner history. Notice that I've also dropped the - other WIP commit and the Revert commit too. + If we check the log, we can see that the commit is now gone and we have a much cleaner history. Notice + that I've also dropped the other WIP commit and the Revert commit too.


    - Lastly, since Git did not remove the auxiliary file created by the - mergetool, we delete it ourselves. + Lastly, since Git did not remove the auxiliary file created by the mergetool, we delete it ourselves.

    diff --git a/pages/065/rewording_commits.html b/pages/065/rewording_commits.html index 66e3ad9..c7650df 100644 --- a/pages/065/rewording_commits.html +++ b/pages/065/rewording_commits.html @@ -32,16 +32,14 @@

    Rewording commits

    - Suppose that we realize that we made a spelling mistake in the - commit message of a commit previous to the last one, but that we - haven't yet pushed onto a remote repository. We can change the - wording with interactive rebasing. + Suppose that we realize that we made a spelling mistake in the commit message of a commit previous to the + last one, but that we haven't yet pushed onto a remote repository. We can change the wording with + interactive rebasing.


    - As an example, suppose we want to reword commits - 6fb2ba7 and fe1a154. To start interactive - rebasing at the parent of oldest commit we run + As an example, suppose we want to reword commits 6fb2ba7 and fe1a154. To start + interactive rebasing at the parent of oldest commit we run

    git rebase -i 6fb2ba7^ @@ -54,8 +52,8 @@

    Rewording commits

    - Now, in GitLens we select the reword option for both commits. We - save and close the file to start the rebasing process. + Now, in GitLens we select the reword option for both commits. We save and close the file to start the + rebasing process.

    @@ -70,20 +68,17 @@

    Rewording commits

    - When we close, Git starts the rebasing process. Every time it - reaches a commit that we want to reword it opens VS Code so that - we can enter our new message. Once we do, we save, close, and Git - continues the rebasing process until all commits have been - rebased. + When we close, Git starts the rebasing process. Every time it reaches a commit that we want to reword it + opens VS Code so that we can enter our new message. Once we do, we save, close, and Git continues the + rebasing process until all commits have been rebased.

    - If we check our log now we will see that the commits that we - selected have been reworded. Notice too that since Git generated - new commits, their IDs are not the same as before the rebase. + If we check our log now we will see that the commits that we selected have been reworded. Notice too that + since Git generated new commits, their IDs are not the same as before the rebase.

    diff --git a/pages/066/reordering_commits.html b/pages/066/reordering_commits.html index 0ca7d67..23d1318 100644 --- a/pages/066/reordering_commits.html +++ b/pages/066/reordering_commits.html @@ -32,17 +32,16 @@

    Reordering commits

    - Suppose now that we want to reorder commits. In our example, - commit 099c06d should come before commit - 23b2c04, so we need to change their order. Once again, we - use interactive rebasing to achieve this. So we run + Suppose now that we want to reorder commits. In our example, commit 099c06d should come before + commit 23b2c04, so we need to change their order. Once again, we use interactive rebasing to + achieve this. So we run

    git rebase -i 70ef834

    - since commit 70ef834 is the parent commit of the oldest - of the two commits that we want to reorder. + since commit 70ef834 is the parent commit of the oldest of the two commits that we want to + reorder.

    @@ -52,10 +51,9 @@

    Reordering commits

    - Now in GitLens we can grab and drag the commits that we want to - reorder, and drop them in their final destination on the commit - tree. If you are not using GitLens you can move lines around in VS - Code with Alt + arrow (up or down as needed). + Now in GitLens we can grab and drag the commits that we want to reorder, and drop them in their final + destination on the commit tree. If you are not using GitLens you can move lines around in VS Code with Alt + + arrow (up or down as needed).

    @@ -70,10 +68,8 @@

    Reordering commits

    - Since there were no conflicts or actions for us to make, Git took - care of everything as soon as we closed the VS Code file. If we - check the log now, we'll see that the commit is where we wanted it - to be. + Since there were no conflicts or actions for us to make, Git took care of everything as soon as we closed + the VS Code file. If we check the log now, we'll see that the commit is where we wanted it to be.

    diff --git a/pages/067/squashing_commits.html b/pages/067/squashing_commits.html index f779a44..8ff6806 100644 --- a/pages/067/squashing_commits.html +++ b/pages/067/squashing_commits.html @@ -32,19 +32,16 @@

    Squashing commits

    - Now let's see how we can squash commits. Squashing commits is the - process of taking two or more commits, and combining all the - changes in those commits into a single commit. For example, here - we will squash commits 78af47a, 7f4e64b, and - 2a57b17 into a single commit. To do this, we use + Now let's see how we can squash commits. Squashing commits is the process of taking two or more commits, + and combining all the changes in those commits into a single commit. For example, here we will squash + commits 78af47a, 7f4e64b, and 2a57b17 into a single commit. To do this, we use interactive rebasing. So we run

    git rebase -i ab0e842

    - where commit ab0e842 is the parent of the oldest commit - that we wish to squash. + where commit ab0e842 is the parent of the oldest commit that we wish to squash.

    @@ -54,17 +51,13 @@

    Squashing commits

    - To squash two commits together we need to use the - squash option in VS Code. Notice how GitLens is not - showing us which commits will be squashed into which commit by - simplifying the commit tree. One thing to remember here is that - squashing is an operation that can only be performed between two - consecutive commits. So once the rebasing starts, Git will first - squash commit 7f4e64b into commit 78af47a, and - then squash commit 2a57b17 into the new commit that it - created for the first squashing. If we want to squash commits that - are not consecutive to one another, then we first need to reorder - the commits. + To squash two commits together we need to use the squash option in VS Code. Notice how GitLens is + not showing us which commits will be squashed into which commit by simplifying the commit tree. One thing + to remember here is that squashing is an operation that can only be performed between two consecutive + commits. So once the rebasing starts, Git will first squash commit 7f4e64b into commit + 78af47a, and then squash commit 2a57b17 into the new commit that it created for the + first squashing. If we want to squash commits that are not consecutive to one another, then we first need + to reorder the commits.

    @@ -79,18 +72,15 @@

    Squashing commits

    - When we close VS Code and the rebasing starts, Git will ask us to - give the new commit a message. The default message that it will - show is the combination of the commit messages for all the commits - that we are squashing. In general, since we squash commits that - have changes that we should have made into a single commit to - begin with, we should input a new message that reflects the - changes done across all of the commits been squashed. + When we close VS Code and the rebasing starts, Git will ask us to give the new commit a message. The + default message that it will show is the combination of the commit messages for all the commits that we + are squashing. In general, since we squash commits that have changes that we should have made into a + single commit to begin with, we should input a new message that reflects the changes done across all of + the commits been squashed.


    - Now if we look at our log there is only one commit for all three - sets of changes. + Now if we look at our log there is only one commit for all three sets of changes.

    @@ -98,21 +88,17 @@

    Squashing commits

    - If we already know that the message for our squashed commit is the - message for the oldest commit, then we can use the - fixup option instead of the squash option. To - see this in action, first we need to reset our repository to how - it was before the last rebasing. So we bring up our reflog by - running + If we already know that the message for our squashed commit is the message for the oldest commit, then we + can use the fixup option instead of the squash option. To see this in action, first we + need to reset our repository to how it was before the last rebasing. So we bring up our reflog by running

    git reflog

    - and grab the commit ID to which the - HEAD pointer was pointing, before - starting the rebase. In this case, commit d038481 (which - is the finish of the last rebase we did). + and grab the commit ID to which the HEAD pointer was pointing, before + starting the rebase. In this case, commit d038481 (which is the finish of the last rebase we + did).

    @@ -129,19 +115,16 @@

    Squashing commits

    git reset --hard d038481

    - and our repository will be restored to the state before the last - rebase. We can see this in our log. + and our repository will be restored to the state before the last rebase. We can see this in our log.

    - Now we restart the interactive rebase just as before, but when Git - asks us which operation to perform to the commits to squash, we - choose fixup. This will cause Git to ignore the commit - messages from these commits, and thus default to the commit that - they are being squashed into (the one with the + Now we restart the interactive rebase just as before, but when Git asks us which operation to perform to + the commits to squash, we choose fixup. This will cause Git to ignore the commit messages from + these commits, and thus default to the commit that they are being squashed into (the one with the pick operation).

    @@ -157,11 +140,9 @@

    Squashing commits

    - Since there are no conflicts for us to resolve, as soon as we save - and close the file, Git will complete the rebasing process. If we - now check the log, we can see that the commits have been squashed, - and the message of the oldest commit was kept without us having to - tell Git which message to use. + Since there are no conflicts for us to resolve, as soon as we save and close the file, Git will complete + the rebasing process. If we now check the log, we can see that the commits have been squashed, and the + message of the oldest commit was kept without us having to tell Git which message to use.

    diff --git a/pages/068/splitting_a_commit.html b/pages/068/splitting_a_commit.html index b26bec5..14401aa 100644 --- a/pages/068/splitting_a_commit.html +++ b/pages/068/splitting_a_commit.html @@ -32,11 +32,9 @@

    Splitting a commit

    - Sometimes we make a commit that combines changes to two separate - logical units of our program, each of which should have its own - commit. We can split these commits using interactive rebasing. As - an example, let's split commit 26986ad into two commits. - To do this we run + Sometimes we make a commit that combines changes to two separate logical units of our program, each of + which should have its own commit. We can split these commits using interactive rebasing. As an example, + let's split commit 26986ad into two commits. To do this we run

    git rebase -i 26986ad^ @@ -49,12 +47,10 @@

    Splitting a commit

    - To split a commit we use the edit option. When we close - the todo file, Git will start the rebase process, but it - will stop at the commit we want to rebase so that we can make our - edition. At this point, we can reset and then stage and commit the - changes that we want to include in one commit, and then stage and - commit the changes that we want to include in the other commit. + To split a commit we use the edit option. When we close the todo file, Git will start + the rebase process, but it will stop at the commit we want to rebase so that we can make our edition. At + this point, we can reset and then stage and commit the changes that we want to include in one commit, and + then stage and commit the changes that we want to include in the other commit.

    @@ -66,25 +62,21 @@

    Splitting a commit

    - Now that we've closed the file, Git started the rebase process. We - see that the HEAD pointer is at - commit 26986ad. We can use the - reset command to go back to the - state before making that commit. So we run + Now that we've closed the file, Git started the rebase process. We see that the + HEAD pointer is at commit 26986ad. We can use the + reset command to go back to the state before making that commit. So we + run

    git reset --mixed HEAD^

    - and Git will move the HEAD pointer - to one commit before its current position and place the changes - done in the commit it's moving away from into the working - directory. + and Git will move the HEAD pointer to one commit before its current position + and place the changes done in the commit it's moving away from into the working directory.


    - Now we have two un-staged changes. We can stage and commit them - one at a time. + Now we have two un-staged changes. We can stage and commit them one at a time.

    @@ -97,9 +89,8 @@

    Splitting a commit

    - Since neither of these commits was part of our commit tree, we - have now diverged from the master branch. To continue with the - rebase we run + Since neither of these commits was part of our commit tree, we have now diverged from the master branch. + To continue with the rebase we run

    git rebase --continue @@ -109,8 +100,8 @@

    Splitting a commit

    - If we now take a look at our log, we see that our tree is clean - and linear. This makes maintaining our project easier. + If we now take a look at our log, we see that our tree is clean and linear. This makes maintaining our + project easier.

    diff --git a/pages/069/introduction_to_github_actions.html b/pages/069/introduction_to_github_actions.html index e9f37f4..24fb643 100644 --- a/pages/069/introduction_to_github_actions.html +++ b/pages/069/introduction_to_github_actions.html @@ -30,54 +30,42 @@

    Introduction to GitHub Actions

    - GitHub Actions is a tool that allows you to automate development - workflows. Each task is called an action. A combination - of tasks is called a workflow. Workflows can be triggered - in different ways: push, pull requests (opened and/or merged), - issues (created, closed, etc), on a specific schedule, or due to - external events. + GitHub Actions is a tool that allows you to automate development workflows. Each task is called an + action. A combination of tasks is called a workflow. Workflows can be triggered in + different ways: push, pull requests (opened and/or merged), issues (created, closed, etc), on a specific + schedule, or due to external events.


    - The workflows will be run in a virtual machine on the GitHub - servers. A workflow can contain one or more jobs, and - each job will run in its own virtual machine. These virtual - machines can use Linux, Windows, or MacOS, and have different - tools installed, and even run Docker Containers. Jobs can be run + The workflows will be run in a virtual machine on the GitHub servers. A workflow can contain one or more + jobs, and each job will run in its own virtual machine. These virtual machines can use Linux, + Windows, or MacOS, and have different tools installed, and even run Docker Containers. Jobs can be run in parallel, or we can specify dependencies between them.


    - A runner is any virtual machine with the GitHub actions - application installed. The runner is responsible for running the - job whenever the triggering conditions are met, and for displaying - back the results. You can use GitHub's runners, or host your own - ones. GitHub hosted runners are maintained by GitHub, but we - cannot customize the hardware configurations. They also come with - some pre-installed tools like curl, git, npm, - yarn, pip, etc, and languages and tools like Python, - Ruby, node.JS, etc. + A runner is any virtual machine with the GitHub actions application installed. The runner is + responsible for running the job whenever the triggering conditions are met, and for displaying back the + results. You can use GitHub's runners, or host your own ones. GitHub hosted runners are maintained by + GitHub, but we cannot customize the hardware configurations. They also come with some pre-installed tools + like curl, git, npm, yarn, pip, etc, and languages and tools like + Python, Ruby, node.JS, etc.

    - Workflows must be written in YAML and placed inside - .github/workflows directory in the root of the project. - This files are composed of key:value pairs, with keys separated - from values by colons, :. To nest objects inside of other - objects in YAML we just need to indent the keys of the child - object with 2 or 4 spaces with respect to the keys of its parent - object. + Workflows must be written in YAML and placed inside .github/workflows directory in the root of + the project. This files are composed of key:value pairs, with keys separated from values by colons, + :. To nest objects inside of other objects in YAML we just need to indent the keys of the child + object with 2 or 4 spaces with respect to the keys of its parent object.


    - Each YAML file in the workflows directory contains the - instructions for one workflow. The first key that we have to - specify is name. The value we pass to it will become the - name of the workflow and GitHub will display it in the Actions - tab. + Each YAML file in the workflows directory contains the instructions for one workflow. The first + key that we have to specify is name. The value we pass to it will become the name of the workflow + and GitHub will display it in the Actions tab.


    @@ -93,76 +81,60 @@

    Introduction to GitHub Actions

    - After the name we'll specify the dispatch mode of the - action using the on key. The value of the on key - can be a single value (for example, use push for a - workflow that needs to be dispatched with every push), an array of - values (for example, use [workflow_dispatch, push] for a - workflow that needs to be dispatched with every push, but also - needs to be able to be manually dispatched), or an object - specifying more complex conditions or to alter the behavior of a - pre-defined dispatch mode. + After the name we'll specify the dispatch mode of the action using the on key. The value + of the on key can be a single value (for example, use push for a workflow that needs to + be dispatched with every push), an array of values (for example, use [workflow_dispatch, push] + for a workflow that needs to be dispatched with every push, but also needs to be able to be manually + dispatched), or an object specifying more complex conditions or to alter the behavior of a pre-defined + dispatch mode.


    - After the name and on keys, we need to start - defining the jobs in our workflow. To do so we use the - jobs key. To it we'll need to supply an array of objects - (each element in the array representing a job) where the first key - is the name of the job and takes as its value an object containing + After the name and on keys, we need to start defining the jobs in our workflow. To do so + we use the jobs key. To it we'll need to supply an array of objects (each element in the array + representing a job) where the first key is the name of the job and takes as its value an object containing all the specifications of the job.


    - The first key of every job is runs-on. The value of this - key needs to be the operating system in which the job is going to - run. We can specify a version of the OS, or just use the key - {os}-latest to have GitHub use the latest version of the - OS. + The first key of every job is runs-on. The value of this key needs to be the operating system in + which the job is going to run. We can specify a version of the OS, or just use the key + {os}-latest to have GitHub use the latest version of the OS.


    - Next comes the steps key, where we can specify the - different steps of the job. We can specify a name for each step - using the name key. After that we use the - run key to specify what needs to be run on this step. + Next comes the steps key, where we can specify the different steps of the job. We can specify a + name for each step using the name key. After that we use the run key to specify what + needs to be run on this step.

    - The first and last step are automatically created by GitHub. The - first one sets up the job, and the last one cleans up after - finishing. You can configure GitHub to send notifications after - each workflow run by going to - Profile > Settings > Notifications > Actions . + The first and last step are automatically created by GitHub. The first one sets up the job, and the last + one cleans up after finishing. You can configure GitHub to send notifications after each workflow run by + going to Profile > Settings > Notifications > Actions .


    - We can cancel a workflow while it's still running by pressing the - Cancel check suite button on the top right corner of the - Actions tab. We can also explore the steps, including their - output, buy pressing the arrows left of the step name. We can use - the search bar to explore the logs. If the job failed, we can - trigger a re-run. + We can cancel a workflow while it's still running by pressing the Cancel check suite button on the + top right corner of the Actions tab. We can also explore the steps, including their output, buy + pressing the arrows left of the step name. We can use the search bar to explore the logs. If the job + failed, we can trigger a re-run.


    - For each job we can define artifacts. In a nut shell, an - artifact is a file generated by the job. An artifact that gets - generated by default is the log archive. We can download this file - from the Actions console. The log consists of one .txt file - for each step of the job. It is useful for debugging. + For each job we can define artifacts. In a nut shell, an artifact is a file generated by the job. + An artifact that gets generated by default is the log archive. We can download this file from the Actions + console. The log consists of one .txt file for each step of the job. It is useful for debugging.


    - To see more information on the logs, we need to set the - ACTIONS_RUNNER_DEBUG and - ACTIONS_STEP_DEBUG secrets to true. To do so, we - need to navigate to the Settings tab on the repo, and to - the Secrets option on the left side menu, and click on the - New repository secret button on the top right corner. + To see more information on the logs, we need to set the ACTIONS_RUNNER_DEBUG and + ACTIONS_STEP_DEBUG secrets to true. To do so, we need to navigate to the Settings + tab on the repo, and to the Secrets option on the left side menu, and click on the New + repository secret button on the top right corner.

    diff --git a/pages/070/triggers.html b/pages/070/triggers.html index f5dd338..c1e12c2 100644 --- a/pages/070/triggers.html +++ b/pages/070/triggers.html @@ -30,10 +30,9 @@

    Triggers

    - Workflows can be triggered with different events. These events can - be any GitHub event: push, pull-requests opened or closed, - comments, etc. Triggers must be specified with the - on keyword of the yaml file. We can pass a single value: + Workflows can be triggered with different events. These events can be any GitHub event: push, + pull-requests opened or closed, comments, etc. Triggers must be specified with the on keyword of + the yaml file. We can pass a single value:

    @@ -46,31 +45,25 @@

    Triggers

    - If we want the same workflow to trigger on different events we can - pass an array of GitHub events to the on keyword. The - workflow will then trigger whenever at least one of the triggering - conditions is met. + If we want the same workflow to trigger on different events we can pass an array of GitHub events to the + on keyword. The workflow will then trigger whenever at least one of the triggering conditions is + met.

    - Some events have activity types. To use the activities - the value that we pass to the on keyword must be an - object. Each attribute in this object must be itself an object - named after a valid GitHub event (like push, pull_request, etc). - Inside each of these object we can define the types key - and pass to it an array of event activity types on which the - workflow should trigger. + Some events have activity types. To use the activities the value that we pass to the on + keyword must be an object. Each attribute in this object must be itself an object named after a valid + GitHub event (like push, pull_request, etc). Inside each of these object we can define the types + key and pass to it an array of event activity types on which the workflow should trigger.


    - Events that have activity types will have some of those set by - default. For example, if we trigger a workflow - on: pull_request, the workflow - will be triggered on opened, synchronized, or - reopened by default. + Events that have activity types will have some of those set by default. For example, if we trigger a + workflow on: pull_request, the workflow will be triggered on + opened, synchronized, or reopened by default.

    @@ -93,44 +86,33 @@

    Triggers

    - Workflow triggers can be filtered so that they only run when - certain branches, files (paths), tags, etc are affected. To - achieve this we need to add more key:value pairs to the - on key. + Workflow triggers can be filtered so that they only run when certain branches, files (paths), tags, etc + are affected. To achieve this we need to add more key:value pairs to the on key.


    - Branches don't necessarily need to be specified by names. They can - also be patterns. Patterns of the form - 'something/*' will only match - branches that start with - something, followed by a slash, - /, followed by some other text, - but not by additional slashes. To match this branches we need to - use 'something/**'. + Branches don't necessarily need to be specified by names. They can also be patterns. Patterns of the form + 'something/*' will only match branches that start with + something, followed by a slash, /, + followed by some other text, but not by additional slashes. To match this branches we need to use + 'something/**'.


    - We can also set the trigger to ignore branches by using the - branches-ignore key. We cannot have branches and - branches-ignore at the same time. But we can ignore - specific branches by adding an exclamation mark, ! in the - branches key. + We can also set the trigger to ignore branches by using the branches-ignore key. We cannot have + branches and branches-ignore at the same time. But we can ignore specific branches by + adding an exclamation mark, ! in the branches key.


    - We can also target specific tags in the same way as we do with - branches. We can use the tags and - tags-ignore keys to specify tags or patterns of tags to - include or ignore, and we can use the exclamation sign to exclude - specific tags. + We can also target specific tags in the same way as we do with branches. We can use the tags and + tags-ignore keys to specify tags or patterns of tags to include or ignore, and we can use the + exclamation sign to exclude specific tags.


    - Finally, we can filter the triggers by paths (files), and ignore - them using the paths-ignore key. We cannot use both keys - in the same workflow, but can also use the exclamation mark here - to ignore. + Finally, we can filter the triggers by paths (files), and ignore them using the paths-ignore key. + We cannot use both keys in the same workflow, but can also use the exclamation mark here to ignore.

    @@ -148,14 +130,11 @@

    Triggers

    - To trigger workflows on a certain schedule we can use - cron jobs scheduling. Scheduling needs to be added by - passing the schedule value to the on key. This - should be an array. Each element of the array needs to contain an - object with the key cron. The value of this key needs to - be a string representing a cron expression. You can use - crontab guru to - create cron expressions. + To trigger workflows on a certain schedule we can use cron jobs scheduling. Scheduling needs to + be added by passing the schedule value to the on key. This should be an array. Each + element of the array needs to contain an object with the key cron. The value of this key needs to + be a string representing a cron expression. You can use crontab guru to create cron expressions.

    @@ -172,9 +151,8 @@

    Triggers

    - We can also trigger workflows on external events. To do so we need - to use the repository_dispatch value, and specify which - activity types should trigger the workflow. + We can also trigger workflows on external events. To do so we need to use the repository_dispatch + value, and specify which activity types should trigger the workflow.


    These dispatch requests need to come to the API endpoint

    @@ -182,37 +160,33 @@

    Triggers

    http://api.github/repos/user_name/repo_name/dispatches

    - They need to be POST requests with the - HEADERS - Accept: application/vmd.github.everest-preview+json, and - Content-Type: application/json. The body of the request - needs to be a JSON object with an event_type that matches - at least one activity type for that trigger. + They need to be POST requests with the HEADERS + Accept: application/vmd.github.everest-preview+json, and Content-Type: application/json. + The body of the request needs to be a JSON object with an event_type that matches at least one + activity type for that trigger.


    - These requests need to be authenticated. This requires that the - request has some authorization header with a valid PAT. The PAT - must have a repo scope. + These requests need to be authenticated. This requires that the request has some authorization header with + a valid PAT. The PAT must have a repo scope.

    - We can also add some client_payload for the workflow. - This payload could, for example, be inputs needed during the jobs. + We can also add some client_payload for the workflow. This payload could, for example, be inputs + needed during the jobs.


    - This payload will be available in the github object on - the workflow. To access it, we use the + This payload will be available in the github object on the workflow. To access it, we use the event.client_payload.key attribute.


    - This can be very useful when we want to trigger workflows in one - repository, based on workflows from another repository. + This can be very useful when we want to trigger workflows in one repository, based on workflows from + another repository.

    diff --git a/pages/071/shells.html b/pages/071/shells.html index 140fb52..223e46a 100644 --- a/pages/071/shells.html +++ b/pages/071/shells.html @@ -30,11 +30,9 @@

    Shells

    - GitHub actions can use different shells: bash, - powershell, cmd, etc. To change the shell from - the default (bash for Linux and MacOS, powershell for Windows) to - a different one, we need to specify it after the run keyword, - using the shell keyword. + GitHub actions can use different shells: bash, powershell, cmd, etc. To change + the shell from the default (bash for Linux and MacOS, powershell for Windows) to a different one, we need + to specify it after the run keyword, using the shell keyword.

    diff --git a/pages/072/running_jobs_in_series.html b/pages/072/running_jobs_in_series.html index a6dd87c..bff2e77 100644 --- a/pages/072/running_jobs_in_series.html +++ b/pages/072/running_jobs_in_series.html @@ -28,10 +28,9 @@

    Running jobs in series

    - By default, jobs will run in parallel. If we want jobs to run in - series we need to specify the needs key. This key takes - as its value an array of job names. The job will only run once all - jobs in the array have finished successfully. + By default, jobs will run in parallel. If we want jobs to run in series we need to specify the + needs key. This key takes as its value an array of job names. The job will only run once all jobs + in the array have finished successfully.

    @@ -42,20 +41,17 @@

    Running jobs in series

    - We can also create actions that capture output. To do so we must - echo the output of a previous step. We access it by - referencing it with + We can also create actions that capture output. To do so we must echo the output of a previous + step. We access it by referencing it with

    "${{ steps.step_id.outputs.output_element }}"

    - The steps variable is created by GitHub. The step - id we need to define it ourselves in the action that we - want to reference. The outputs attribute is created by - GitHub, and the output_element is defined by the creator - of the action. Check the action's documentation to find which - elements can be output, and their names. + The steps variable is created by GitHub. The step id we need to define it ourselves in + the action that we want to reference. The outputs attribute is created by GitHub, and the + output_element is defined by the creator of the action. Check the action's documentation to find + which elements can be output, and their names.

    diff --git a/pages/073/actions.html b/pages/073/actions.html index 400e45b..52c9a42 100644 --- a/pages/073/actions.html +++ b/pages/073/actions.html @@ -32,29 +32,24 @@

    Actions

    - Actions are pieces of code that you or someone else has written to - run some task. Actions need to be written in JavaScript. + Actions are pieces of code that you or someone else has written to run some task. Actions need to be + written in JavaScript.


    - To use an action we specify it with the uses key. Actions - can be included in the same repository as the workflow is by - passing the path to it as a value, or they can be published in - public GitHub repositories. To use an action that has been - published in a public GitHub repository the value of the uses key - needs to be user_name/repo_name@branch_name. We can also - target a released version with - user_name/repo_name@tag_name. We can reference a commit - with user_name/repo_name@commit_sha. The preferred method - it to use the tag name, since the tip of a branch might change in - the future and introduce breaking changes. If the version - references only a mayor, then the latest minor of that mayor will - be used. Same logic with patches. + To use an action we specify it with the uses key. Actions can be included in the same repository + as the workflow is by passing the path to it as a value, or they can be published in public GitHub + repositories. To use an action that has been published in a public GitHub repository the value of the uses + key needs to be user_name/repo_name@branch_name. We can also target a released version with + user_name/repo_name@tag_name. We can reference a commit with + user_name/repo_name@commit_sha. The preferred method it to use the tag name, since the tip of a + branch might change in the future and introduce breaking changes. If the version references only a mayor, + then the latest minor of that mayor will be used. Same logic with patches.


    - Actions might require/allow inputs. The inputs need to be passed - by name (key) as child elements of the with key. + Actions might require/allow inputs. The inputs need to be passed by name (key) as child elements of the + with key.

    diff --git a/pages/074/the_checkout_action.html b/pages/074/the_checkout_action.html index 71fbaa4..1cb7205 100644 --- a/pages/074/the_checkout_action.html +++ b/pages/074/the_checkout_action.html @@ -30,26 +30,24 @@

    The checkout action

    - When we run a CLI command in our local machine, the command is run - on the current directory. When we use workflows, GitHub will set - up a directory in which to run them. This directory is + When we run a CLI command in our local machine, the command is run on the current directory. When we use + workflows, GitHub will set up a directory in which to run them. This directory is

    /home/runner/work/repo_name/repo_name

    - But, by default, that directory will not contain the files in our - directory. The repository is not cloned by default. + But, by default, that directory will not contain the files in our directory. The repository is not cloned + by default.

    - We can use an action to clone the repository into the working - directory. This special action was created by GitHub and is called - checkout. This action will authenticate with our - repository, and checkout to the commit that triggered the run. + We can use an action to clone the repository into the working directory. This special action was created + by GitHub and is called checkout. This action will authenticate with our repository, and checkout + to the commit that triggered the run.

    diff --git a/pages/075/environment_variables.html b/pages/075/environment_variables.html index b21233e..68876de 100644 --- a/pages/075/environment_variables.html +++ b/pages/075/environment_variables.html @@ -33,25 +33,22 @@

    Environment variables

    - Some environment variables are set up automatically by GitHub (in - the runner). We can use these variables in our workflows by - referencing them with $VARIABLE_NAME. + Some environment variables are set up automatically by GitHub (in the runner). We can use these variables + in our workflows by referencing them with $VARIABLE_NAME.


    Some of them are:

    • - $GITHUB_SHA will return the SHA - of the commit that triggered the workflow + $GITHUB_SHA will return the SHA of the commit that triggered the + workflow
    • - $GITHUB_REPOSITORY will return - the user_name/repo_name in which the workflow is - running + $GITHUB_REPOSITORY will return the user_name/repo_name in + which the workflow is running
    • - $GITHUB_WORKSPACE will return - the workspace directory in the runner. + $GITHUB_WORKSPACE will return the workspace directory in the runner

    @@ -67,29 +64,26 @@

    Environment variables

    - We can define our own environment variables as well. To declare a - variable we need to use the env key at the start of our - workflow. This key takes as its value a list of key:value pairs, - where the keys are the names of the environment variables that we - are declaring, and its values are the values of the variables. + We can define our own environment variables as well. To declare a variable we need to use the env + key at the start of our workflow. This key takes as its value a list of key:value pairs, where the keys + are the names of the environment variables that we are declaring, and its values are the values of the + variables.


    - After that we can just write our jobs as we would normally do. To - access the variables we just need to use the - ${ VAR_NAME } syntax. + After that we can just write our jobs as we would normally do. To access the variables we just need to use + the ${ VAR_NAME } syntax.


    - Variables declared this way will be available to the whole - workflow. Variables that need to only be available to a specific - job in the workflow are declared and used in the same way, but - using the env in that specific job. + Variables declared this way will be available to the whole workflow. Variables that need to only be + available to a specific job in the workflow are declared and used in the same way, but using the + env in that specific job.


    - Likewise, if we want a variable to only be available in a step of - a job, we use declare and use it in that step. + Likewise, if we want a variable to only be available in a step of a job, we use declare and use it in that + step.

    @@ -104,34 +98,29 @@

    Environment variables

    - Some variables need to be encrypted. To do so, we just need to add - the variable value in - Settings > Secrets > Actions > New repository secret. Give - it a name and a value, and save it. These variables will be - available in a workflow using an object called secrets. + Some variables need to be encrypted. To do so, we just need to add the variable value in Settings > + Secrets > Actions > New repository secret. Give it a name and a value, and save it. These + variables will be available in a workflow using an object called secrets.


    - One secret that is automatically available on workflows is - secrets.GITHUB_TOKEN. This token can be used to access - the GitHub API, or to push something to the repo, etc. Basically, - any time that the action needs to interact with the repository it - will need authentication, and we can use this variable to do it. + One secret that is automatically available on workflows is secrets.GITHUB_TOKEN. This token can + be used to access the GitHub API, or to push something to the repo, etc. Basically, any time that the + action needs to interact with the repository it will need authentication, and we can use this variable to + do it.

    - Secrets can be safely logged because GitHub will never expose them - to the logs. It will print them as asterisks. + Secrets can be safely logged because GitHub will never expose them to the logs. It will print them as + asterisks.


    - The authentication token can also be accessed via the - github object. This object is automatically set for us by - GitHub and contains several other values too. More on that object - latter. + The authentication token can also be accessed via the github object. This object is automatically + set for us by GitHub and contains several other values too. More on that object later.

    @@ -143,23 +132,18 @@

    Environment variables

    - Secrets are useful but they have a limit of 6kbs. Likewise, we - might be using some CLI commands in a workflow that uses some - secrets that need to be stored in a JSON file. We can push - encrypted versions of those files and then include a decryption - step in our jobs. + Secrets are useful but they have a limit of 6kbs. Likewise, we might be using some CLI commands in a + workflow that uses some secrets that need to be stored in a JSON file. We can push encrypted versions of + those files and then include a decryption step in our jobs.


    - To encrypt the file locally we can use tools like - GPG. For details - on how to use this tool, refer to the encrypted secrets - documentation + To encrypt the file locally we can use tools like GPG. + For details on how to use this tool, refer to the encrypted secrets documentation here. - Since this files require a passphrase to be decrypted, that - passphrase needs to be added as a repository secret. And since the - encrypted file itself needs to be available in the runner, - workflows that require them must first include a checkout step. + Since this files require a passphrase to be decrypted, that passphrase needs to be added as a repository + secret. And since the encrypted file itself needs to be available in the runner, workflows that require + them must first include a checkout step.

    diff --git a/pages/077/continue_on_error.html b/pages/077/continue_on_error.html index 43a1595..a9e4a59 100644 --- a/pages/077/continue_on_error.html +++ b/pages/077/continue_on_error.html @@ -30,13 +30,10 @@

    Continue on error

    - The if: failure() option was good to force a downstream - step to run even if the previous one had failed. But any step - coming after that immediate failed one, will still not run. If we - need to make sure that all downstream steps do run, we can add the - continue-on-error: true key:value - pair to the job that might fail. By default this key's value is - set to false. + The if: failure() option was good to force a downstream step to run even if the previous one had + failed. But any step coming after that immediate failed one, will still not run. If we need to make sure + that all downstream steps do run, we can add the continue-on-error: true + key:value pair to the job that might fail. By default this key's value is set to false.

    diff --git a/pages/078/timeout_minutes.html b/pages/078/timeout_minutes.html index ba0033b..e8af8ae 100644 --- a/pages/078/timeout_minutes.html +++ b/pages/078/timeout_minutes.html @@ -32,11 +32,9 @@

    Timeout minutes

    - Another key that we can use is the timeout-minutes. It - can be added either to a job or to a step. This key controls the - maximum number of minutes that the job or step can take. By - default this key's value is set to 360. After the alloted time, - GitHub will cancel the job. + Another key that we can use is the timeout-minutes. It can be added either to a job or to a step. + This key controls the maximum number of minutes that the job or step can take. By default this key's value + is set to 360. After the alloted time, GitHub will cancel the job.

    diff --git a/pages/079/matrix_and_strategy.html b/pages/079/matrix_and_strategy.html index cb5ff86..4ac91ca 100644 --- a/pages/079/matrix_and_strategy.html +++ b/pages/079/matrix_and_strategy.html @@ -30,38 +30,30 @@

    Matrix and strategy

    - The strategy key will allow us to set up an environment - matrix. GitHub will then run the job in every possible - combination of environments set-ups specified on our matrix. To - set up a strategy we need to include the strategy key in - our job. Inside this key we also need to add the - matrix key. The value of the matrix key needs to - be an object. The keys of this object can be whatever we like. - These keys basically act as parameters. Each value is an array of - the different values that we want to pass to our job for that - parameter. + The strategy key will allow us to set up an environment matrix. GitHub will then run the + job in every possible combination of environments set-ups specified on our matrix. To set up a strategy we + need to include the strategy key in our job. Inside this key we also need to add the + matrix key. The value of the matrix key needs to be an object. The keys of this object + can be whatever we like. These keys basically act as parameters. Each value is an array of the different + values that we want to pass to our job for that parameter.


    - Under the strategy key we can also add the - fail-fast key. By default this key has a value of true. - This means that under this job, if one step fails, all other steps - of the job will be stopped. + Under the strategy key we can also add the fail-fast key. By default this key has a + value of true. This means that under this job, if one step fails, all other steps of the job will be + stopped.


    - We can also add the max-parallel keyword. This key takes - as its value an integer that specifies how many values of the - matrix can run in parallel. By default, GitHub will try to - maximize the number of jobs running in parallel. + We can also add the max-parallel keyword. This key takes as its value an integer that specifies + how many values of the matrix can run in parallel. By default, GitHub will try to maximize the number of + jobs running in parallel.


    - To reference the values of our matrix we need to use an expression - that invokes the matrix context. Using dot notation, we pass the - context and the parameter key that we defined in our matrix. - GitHub will run the job once with each possible combination of - parameter values. + To reference the values of our matrix we need to use an expression that invokes the matrix context. Using + dot notation, we pass the context and the parameter key that we defined in our matrix. GitHub will run the + job once with each possible combination of parameter values.

    @@ -74,20 +66,17 @@

    Matrix and strategy

    - If we want to exclude a particular combination in our matrix, we - can use the exclude key to specify an array of values - (one per key) to exclude. + If we want to exclude a particular combination in our matrix, we can use the exclude key to + specify an array of values (one per key) to exclude.

    - There's also an include key, but it's not the opposite of - the exclude key. This key also takes an array of objects - with all the parameters of the matrix, but we use it to specify - additional configurations or variables that are needed for that - combination only. + There's also an include key, but it's not the opposite of the exclude key. This key also + takes an array of objects with all the parameters of the matrix, but we use it to specify additional + configurations or variables that are needed for that combination only.

    diff --git a/pages/080/docker.html b/pages/080/docker.html index c7bc0db..38dc32e 100644 --- a/pages/080/docker.html +++ b/pages/080/docker.html @@ -31,15 +31,12 @@

    Docker

    - We can specify Docker containers for our jobs to run by using the - container key. To it we pass an object with an - image key, its value being the image that we will be - using. Additionally, we can specify the env (for - environment variables that need to be available in the container), - ports (to specify ports to be exposed in the container), - volumes, options (to be used in the Docker - create command). All steps in the job will run in de container, - and not on the virtual machine. + We can specify Docker containers for our jobs to run by using the container key. To it we pass an + object with an image key, its value being the image that we will be using. Additionally, we can + specify the env (for environment variables that need to be available in the container), + ports (to specify ports to be exposed in the container), volumes, options (to + be used in the Docker create command). All steps in the job will run in de container, and not on the + virtual machine.

    @@ -52,20 +49,17 @@

    Docker

    - We can also specify multiple containers. To specify multiple - containers we pass an object to the services key. Each - element of that object is the key that identifies each one of our - services. In order to communicate between the two containers we - can use the service key (name) as a host name. + We can also specify multiple containers. To specify multiple containers we pass an object to the + services key. Each element of that object is the key that identifies each one of our services. In + order to communicate between the two containers we can use the service key (name) as a host name.

    - We can specify different containers for different steps. To do so, - we simply pass the Docker image to uses keyword of the - respective steps. + We can specify different containers for different steps. To do so, we simply pass the Docker image to + uses keyword of the respective steps.

    diff --git a/pages/081/executable_files.html b/pages/081/executable_files.html index bdc46f8..22bc1d3 100644 --- a/pages/081/executable_files.html +++ b/pages/081/executable_files.html @@ -31,11 +31,9 @@

    Executable files

    - We can create our own executable files and run them in actions. - This includes passing them as the ENTRYPOINT to a Docker - file. When using a shell script, be sure to run - chmod +x path/to/file.sh before - committing the changes. + We can create our own executable files and run them in actions. This includes passing them as the + ENTRYPOINT to a Docker file. When using a shell script, be sure to run + chmod +x path/to/file.sh before committing the changes.

    diff --git a/pages/082/building_github_actions.html b/pages/082/building_github_actions.html index 46a3de4..7d5d23b 100644 --- a/pages/082/building_github_actions.html +++ b/pages/082/building_github_actions.html @@ -33,15 +33,11 @@

    Building GitHub Actions

    - We can create our own actions to automate our steps. Public - actions require their own dedicated repository. Private actions - can be built in our repository. Actions must be written using - JavaScript. If we need to write the Action in a different - language, we need to run them in Docker containers. They have the - benefit of being consistent (since they run in a controlled - environment defined in the Docker image), but they have the draw - side of being slower (since the image needs to be deployed to the - virtual machine). + We can create our own actions to automate our steps. Public actions require their own dedicated + repository. Private actions can be built in our repository. Actions must be written using JavaScript. If + we need to write the Action in a different language, we need to run them in Docker containers. They have + the benefit of being consistent (since they run in a controlled environment defined in the Docker image), + but they have the draw side of being slower (since the image needs to be deployed to the virtual machine).

    diff --git a/pages/083/javascript_actions.html b/pages/083/javascript_actions.html index 1f9872a..a9ce1b1 100644 --- a/pages/083/javascript_actions.html +++ b/pages/083/javascript_actions.html @@ -34,26 +34,21 @@

    JavaScript actions

    - We place actions in the - .github/actions directory. Each - action should have its own sub-directory. + We place actions in the .github/actions directory. Each action should + have its own sub-directory.


    - Each action requires an action.yml file. In this file - we'll declare the name, author, and - description of the action. Next we can add objects to the - inputs and outputs keywords. Each elements of - the inputs object is itself an object too, with a - description, required flag, and a - default value. Each element of the outputs object takes a - description. + Each action requires an action.yml file. In this file we'll declare the name, + author, and description of the action. Next we can add objects to the inputs + and outputs keywords. Each elements of the inputs object is itself an object too, with a + description, required flag, and a default value. Each element of the outputs + object takes a description.


    - Below that we need to include the runs keyword. In it we - specify the version of node in the using keyword, and the - location of the file with the action in the main keyword. + Below that we need to include the runs keyword. In it we specify the version of node in the + using keyword, and the location of the file with the action in the main keyword.

    @@ -61,26 +56,21 @@

    JavaScript actions

    - To include this action in a workflow, first we'll need to checkout - the repository and then pass the action path to the - uses keyword. + To include this action in a workflow, first we'll need to checkout the repository and then pass the action + path to the uses keyword.


    - When our actions use external packages we need to compile our code - so that the packages are available in the virtual machine. To do - this, we can use the vercel/ncc package. To install it - locally we run - npm i -D @vercel/ncc. Once - installed we can use it by running + When our actions use external packages we need to compile our code so that the packages are available in + the virtual machine. To do this, we can use the vercel/ncc package. To install it locally we run + npm i -D @vercel/ncc. Once installed we can use it by running

    npx ncc build path/to/file.js -o path/to/output/dist

    - Once the dist is generated we just have to update the - main keyword in our workflow so that it points to it (for - example main: 'dist/index.js'). + Once the dist is generated we just have to update the main keyword in our workflow so that + it points to it (for example main: 'dist/index.js').

    diff --git a/pages/084/github_toolkit.html b/pages/084/github_toolkit.html index 12f0dc6..fc27c1c 100644 --- a/pages/084/github_toolkit.html +++ b/pages/084/github_toolkit.html @@ -30,42 +30,31 @@

    GitHub toolkit

    - GitHub provides a - toolkit - to help facilitate building actions that we can use. This toolkit - is composed of several packages, each specialized in one group of - tools. + GitHub provides a toolkit to help facilitate + building actions that we can use. This toolkit is composed of several packages, each specialized in one + group of tools.

    • - The - core - package provides functions for inputs, outputs, results, - logging, secrets, and variables. + The core package + provides functions for inputs, outputs, results, logging, secrets, and variables.
    • - The - exec - package provides functions to execute CLI tools and process - output. + The exec package + provides functions to execute CLI tools and process output.
    • - The - glob - package provides functions to search for files matching glob - patterns. + The glob package + provides functions to search for files matching glob patterns.
    • The http-client - package provides a lightweight HTTP client optimized for - building actions. + package provides a lightweight HTTP client optimized for building actions.
    • - The - io - package provides disk i/o functions (like cp, mv, rmRF, which, - etc). + The io package + provides disk i/o functions (like cp, mv, rmRF, which, etc).
    • The @@ -73,21 +62,16 @@

      GitHub toolkit

      package provides functions for downloading and caching tools.
    • - The - github - package provides an Octokit client hydrated with the context - that the current action is being run in. + The github + package provides an Octokit client hydrated with the context that the current action is being run in.
    • - The - artifact + The artifact package provides functions to interact with actions artifacts.
    • - The - cache - package provides functions to cache dependencies and build - outputs to improve workflow execution time. + The cache package + provides functions to cache dependencies and build outputs to improve workflow execution time.
    diff --git a/pages/085/docker_actions.html b/pages/085/docker_actions.html index 9ac6c53..ee46818 100644 --- a/pages/085/docker_actions.html +++ b/pages/085/docker_actions.html @@ -30,18 +30,15 @@

    Docker actions

    - Docker actions don't run directly on the virtual machine in the - GitHub Action runner, but rather in the container defined by the - Docker build. It will be slower, but allows us to use tools that - are otherwise not available in the GitHub servers. + Docker actions don't run directly on the virtual machine in the GitHub Action runner, but rather in the + container defined by the Docker build. It will be slower, but allows us to use tools that are otherwise + not available in the GitHub servers.


    - The basic directory organization is the same. Create a - sub-directory in the .github/actions directory, and place - the action.yml file in there. We also need to add in this - directory all other files needed for the action (e.g. Dockerfile, - executable files, etc). + The basic directory organization is the same. Create a sub-directory in the .github/actions + directory, and place the action.yml file in there. We also need to add in this directory all + other files needed for the action (e.g. Dockerfile, executable files, etc).

    @@ -54,26 +51,22 @@

    Docker actions

    - The action.yml file follows the same structure as before, - but the using key needs to be set to docker, and instead - of main we need to supply an image. This can be - either an image from DockerHub, or one that we create ourselves. + The action.yml file follows the same structure as before, but the using key needs to be + set to docker, and instead of main we need to supply an image. This can be either an + image from DockerHub, or one that we create ourselves.

    - The Dockerfile needs to be placed inside the action - directory. When using Docker actions, we need to define the inputs - in the inputs object, but also pass them to the - args array. This way, arguments will be supplied to the - entrypoint. + The Dockerfile needs to be placed inside the action directory. When using Docker actions, we need + to define the inputs in the inputs object, but also pass them to the args array. This + way, arguments will be supplied to the entrypoint.


    - Dockerfiles in Github actions do have certain limitations. You can - check them + Dockerfiles in Github actions do have certain limitations. You can check them here.

    @@ -87,8 +80,7 @@

    Docker actions

    - To set environment variables when creating actions in Docker - containers we use the syntax + To set environment variables when creating actions in Docker containers we use the syntax

    echo "{environment_variable_name}={value}" >> $GITHUB_ENV From bb436df29688fdf4b89a1c18151977c07df09f90 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 20:44:16 +0200 Subject: [PATCH 20/24] Update pages --- pages/057/forks.html | 189 ++++++++++++------------------- pages/058/rewriting_history.html | 81 ++++++------- pages/059/undoing_commits.html | 62 ++++------ pages/060/reverting_commits.html | 58 ++++------ 4 files changed, 154 insertions(+), 236 deletions(-) diff --git a/pages/057/forks.html b/pages/057/forks.html index a436f9e..66b2952 100644 --- a/pages/057/forks.html +++ b/pages/057/forks.html @@ -32,15 +32,12 @@

    Forks

    - So far, all that we've done included working with a repository to - which we have push access. Suppose now that we've found an - Open-Source project to which we want to collaborate. These kinds - of projects use the Integration-Manager Workflow that we saw - before. Therefore, we don't have push access to them. This is why, - when contributing to open source projects, the first thing we need - to do is to fork the project repository. This will create a new - repository that we own and that has a copy of all the code and - files in the original repository. + So far, all that we've done included working with a repository to which we have push access. Suppose now + that we've found an Open-Source project to which we want to collaborate. These kinds of projects use the + Integration-Manager Workflow that we saw before. Therefore, we don't have push access to them. This is + why, when contributing to open source projects, the first thing we need to do is to fork the project + repository. This will create a new repository that we own and that has a copy of all the code and files in + the original repository.

    @@ -53,31 +50,25 @@

    Forks

    - The new repository will have the same name as the original one - (though we can change it), and a legend will be displayed below - our repository's name saying from which repository it was forked. - Since this new repository is ours, we can push changes to it. + The new repository will have the same name as the original one (though we can change it), and a legend + will be displayed below our repository's name saying from which repository it was forked. Since this new + repository is ours, we can push changes to it.


    - The first thing you need to do is to clone this new repository to - your local machine so that you can work on it. Then, create a new - branch where you will work on your proposed changes. + The first thing you need to do is to clone this new repository to your local machine so that you can work + on it. Then, create a new branch where you will work on your proposed changes.

    - Most open-source projects welcome contributions as long as they - are done following their contribution guide. Just as - README.md and LICENSE.md are special files to - GitHub, so too are files like CONTRIBUTION_GUIDE.md (or - some variation of the name), CODE_OF_CONDUCT.md, and - templates for issues and PRs. You can usually find all this - information in either the root directory of a repository, a - special folder set for this, or a Wiki page (under the Wiki tab of - the repository). + Most open-source projects welcome contributions as long as they are done following their contribution + guide. Just as README.md and LICENSE.md are special files to GitHub, so too are files + like CONTRIBUTION_GUIDE.md (or some variation of the name), CODE_OF_CONDUCT.md, and + templates for issues and PRs. You can usually find all this information in either the root directory of a + repository, a special folder set for this, or a Wiki page (under the Wiki tab of the repository).

    @@ -90,9 +81,8 @@

    Forks

    - Once you've made all your changes, push them onto your forked - repository. Remember that the first time you push a new branch, - you need to set the upstream with + Once you've made all your changes, push them onto your forked repository. Remember that the first time you + push a new branch, you need to set the upstream with

    git push -u remote_name branch_name @@ -102,8 +92,7 @@

    Forks

    - Once you are done making and pushing all your changes, go back to - GitHub and start a new PR. + Once you are done making and pushing all your changes, go back to GitHub and start a new PR.

    @@ -116,32 +105,29 @@

    Forks

    - The only difference between this PR and the PRs we saw earlier, is - that now you are going to be comparing the new branch on your - repository, with a branch (in this case main) from the - original repository. + The only difference between this PR and the PRs we saw earlier, is that now you are going to be comparing + the new branch on your repository, with a branch (in this case main) from the original + repository.

    - After clicking on the Create pull request button, GitHub - will create it IN THE ORIGINAL REPOSITORY. There we can - start a conversation with the maintainers of the project. They - might request additional changes from us, or to expand our - explanation or documentation of what our code does. + After clicking on the Create pull request button, GitHub will create it + IN THE ORIGINAL REPOSITORY. There we can start a conversation with the maintainers of the + project. They might request additional changes from us, or to expand our explanation or documentation of + what our code does.


    - But notice that we are not allowed to merge the PR into the - original repository. Only maintainers can do so. + But notice that we are not allowed to merge the PR into the original repository. Only maintainers can do + so.


    - Keep in mind that if we push more changes onto the branch that - we've created while the PR is in progress, these changes will - impact not only the branch in our fork but the PR too. + Keep in mind that if we push more changes onto the branch that we've created while the PR is in progress, + these changes will impact not only the branch in our fork but the PR too.

    @@ -154,13 +140,11 @@

    Forks

    - Whenever you find yourself in the position of the maintainer, - merging this type of PR is no different than merging any other PR. - Once that you and the contributor have finished discussing the - changes and you are ready to merge them, just click on the - Merge pull request button. If there are any conflicts - you'll have to resolve them or ask the contributor to make a new - push and that solves them, before clicking on the merge button. + Whenever you find yourself in the position of the maintainer, merging this type of PR is no different than + merging any other PR. Once that you and the contributor have finished discussing the changes and you are + ready to merge them, just click on the Merge pull request button. If there are any conflicts + you'll have to resolve them or ask the contributor to make a new push and that solves them, before + clicking on the merge button.


    Once the merger is done, the PR will be closed.

    @@ -169,19 +153,16 @@

    Forks

    - Now that your PR has been merged into the original repository, if - you go back to your forked repository on GitHub, you'll notice a - message saying that your fork is an x number of commits behind the - base repository. This happens because even though our fork knows - about the existence of the original repository, GitHub does not - automatically keep them in sync. We need to do this manually. + Now that your PR has been merged into the original repository, if you go back to your forked repository on + GitHub, you'll notice a message saying that your fork is an x number of commits behind the base + repository. This happens because even though our fork knows about the existence of the original + repository, GitHub does not automatically keep them in sync. We need to do this manually.


    - Therefore, we need to be able to pull the new changes from the - base repository onto our local repository of the forked - repository. To do so, we need to set up a new reference between - our local repository and the original remote upstream. + Therefore, we need to be able to pull the new changes from the base repository onto our local repository + of the forked repository. To do so, we need to set up a new reference between our local repository and the + original remote upstream.

    @@ -198,12 +179,10 @@

    Forks

    git remote -v

    - Git will show us our current remotes and the URL from where they - fetch or push to. When we clone a repository onto our machine, Git - will automatically create the - origin remote. In this case, this - remote refers to our forked repository. To add a new one that - points to the original upstream repository we run + Git will show us our current remotes and the URL from where they fetch or push to. When we clone a + repository onto our machine, Git will automatically create the origin + remote. In this case, this remote refers to our forked repository. To add a new one that points to the + original upstream repository we run

    @@ -211,12 +190,9 @@

    Forks

    - Here remote_name can be anything - you want, but it's most common to call them either - base or - upstream. The - remote_url we are referring to is - the URL of the original repository. + Here remote_name can be anything you want, but it's most common to call + them either base or upstream. The + remote_url we are referring to is the URL of the original repository.

    @@ -237,37 +213,29 @@

    Forks

    - Now we can bring in the new changes in the original repository by - using the fetch or - pull commands. Remember that when - we fetch or - pull we need to supply the name - of the remote from where Git is - supposed to fetch or - pull. When we omit this, Git - assumes that we want to use the - origin. But in this case, we must - include it, since we want Git to bring in changes that are not in - our origin but in a different - remote. So, we run + Now we can bring in the new changes in the original repository by using the + fetch or pull commands. Remember that + when we fetch or pull we need to supply + the name of the remote from where Git is supposed to + fetch or pull. When we omit this, Git + assumes that we want to use the origin. But in this case, we must + include it, since we want Git to bring in changes that are not in our + origin but in a different remote. So, we + run

    git fetch remote_name

    - Notice that now we have a new branch called - base/main. If we take a look at our - log, we can see that this branch is ahead of our local - main branch. So we need to merge - base/main onto - main. Luckily, there's nothing - special about this merge. + Notice that now we have a new branch called base/main. If we take a look at + our log, we can see that this branch is ahead of our local main branch. So + we need to merge base/main onto main. Luckily, + there's nothing special about this merge.


    - Since our local repository is now in sync with the original - repository, we can push these changes into our forked repository - and it too will be up-to-date with the original one. + Since our local repository is now in sync with the original repository, we can push these changes into our + forked repository and it too will be up-to-date with the original one.

    @@ -277,30 +245,23 @@

    Forks

    - One thing you may have noticed is that we never merged the branch - where we made our proposed changes onto the main branch of our - repository. You can do so if you want. But our changes got brought - into our local and remote main branches via the pull (or fetch) - from the original repository in its post-PR state. So they are - there already. + One thing you may have noticed is that we never merged the branch where we made our proposed changes onto + the main branch of our repository. You can do so if you want. But our changes got brought into our local + and remote main branches via the pull (or fetch) from the original repository in its post-PR state. So + they are there already.


    - If you decide to go ahead and merge anyway, keep in mind that the - maintainer of the original repository may have changed our code - when merging (maybe he/she fixed some merge conflicts for - example). By merging our branch onto main we may be reintroducing - those merge conflicts. So it's usually best to just throw them - away (unless our changes were rejected by the maintainer but we'd - still like to keep them). + If you decide to go ahead and merge anyway, keep in mind that the maintainer of the original repository + may have changed our code when merging (maybe he/she fixed some merge conflicts for example). By merging + our branch onto main we may be reintroducing those merge conflicts. So it's usually best to just throw + them away (unless our changes were rejected by the maintainer but we'd still like to keep them).


    - A final comment. When contributing to open source projects is - usually customary that before we send a PR, we pull in the most - recent changes from the original repository first, merge the main - branch onto our proposed changes, and then start a PR. This - decreases the number of merge conflicts that could happen when + A final comment. When contributing to open source projects is usually customary that before we send a PR, + we pull in the most recent changes from the original repository first, merge the main branch onto our + proposed changes, and then start a PR. This decreases the number of merge conflicts that could happen when merging our PR into the original repository.

    diff --git a/pages/058/rewriting_history.html b/pages/058/rewriting_history.html index 31d2f0a..8ae7c24 100644 --- a/pages/058/rewriting_history.html +++ b/pages/058/rewriting_history.html @@ -28,33 +28,26 @@

    Rewriting History

    - In Git we can rewrite the history of our repository. But this must - be handled with care. The ultimate goal is to have a clean and - readable history that allows us to understand how our project - evolved and makes it easy to move back and forth between versions. + In Git we can rewrite the history of our repository. But this must be handled with care. The ultimate goal + is to have a clean and readable history that allows us to understand how our project evolved and makes it + easy to move back and forth between versions.


    - To ensure this goal, our commits should not be too large, nor too - small, and with meaningful messages that clearly explain what - changes in that commit (what was delete, added, or modified). They - should focus on one task at a time. So, for example, if - implementing a new feature requires completing three steps, then - there should be a branch for that feature. In this branch, we - should have three commits, each representing the completion of one - task. If while we are working on a task we find a bug or a typo, - we should create a new task and work on it on its own branch and - commits. + To ensure this goal, our commits should not be too large, nor too small, and with meaningful messages that + clearly explain what changes in that commit (what was delete, added, or modified). They should focus on + one task at a time. So, for example, if implementing a new feature requires completing three steps, then + there should be a branch for that feature. In this branch, we should have three commits, each representing + the completion of one task. If while we are working on a task we find a bug or a typo, we should create a + new task and work on it on its own branch and commits.


    - If the new feature is too large or complex, then it needs to be - broken down into smaller iterations. Focus on making a basic - functionality, and then iterate adding extra functionalities one - at a time. Likewise, if a task is too complex, then it should be - broken into sub-tasks and each sub-task should be developed in its - own branch. Don't be afraid of your history looking like the one - below. Use branches!! That's what they are there for!! + If the new feature is too large or complex, then it needs to be broken down into smaller iterations. Focus + on making a basic functionality, and then iterate adding extra functionalities one at a time. Likewise, if + a task is too complex, then it should be broken into sub-tasks and each sub-task should be developed in + its own branch. Don't be afraid of your history looking like the one below. Use branches!! That's what + they are there for!!

    @@ -66,45 +59,35 @@

    Rewriting History

    - Having said that, it is not always easy (or even possible) to - maintain a clean history while working. This is where the tools - for rewriting history come into play. With them, we can squash - small and related commits into a single one, split large commits - into smaller ones (each of which should represent a separate logic - of changes). We can also use them to correct or improve commit - messages. We can drop or modify commits (for example, if you - forgot to include a file in a commit). + Having said that, it is not always easy (or even possible) to maintain a clean history while working. This + is where the tools for rewriting history come into play. With them, we can squash small and related + commits into a single one, split large commits into smaller ones (each of which should represent a + separate logic of changes). We can also use them to correct or improve commit messages. We can drop or + modify commits (for example, if you forgot to include a file in a commit).


    - But, rewriting the history of a repository can be dangerous. So, - there are two golden rules for rewriting history: + But, rewriting the history of a repository can be dangerous. So, there are two golden rules for rewriting + history:

    • - Always make sure that you know exactly what you are doing before - doing it. If you thought you knew how to do something and now - realize you didn't, or if you made a mistake while doing it and - you don't know how to fix it, stop what you are doing and, - before touching anything else, seek help. + Always make sure that you know exactly what you are doing before doing it. If you thought you knew how + to do something and now realize you didn't, or if you made a mistake while doing it and you don't know + how to fix it, stop what you are doing and, before touching anything else, seek help.
    • - NEVER REWRITE PUBLIC HISTORY. Public - history is everything that has already been shared with other - people. In essence, if it has been pushed onto a GitHub - repository, then don't change it. Remember that commits are - actually immutable. So when we rewrite history, what we are - actually doing is telling Git to throw away a commit, and - replace it with another (or others). If another person already - started working from where we left off, then our changes might - break their code. + NEVER REWRITE PUBLIC HISTORY. Public history is everything that has already + been shared with other people. In essence, if it has been pushed onto a GitHub repository, then don't + change it. Remember that commits are actually immutable. So when we rewrite history, what we are + actually doing is telling Git to throw away a commit, and replace it with another (or others). If + another person already started working from where we left off, then our changes might break their code.

    - This does not mean that rewriting history is a bad practice. In - fact, it's a good one. Just remember doing it before you push your - changes onto a public repository. This way you make sure that the - history of the project is clean and clear. + This does not mean that rewriting history is a bad practice. In fact, it's a good one. Just remember doing + it before you push your changes onto a public repository. This way you make sure that the history of the + project is clean and clear.

    diff --git a/pages/059/undoing_commits.html b/pages/059/undoing_commits.html index e8f205b..1c9bbd2 100644 --- a/pages/059/undoing_commits.html +++ b/pages/059/undoing_commits.html @@ -32,9 +32,8 @@

    Undoing commits

    - Suppose we have a repository that looks like the one on the image - and we want to undo the last commit (088455d). Since this - commit is only in our local repository, we use the + Suppose we have a repository that looks like the one on the image and we want to undo the last commit + (088455d). Since this commit is only in our local repository, we use the reset command.

    @@ -47,22 +46,17 @@

    Undoing commits

    This command has three options that you should know about:

    • - --soft removes from the - repository only. This means that it undoes the - git commit action, but our - changes are still in the staging area. + --soft removes from the repository only. This means that it undoes the + git commit action, but our changes are still in the staging area.
    • - --mixed removes from the - repository and the staging area. This means that it undoes both - git commit and - git add action. Our changes - will still be in our working directory. + --mixed removes from the repository and the staging area. This means + that it undoes both git commit and + git add action. Our changes will still be in our working directory.
    • - --hard removes from the - repository, the staging area, and the working directory. This - means that we are getting rid of our work for good. + --hard removes from the repository, the staging area, and the working + directory. This means that we are getting rid of our work for good.
    @@ -73,38 +67,32 @@

    Undoing commits

    - When we reset commits we need to supply the target position for - the HEAD pointer. In this case, - since we are going to be working with the last commit, we should - tell Git that the target commit for the - HEAD pointer is the commit before - last. So we run + When we reset commits we need to supply the target position for the HEAD + pointer. In this case, since we are going to be working with the last commit, we should tell Git that the + target commit for the HEAD pointer is the commit before last. So we run

    git reset --soft HEAD~1

    - The last commit is now gone from our repository and we have - changes that have already been staged and are ready to be - committed. So it's as if we had never run - git commit that last time. + The last commit is now gone from our repository and we have changes that have already been staged and are + ready to be committed. So it's as if we had never run git commit that + last time.

    - If we instead want to remove changes from the repository and the - staging area, then we run + If we instead want to remove changes from the repository and the staging area, then we run

    git reset --mixed HEAD~1

    - The --mixed option is the - default, so we can omit it. Just as before, the commit is now gone - from the repository. But this time notice that the changes are in - the working directory only. They have not been staged. + The --mixed option is the default, so we can omit it. Just as before, the + commit is now gone from the repository. But this time notice that the changes are in the working directory + only. They have not been staged.

    @@ -117,18 +105,16 @@

    Undoing commits

    - Lastly, if we want to remove changes from the repository, the - staging area, and the working directory, then we run + Lastly, if we want to remove changes from the repository, the staging area, and the working directory, + then we run

    git reset --hard HEAD~1

    - Notice that now, when we run - git status -s Git is staying that - there's nothing there. This is because we just deleted our changes - from everywhere. It's as if we had never written that code to - begin with. + Notice that now, when we run git status -s Git is staying that there's + nothing there. This is because we just deleted our changes from everywhere. It's as if we had never + written that code to begin with.

    diff --git a/pages/060/reverting_commits.html b/pages/060/reverting_commits.html index 2cfefe0..da2e92e 100644 --- a/pages/060/reverting_commits.html +++ b/pages/060/reverting_commits.html @@ -32,32 +32,27 @@

    Reverting commits

    - If we have already shared our work with other people, then we - cannot rewrite its history. Other people may have already built - more features or fixed new bugs on top of our code and rewriting - the history of the project could break their work. For these - situations we use git revert. + If we have already shared our work with other people, then we cannot rewrite its history. Other people may + have already built more features or fixed new bugs on top of our code and rewriting the history of the + project could break their work. For these situations we use git revert.


    - Suppose we want to revert the - last commit. So we run + Suppose we want to revert the last commit. So we run

    git revert HEAD

    - Git will create a new commit after our - HEAD that undoes all changes done in - the HEAD commit. The message for - this commit will be Revert "original_commit_message". + Git will create a new commit after our HEAD that undoes all changes done in + the HEAD commit. The message for this commit will be + Revert "original_commit_message".


    - We can also revert earlier commits with - git revert HEAD~n where - n refers to the commit - n steps prior to HEAD. + We can also revert earlier commits with git revert HEAD~n where + n refers to the commit n steps prior to + HEAD.

    @@ -74,45 +69,38 @@

    Reverting commits

    git revert HEAD~3..HEAD

    - With this, Git will revert all commits from - HEAD~2 to - HEAD. So, Git will not include the - oldest commit. When we revert a range of commits, Git will revert - them one by one, starting from HEAD. - At each commit, Git will open VS Code and ask us to supply a - commit message (or confirm the default one). + With this, Git will revert all commits from HEAD~2 to + HEAD. So, Git will not include the oldest commit. When we revert a range of + commits, Git will revert them one by one, starting from HEAD. At each + commit, Git will open VS Code and ask us to supply a commit message (or confirm the default one).


    - Because our last commit is HEAD, we - can omit it and run - git revert HEAD~3.. and Git will - start from the HEAD pointer. + Because our last commit is HEAD, we can omit it and run + git revert HEAD~3.. and Git will start from the + HEAD pointer.

    - When reverting a range of commits, is better to produce only one - revert commit. This will leave us with a cleaner history. To do - so, we run + When reverting a range of commits, is better to produce only one revert commit. This will leave us with a + cleaner history. To do so, we run

    git revert --no-commit HEAD~3..

    - With this, Git will figure out what changes need to be done, and - apply those changes to the staging area. We can review the changes - and then run + With this, Git will figure out what changes need to be done, and apply those changes to the staging area. + We can review the changes and then run

    git revert --continue

    - Git will open VS Code so that we can write our commit message. If - while reviewing the changes we realize that we don't want to go - ahead with the revert, we can run + Git will open VS Code so that we can write our commit message. If while reviewing the changes we realize + that we don't want to go ahead with the revert, we can run

    git revert --abort From 81311f41fd796394ce48d23ecd98999230def52a Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 23:14:56 +0200 Subject: [PATCH 21/24] Update pages --- .cspell.json | 4 +- pages/035/fast_forward_merging.html | 49 ++--- pages/036/three_way_merges.html | 62 +++---- pages/037/viewing_branches.html | 15 +- pages/038/merge_conflicts.html | 117 +++++------- pages/039/aborting_a_merge.html | 5 +- pages/042/rebasing.html | 132 ++++++-------- pages/043/cherry_picking.html | 42 ++--- .../picking_a_file_from_another_branch.html | 16 +- pages/045/collaboration_workflows.html | 102 ++++------- pages/046/creating_a_github_repository.html | 77 ++++---- pages/047/cloning_a_repository.html | 45 ++--- pages/048/fetching.html | 72 +++----- pages/049/pulling.html | 59 +++--- pages/050/pushing.html | 47 ++--- pages/051/storing_credentials.html | 14 +- pages/052/sharing_tags.html | 11 +- pages/053/releases.html | 54 +++--- pages/054/sharing_branches.html | 129 ++++++------- pages/055/pull_requests.html | 169 +++++++----------- pages/056/github_issues.html | 63 +++---- 21 files changed, 497 insertions(+), 787 deletions(-) diff --git a/.cspell.json b/.cspell.json index 20957cf..588927e 100644 --- a/.cspell.json +++ b/.cspell.json @@ -29,8 +29,8 @@ ], "overrides": [ { - "filename": "**/*.py", - "languageId": "python", + "filename": "**/*.html", + "languageId": "html", }, { "filename": "**/*.yaml", diff --git a/pages/035/fast_forward_merging.html b/pages/035/fast_forward_merging.html index 6986092..2a01b31 100644 --- a/pages/035/fast_forward_merging.html +++ b/pages/035/fast_forward_merging.html @@ -28,12 +28,9 @@

    Fast-forward merging

    - To make a fast-forward merge, first we need to switch to - the branch that we want to merge into. Then we use the - git merge command. For example, - if we want to merge a branch called - bugfix into - master we run + To make a fast-forward merge, first we need to switch to the branch that we want to merge into. + Then we use the git merge command. For example, if we want to merge a + branch called bugfix into master we run

    git merge bugfix @@ -49,47 +46,38 @@

    Fast-forward merging

    - Fast-forward merges have one disadvantage compared to three-way - merges. Since they don't have a merge commit, undoing the merge - (for example if there was a bug in the merged code) can be hard. - So we usually tell Git to not do an ff-merge, even if it's - possible. Let's see this in an example. + Fast-forward merges have one disadvantage compared to three-way merges. Since they don't have a merge + commit, undoing the merge (for example if there was a bug in the merged code) can be hard. So we usually + tell Git to not do an ff-merge, even if it's possible. Let's see this in an example.


    - Since we don't need the old - bugfix branch anymore (because all - its content has already been merged into - master), we delete it and create a - new bugfix branch where we'll fix a - new bug. Once the bug is fixed, we stage and commit the changes, - and switch to master. To merge we - run + Since we don't need the old bugfix branch anymore (because all its content + has already been merged into master), we delete it and create a new + bugfix branch where we'll fix a new bug. Once the bug is fixed, we stage and + commit the changes, and switch to master. To merge we run

    git merge --no-ff bugfix

    - VS Code will open and we'll be asked to write a commit message. In - general, the default message is OK. When we close the VS Code tab, - Git will carry out the merge, using a three-way merge strategy. + VS Code will open and we'll be asked to write a commit message. In general, the default message is OK. + When we close the VS Code tab, Git will carry out the merge, using a three-way merge strategy.

    - Now let's check our log, but using the - --graph option. So we run + Now let's check our log, but using the --graph option. So we run

    git log --oneline --all --graph -5

    - This will show a one-line log of our last 5 commits from all - branches, using the graph display. Here we can see that commit - 4188bbb was created as a commit message that combined - commits e6614d7 and d106b04. + This will show a one-line log of our last 5 commits from all branches, using the graph display. Here we + can see that commit 4188bbb was created as a commit message that combined commits + e6614d7 and d106b04.

    @@ -103,9 +91,8 @@

    Fast-forward merging

    git config ff no

    - This will disable them for this repository alone. If you want to - disable them for all repositories, just add the - --global option. + This will disable them for this repository alone. If you want to disable them for all repositories, just + add the --global option.

    diff --git a/pages/036/three_way_merges.html b/pages/036/three_way_merges.html index ae9d7d6..6d25e98 100644 --- a/pages/036/three_way_merges.html +++ b/pages/036/three_way_merges.html @@ -30,38 +30,32 @@

    Three-way merging

    - To see how three-way merges work, first we'll create a new branch - called new-feature and create a new - file there called main.js. After staging and committing - main.js we switch back to - master. Here we'll update - toc.txt and again, we'll stage and commit the changes. + To see how three-way merges work, first we'll create a new branch called + new-feature and create a new file there called main.js. After + staging and committing main.js we switch back to master. Here we'll + update toc.txt and again, we'll stage and commit the changes.


    - Now we are in the situation described in the three-way merge - scenario. Our target branch (in this case - master) is one commit ahead of the - commit it was when we created the objective branch (in this case - new-feature). Thus, Git can't just - move the master pointer to the - tip of the new-feature branch - because there's a commit in + Now we are in the situation described in the three-way merge scenario. Our target branch (in this case + master) is one commit ahead of the commit it was when we created the + objective branch (in this case new-feature). Thus, Git can't just move the + master pointer to the tip of the + new-feature branch because there's a commit in master that cannot be reached from new-feature.


    - To run a three-way merge we proceed as before and start by - switching into the master branch. - Now we run + To run a three-way merge we proceed as before and start by switching into the + master branch. Now we run

    git merge new-feature

    - VS Code will be launched where we can edit our commit message (if - necessary). When we close it, Git will conclude the merge process. + VS Code will be launched where we can edit our commit message (if necessary). When we close it, Git will + conclude the merge process.

    @@ -74,34 +68,26 @@

    Three-way merging

    - We can see our merges in the - log more clearly by using the + We can see our merges in the log more clearly by using the --graph option

    git log --oneline --all --graph -10

    - Starting from the bottom and moving up, the first merge we see is - the fast-forward merge from the now-deleted - bugfix branch onto - master. This branch was created - from commit d106b04. On it, we created commit - e6614d7. Because at the time of merge - master was still at commit - d106b04 and we used a - --no-ff option, the merge commit - 4188bbb was created. Git shows this merge as a triangle - where each commit is a vertex. + Starting from the bottom and moving up, the first merge we see is the fast-forward merge from the + now-deleted bugfix branch onto master. This + branch was created from commit d106b04. On it, we created commit e6614d7. Because at the + time of merge master was still at commit d106b04 and we used a + --no-ff option, the merge commit 4188bbb was created. Git shows + this merge as a triangle where each commit is a vertex.


    - On the other hand, for our three-way merge, Git is displaying a - trapezoid, since there's a commit on - master (2aa25c1) that was - created after the - new-feature branch was created. - Both branches merged at commit 9a4b466. + On the other hand, for our three-way merge, Git is displaying a trapezoid, since there's a commit on + master (2aa25c1) that was created after the + new-feature branch was created. Both branches merged at commit + 9a4b466.

    diff --git a/pages/037/viewing_branches.html b/pages/037/viewing_branches.html index e7e7e07..1f927e9 100644 --- a/pages/037/viewing_branches.html +++ b/pages/037/viewing_branches.html @@ -30,25 +30,22 @@

    Viewing merged and unmerged branches

    - Sometimes we might forget to delete branches that have already - been merged into master. To check - which branches have already been merged we use + Sometimes we might forget to delete branches that have already been merged into + master. To check which branches have already been merged we use

    git branch --merged

    - Git will return the list of branches that have already been merged - into master. Similarly, to check - which branches have not been merged we run + Git will return the list of branches that have already been merged into + master. Similarly, to check which branches have not been merged we run

    git branch --no-merged

    - We can use these two commands with any branch and Git will show - the list of branches that have merged or have not been merged onto - our current branch. + We can use these two commands with any branch and Git will show the list of branches that have merged or + have not been merged onto our current branch.

    diff --git a/pages/038/merge_conflicts.html b/pages/038/merge_conflicts.html index fd4cbce..d514207 100644 --- a/pages/038/merge_conflicts.html +++ b/pages/038/merge_conflicts.html @@ -30,27 +30,23 @@

    Merge conflicts

    - When merging branches, three different types of conflicts may - arise + When merging branches, three different types of conflicts may arise

    • - The same line of code was changed in different ways in the two - merging branches. + The same line of code was changed in different ways in the two merging branches.
    • - A file was changed in one branch but deleted in the other - branch. + A file was changed in one branch but deleted in the other branch.
    • - The same file is added in different branches, but the content of - the file is different in the two branches. + The same file is added in different branches, but the content of the file is different in the two + branches.

    - Whenever there's a conflict Git will not know how to merge the - branches and it's going to ask us to solve the conflicts manually - before staging and committing the merge. + Whenever there's a conflict Git will not know how to merge the branches and it's going to ask us to solve + the conflicts manually before staging and committing the merge.

    @@ -58,18 +54,14 @@

    Merge conflicts

    - To see an example of the first scenario, let's create a new branch - called bugfix and change the - toc.txt file. In this file, we'll delete all its content - and on the first line write Changes from bugfix branch. - Now stage it and commit it. + To see an example of the first scenario, let's create a new branch called + bugfix and change the toc.txt file. In this file, we'll delete all + its content and on the first line write Changes from bugfix branch. Now stage it and commit it.


    - Next, we'll switch back to master. - Open the toc.txt file. Delete all its content, and in the - first row write Changes from master branch. Stage it. - Commit it. + Next, we'll switch back to master. Open the toc.txt file. Delete + all its content, and in the first row write Changes from master branch. Stage it. Commit it.


    Now we'll run

    @@ -77,11 +69,9 @@

    Merge conflicts

    git merge bugfix

    - Now Git is telling us that there is a conflict and that the - automatic merge process failed. Notice that Git Bash has changed - from master to - master|MERGING. This tells us that - Git is in the middle of a merge process. + Now Git is telling us that there is a conflict and that the automatic merge process failed. Notice that + Git Bash has changed from master to + master|MERGING. This tells us that Git is in the middle of a merge process.

    @@ -98,10 +88,8 @@

    Merge conflicts

    git status

    - Here we can see where the merge conflict is under the unmerged - paths. Git is telling us that both branches have changes to - toc.txt. So let's open toc.txt in VS Code by - running + Here we can see where the merge conflict is under the unmerged paths. Git is telling us that both branches + have changes to toc.txt. So let's open toc.txt in VS Code by running

    code toc.txt @@ -111,12 +99,10 @@

    Merge conflicts

    - The image to the right is what you'll see in VS Code. What we see - are markers that represent the changes in the current branch - (green) and the changes in the other branch (blue). In between - them there's a divider marked by equal signs, =======. - This syntax will be repeated throughout the file as many times as - there are conflicts. + The image to the right is what you'll see in VS Code. What we see are markers that represent the changes + in the current branch (green) and the changes in the other branch (blue). In between them there's a + divider marked by equal signs, =======. This syntax will be repeated throughout the file as many + times as there are conflicts.

    @@ -129,63 +115,51 @@

    Merge conflicts

    - On top of the HEAD marker, there - are three buttons. We need to choose one. If we select - Accept Current Change then the changes from the current - branch will be kept and the incoming ones will be discarded. If - the select Accept Incoming Changes the incoming changes - will be kept and the current ones will be discarded. If we select - Accept Both Changes then both changes will be kept, in - the order in which VS Code is showing them. + On top of the HEAD marker, there are three buttons. We need to choose one. + If we select Accept Current Change then the changes from the current branch will be kept and the + incoming ones will be discarded. If the select Accept Incoming Changes the incoming changes will + be kept and the current ones will be discarded. If we select Accept Both Changes then both + changes will be kept, in the order in which VS Code is showing them.


    - For this demo, I'll go with Accept Both Changes and the - file will change to what you see on the image to the left. + For this demo, I'll go with Accept Both Changes and the file will change to what you see on the + image to the left.

    - Three brief comments before we move on. There's a fourth button - that reads Compare Changes. If you click on it, VS Code - will open the file in diff mode (that is, showing the changes side - by side). + Three brief comments before we move on. There's a fourth button that reads Compare Changes. If + you click on it, VS Code will open the file in diff mode (that is, showing the changes side by side).


    - If you selected an option and wish to change it, even if you have - already saved it, just press Ctrl + z (undo). Git will not - continue with the merge process until we manually create a merge - commit. + If you selected an option and wish to change it, even if you have already saved it, just press Ctrl + z + (undo). Git will not continue with the merge process until we manually create a merge commit.


    - You can always edit the file by hand. To do so, you'll need to - remove the markers and the separation. Try not to include new - changes on the merge commit (that is, new code or new lines of any - sort). But sometimes this is not possible because of the kind of - merge conflict that we are faced with. We refer to merge commits - that add new code as evil commits. + You can always edit the file by hand. To do so, you'll need to remove the markers and the separation. Try + not to include new changes on the merge commit (that is, new code or new lines of any sort). But sometimes + this is not possible because of the kind of merge conflict that we are faced with. We refer to merge + commits that add new code as evil commits.

    - Now that we have resolved all merge conflicts, we can stage our - changes with git add toc.txt. If - we run + Now that we have resolved all merge conflicts, we can stage our changes with + git add toc.txt. If we run

    git status

    - we'll see that now there are no more unmerged paths. Therefore, - there are no more changes. At this point, we can commit our - changes. Since this is a merge commit, we will not introduce a - commit message. So we run + we'll see that now there are no more unmerged paths. Therefore, there are no more changes. At this point, + we can commit our changes. Since this is a merge commit, we will not introduce a commit message. So we run

    git commit @@ -198,13 +172,10 @@

    Merge conflicts

    - Because we didn't provide a commit message, Git will open VS Code. - In general, we accept the default short-message but add a - description explaining how the merge conflicts were resolved. Once - done, we save our changes and close VS Code. Now Git will complete - the merge process. You can see that Git Bash has changed from - master|MERGING to - master. + Because we didn't provide a commit message, Git will open VS Code. In general, we accept the default + short-message but add a description explaining how the merge conflicts were resolved. Once done, we save + our changes and close VS Code. Now Git will complete the merge process. You can see that Git Bash has + changed from master|MERGING to master.

    diff --git a/pages/039/aborting_a_merge.html b/pages/039/aborting_a_merge.html index 52769ae..e8339fc 100644 --- a/pages/039/aborting_a_merge.html +++ b/pages/039/aborting_a_merge.html @@ -30,9 +30,8 @@

    Aborting a merge

    - Sometimes we run into conflicts while merging and we decide that - this is not a good time to solve them. In order to continue - working, we need to abort the merge process. To do so we run + Sometimes we run into conflicts while merging and we decide that this is not a good time to solve them. In + order to continue working, we need to abort the merge process. To do so we run

    git merge --abort diff --git a/pages/042/rebasing.html b/pages/042/rebasing.html index b69df75..60a1925 100644 --- a/pages/042/rebasing.html +++ b/pages/042/rebasing.html @@ -30,22 +30,16 @@

    Rebasing

    - In Git we can change the base commit of a branch by using a - technique called rebasing. - Suppose we have a repository that looks like the one on the - diagram. The way rebasing seems to work is by moving the base - commit of a branch (that is the parent commit of F1). The - problem with rebasing is that this is not true. Commits are - immutable. So what Git actually does is to create new commits (in - this example, F1* and F2*) that come after the - master pointer, and moves the branch - pointer from F2 to F2*. Now there are no pointers or commits pointing to - F2 so - Git will delete them on the next - Garbage Collection cycle. This might be OK if this branch - is local (only you have it on your computer), but if other people - created commits on top of F2 their work will be lost - too!! So be very careful when rebasing. + In Git we can change the base commit of a branch by using a technique called + rebasing. Suppose we have a repository that looks like the one on the + diagram. The way rebasing seems to work is by moving the base commit of a branch (that is the parent + commit of F1). The problem with rebasing is that this is not true. Commits are immutable. So what + Git actually does is to create new commits (in this example, F1* and + F2*) that come after the master pointer, and moves the + branch pointer from F2 to F2*. Now there are no pointers or commits pointing + to F2 so Git will delete them on the next Garbage Collection cycle. This might be OK if + this branch is local (only you have it on your computer), but if other people created commits on top of + F2 their work will be lost too!! So be very careful when rebasing.

    @@ -74,25 +68,19 @@

    Rebasing

    - To see an example of rebasing, I've created a new branch called - feature. In this branch, I've - updated the toc.txt. Back in the - master branch, I've updated the - main.js file. If we look at the log we can see that both - branches have diverged. The new - feature branch is at - 9795f10, master is at - 4104ec7, and their last common ancestor is + To see an example of rebasing, I've created a new branch called feature. In + this branch, I've updated the toc.txt. Back in the master branch, + I've updated the main.js file. If we look at the log we can see that both branches have diverged. + The new feature branch is at 9795f10, + master is at 4104ec7, and their last common ancestor is 6166e28.


    - When we rebase the feature branch we - will change its base commit from 6166e28 (which was the - commit that our master branch was at - when we created the feature branch), - to commit 4104ec7 (which is the commit where - master is now). + When we rebase the feature branch we will change its base commit from + 6166e28 (which was the commit that our master branch was at + when we created the feature branch), to commit 4104ec7 (which is + the commit where master is now).

    @@ -105,39 +93,33 @@

    Rebasing

    - To rebase, make sure that you are on the target branch, in this - case, feature. Now we run + To rebase, make sure that you are on the target branch, in this case, + feature. Now we run

    git rebase master

    - This is telling Git to change the base of the current branch (in - this case feature) with the tip of - the branch that we supply (in this case - master). Usually, when rebasing - there will be conflicts that we must resolve the same way that we - resolve merge conflicts. + This is telling Git to change the base of the current branch (in this case + feature) with the tip of the branch that we supply (in this case + master). Usually, when rebasing there will be conflicts that we must resolve + the same way that we resolve merge conflicts.


    - Now if we check our log we can see that there's a linear path from - master to our - feature branch. If we merge these - branches, Git will do a simple fast-forward merge. But take a - close look at the commit IDs. Before the rebase, the tip of our - branch was at commit 9795f10, now it's at commit - 6f25ebf. This is a new commit! + Now if we check our log we can see that there's a linear path from master to + our feature branch. If we merge these branches, Git will do a simple + fast-forward merge. But take a close look at the commit IDs. Before the rebase, the tip of our branch was + at commit 9795f10, now it's at commit 6f25ebf. This is a new commit!

    - We can checkout to the old commit 9795f10 and use the log - to see the graph. The new tip of the rebased branch is in fact an - entirely new commit. The old one still exists. But there are no - pointers pointing to it, Git will Garbage Collect it. + We can checkout to the old commit 9795f10 and use the log to see the graph. The new tip of the + rebased branch is in fact an entirely new commit. The old one still exists. But there are no pointers + pointing to it, Git will Garbage Collect it.

    @@ -150,11 +132,9 @@

    Rebasing

    - Back on the master branch, we can - now merge the feature branch onto it - and Git will resolve it with a fast-forward merge. If we check out - the log again, we'll see that both branches are now pointing to - the same commit. + Back on the master branch, we can now merge the + feature branch onto it and Git will resolve it with a fast-forward merge. If + we check out the log again, we'll see that both branches are now pointing to the same commit.

    @@ -162,34 +142,29 @@

    Rebasing

    - A few comments about rebasing conflicts. When Git tries to rebase, - it will start by taking the oldest commit in the current branch - and adding it to the tip of the target branch. If there's a - conflict we'll have to open VS Code and solve it the same way we - would solve a merge conflict. But because Git does a rebase one - commit at a time, when we are done, we need to run + A few comments about rebasing conflicts. When Git tries to rebase, it will start by taking the oldest + commit in the current branch and adding it to the tip of the target branch. If there's a conflict we'll + have to open VS Code and solve it the same way we would solve a merge conflict. But because Git does a + rebase one commit at a time, when we are done, we need to run

    git rebase --continue

    - This will let Git know that it can continue to the next commit. If - we wish to skip one commit, we run + This will let Git know that it can continue to the next commit. If we wish to skip one commit, we run

    git rebase --skip

    - Git will not create a copy of that commit and move on to the next - one. If at any point in time we wish to stop the rebase all - together, we run + Git will not create a copy of that commit and move on to the next one. If at any point in time we wish to + stop the rebase all together, we run

    git rebase --abort

    - This will tell Git to stop the rebase and revert everything back - to before we even started. + This will tell Git to stop the rebase and revert everything back to before we even started.

    @@ -197,28 +172,25 @@

    Rebasing

    - If before starting a rebase we already know that we always want to - keep the changes as they are in the - feature branch, we can run the - rebase with the -Xtheirs option. + If before starting a rebase we already know that we always want to keep the changes as they are in the + feature branch, we can run the rebase with the + -Xtheirs option.

    git rebase -Xtheirs NEW_BASE_BRANCH

    - Likewise, if before starting the rebase we already know that we - wish to keep the changes in the - master branch, the we use the - -Xours option. + Likewise, if before starting the rebase we already know that we wish to keep the changes in the + master branch, the we use the -Xours + option.

    git rebase -Xours NEW_BASE_BRANCH

    - This -X option is called the - strategy option. You should keep in mind that when we - supply a strategy to be used by default, said strategy is used in - all commits that are being rebased. + This -X option is called the strategy option. You should keep in + mind that when we supply a strategy to be used by default, said strategy is used in all commits that are + being rebased.

    diff --git a/pages/043/cherry_picking.html b/pages/043/cherry_picking.html index 53530f0..9cbac4f 100644 --- a/pages/043/cherry_picking.html +++ b/pages/043/cherry_picking.html @@ -30,13 +30,10 @@

    Cherry picking

    - Suppose we are working on a new feature on its own branch, but - there's a commit on that branch that we would like to have on - another branch (say master), but we - are not ready to merge the entire branch. This is where - cherry-picking comes in. The cherry-picking tool - allows us to grab a commit from another branch, and apply it to - the tip of our current branch. + Suppose we are working on a new feature on its own branch, but there's a commit on that branch that we + would like to have on another branch (say master), but we are not ready to + merge the entire branch. This is where cherry-picking comes in. The cherry-picking tool + allows us to grab a commit from another branch, and apply it to the tip of our current branch.

    @@ -59,22 +56,18 @@

    Cherry picking

    - As an example, take a look at the git log. Here I've added two - commits to the feature branch (f88ecdc - and fc6e687), and one commit to the - master branch (88c4524). - Now suppose that we want to get the changes made in commit - f88ecdc and apply them to the tip of the - master branch. To cherry-pick this - commit we run + As an example, take a look at the git log. Here I've added two commits to the + feature branch (f88ecdc and fc6e687), and one commit to + the master branch (88c4524). Now suppose that we want to get the + changes made in commit f88ecdc and apply them to the tip of the + master branch. To cherry-pick this commit we run

    git cherry-pick f88ecdc

    - Before cherry-picking commits, be sure to check your current - branch. Your current branch should be the branch into which you - want to bring the target commit. + Before cherry-picking commits, be sure to check your current branch. Your current branch should be the + branch into which you want to bring the target commit.

    @@ -87,20 +80,17 @@

    Cherry picking

    - If we take a look at the log we can see that all previous commits - still exist, but the tip of the - master branch is now - 86bf257 which is a copy of f88ecdc. + If we take a look at the log we can see that all previous commits still exist, but the tip of the + master branch is now 86bf257 which is a copy of f88ecdc.

    - During a cherry-pick, you might run into conflicts. These - conflicts are no different than a - merge conflict. Solve them - using VS Code and then stage and commit your changes. + During a cherry-pick, you might run into conflicts. These conflicts are no different than a + merge conflict. Solve them using VS Code and then stage and commit + your changes.

    diff --git a/pages/044/picking_a_file_from_another_branch.html b/pages/044/picking_a_file_from_another_branch.html index efcb806..06e59f9 100644 --- a/pages/044/picking_a_file_from_another_branch.html +++ b/pages/044/picking_a_file_from_another_branch.html @@ -32,22 +32,18 @@

    Picking a file from another branch

    - Suppose you are working on a branch and need a file from another - branch. As an example, I've created a branch called - feature and made some changes to the - toc.txt file in that branch. Now we switch back to the - master branch and we are going to - bring the last version of toc.txt from the - feature branch onto the + Suppose you are working on a branch and need a file from another branch. As an example, I've created a + branch called feature and made some changes to the toc.txt file in + that branch. Now we switch back to the master branch and we are going to + bring the last version of toc.txt from the feature branch onto the master branch. To do so, we run

    git restore --source=feature -- toc.txt

    - Git will grab that version of the file and place it in our working - tree. We can now stage it and commit it to the - master branch. + Git will grab that version of the file and place it in our working tree. We can now stage it and commit it + to the master branch.

    diff --git a/pages/045/collaboration_workflows.html b/pages/045/collaboration_workflows.html index 211b171..4bc54d0 100644 --- a/pages/045/collaboration_workflows.html +++ b/pages/045/collaboration_workflows.html @@ -32,44 +32,31 @@

    Collaboration workflows

    - When working in collaboration with other people we use hosting - services like GitHub to host a centralized version of the - repository. There are two possible workflows that we can use: - Centralized Workflow or - Integration-Manager Workflow. + When working in collaboration with other people we use hosting services like GitHub to host a centralized + version of the repository. There are two possible workflows that we can use: Centralized Workflow + or Integration-Manager Workflow.


    - In the Centralized Workflow, all collaborators have push - authorization and can thus write changes to the central - repository. They all start by - cloning the central repository to - get a local copy of it on their machines. To keep their copy - up-to-date with what's on the central repository, they use the - pull command. To send their local - changes to the central repository they use the - push command. + In the Centralized Workflow, all collaborators have push authorization and can thus write changes + to the central repository. They all start by cloning the central + repository to get a local copy of it on their machines. To keep their copy up-to-date with what's on the + central repository, they use the pull command. To send their local + changes to the central repository they use the push command.


    - In the Integration-Manager Workflow, only some people - (known as Maintainers) have push access to the - central repository. In order to contribute to these projects, - Contributors need to first - fork the central repository. This - creates a copy of the central repository on GitHub to which they - have push access. Then they must - clone this - forked repository to get a local - copy on their machines. Once they are done with their proposed - changes, they push them into - their forked copy of the - centralized repository, and from it, send a - pull request to the - Maintainer of the original centralized repository. - Maintainers then review the changes and decide whether - they want to pull the changes - into the repository or not. + In the Integration-Manager Workflow, only some people (known as Maintainers) have + push access to the central repository. In order to contribute to these projects, + Contributors need to first fork the central repository. This + creates a copy of the central repository on GitHub to which they have push access. Then they must + clone this forked repository to get a + local copy on their machines. Once they are done with their proposed changes, they + push them into their forked copy of the + centralized repository, and from it, send a pull request to the + Maintainer of the original centralized repository. Maintainers then review the changes + and decide whether they want to pull the changes into the repository or + not.

    @@ -88,43 +75,32 @@

    Collaboration workflows

    - The Centralized Workflow is the workflow we commonly use - for projects with people we know. The - Integration-Manager Workflow is the one commonly used for - open-source projects where anyone can contribute. + The Centralized Workflow is the workflow we commonly use for projects with people we know. The + Integration-Manager Workflow is the one commonly used for open-source projects where anyone can + contribute.


    - Many companies use a hybrid workflow. In this workflow, there are - two roles: the team manager and the contributors, and the - repository is organized in at least three branches. The - master branch is where the - production code lives. The team manager is in charge of - maintaining this branch and of merging Pull Requests. Other team - members work on the staging and - feature branches. When someone needs - to start working on a new feature, they start by creating a new - branch from the staging branch. Once - they are done working, they send a - pull request from the - feature branch to the - staging. Another team member must - approve it before it can be merged on to the - staging branch. + Many companies use a hybrid workflow. In this workflow, there are two roles: the team manager and the + contributors, and the repository is organized in at least three branches. The + master branch is where the production code lives. The team manager is in + charge of maintaining this branch and of merging Pull Requests. Other team members work on the + staging and feature branches. When someone + needs to start working on a new feature, they start by creating a new branch from the + staging branch. Once they are done working, they send a + pull request from the feature branch to the + staging. Another team member must approve it before it can be merged on to + the staging branch.


    - There's usually a server that runs the code in the - staging branch called a - staging server. Once code reaches this branch (and thus - this server) it is presented to clients and/or stakeholders for - approval. If approved, the team manager merges the - staging branch into the - master branch and creates a new - release tag. Code that makes it to - the master branch is run on the - production server and makes up the application or program - that can be accessed by the final users. + There's usually a server that runs the code in the staging branch called a + staging server. Once code reaches this branch (and thus this server) it is presented to clients + and/or stakeholders for approval. If approved, the team manager merges the + staging branch into the master branch and + creates a new release tag. Code that makes it to the + master branch is run on the production server and makes up the + application or program that can be accessed by the final users.

    diff --git a/pages/046/creating_a_github_repository.html b/pages/046/creating_a_github_repository.html index 7ba7c80..42f2d9b 100644 --- a/pages/046/creating_a_github_repository.html +++ b/pages/046/creating_a_github_repository.html @@ -32,19 +32,16 @@

    Creating a GitHub repository

    - When you log on to GitHub, you'll see your home page. On the - left-hand panel you can find your repositories (top) and your - teams (bottom). On the main panel you can see your recent activity - (top) and the recent activity of people you follow or repositories - you've stared. On the right-hand panel GitHub will recommend other - repositories you might be interested in. + When you log on to GitHub, you'll see your home page. On the left-hand panel you can find your + repositories (top) and your teams (bottom). On the main panel you can see your recent activity + (top) and the recent activity of people you follow or repositories you've stared. On the right-hand panel + GitHub will recommend other repositories you might be interested in.


    - To create a new repository on GitHub, login, and on the home page - click the - New button - icon on the left-hand side panel. + To create a new repository on GitHub, login, and on the home page click the + New button icon on the + left-hand side panel.

    @@ -57,54 +54,41 @@

    Creating a GitHub repository

    - Here you can create a new repository. Mandatory fields have a red - asterisk next to them. If you've created - template repositories and want to create a new repository - based on one of your templates you can choose so at the top. A - template repository is a repository that already comes - with certain files and directories. Usually, you will create - templates for things you do quite often and that share some common - structure. + Here you can create a new repository. Mandatory fields have a red asterisk next to them. If you've created + template repositories and want to create a new repository based on one of your templates you can + choose so at the top. A template repository is a repository that already comes with certain files + and directories. Usually, you will create templates for things you do quite often and that share some + common structure.


    - After choosing a name and (optionally) a - description for your repository, you need to choose - whether it will be public or private. Public repositories can be - seen by anyone, but you can still manage who has - push access to them. Private repositories can only be - seen by you and by those with whom you choose to share it with (by - adding them as collaborators). You can manage different levels of - privileges for contributors on private repositories. + After choosing a name and (optionally) a description for your repository, you need to + choose whether it will be public or private. Public repositories can be seen by anyone, but you can still + manage who has push access to them. Private repositories can only be seen by you and by those + with whom you choose to share it with (by adding them as collaborators). You can manage different levels + of privileges for contributors on private repositories.


    - Below this there are three checkboxes. The README file is a - Markdown file where you can explain how to use the repository. Its - content will be displayed on the repositories code tab (more on - that later). I suggest you always create all repositories with a - README file. Next, you can choose to add a - .gitignore file. If you do so, a dropdown menu will - appear where you can choose the language. These are templates that - already come with a list of the files you should normally ignore - when working on the selected language. I suggest you always create - all repositories with a .gitignore file. + Below this there are three checkboxes. The README file is a Markdown file where you can explain how to use + the repository. Its content will be displayed on the repositories code tab (more on that later). I suggest + you always create all repositories with a README file. Next, you can choose to add a .gitignore + file. If you do so, a dropdown menu will appear where you can choose the language. These are templates + that already come with a list of the files you should normally ignore when working on the selected + language. I suggest you always create all repositories with a .gitignore file.


    - Lastly, you can choose a template LICENSE file. These are usually - only used on open-source projects. + Lastly, you can choose a template LICENSE file. These are usually only used on open-source projects.

    - After clicking on the Create Repository button at the - bottom of the page, GitHub will create a new repository for you. - If you selected either a README, .gitignore, or LICENSE then - GitHub will also create the first commit (with an - Initial commit message) and create those files for you. + After clicking on the Create Repository button at the bottom of the page, GitHub will create a + new repository for you. If you selected either a README, .gitignore, or LICENSE then GitHub will also + create the first commit (with an Initial commit message) and create those files for you.

    @@ -114,10 +98,9 @@

    Creating a GitHub repository

    If you need to add collaborators to the repository, go to - Settings > Manage Access > Invite Collaborator section. - You can search for them by name, user name, or email address. Once - you add them, they will receive an invite via email where they can - choose to accept or ignore your invitation. + Settings > Manage Access > Invite Collaborator section. You can search for them by name, user + name, or email address. Once you add them, they will receive an invite via email where they can choose to + accept or ignore your invitation.

    diff --git a/pages/047/cloning_a_repository.html b/pages/047/cloning_a_repository.html index 6a8e5a3..119aaab 100644 --- a/pages/047/cloning_a_repository.html +++ b/pages/047/cloning_a_repository.html @@ -50,35 +50,27 @@

    Cloning a repository

    git clone url directory_name

    - where url is the URL you copied from GitHub and the - directory_name is optional (by default Git will create a - directory with the same name as your repository). + where url is the URL you copied from GitHub and the directory_name is optional (by + default Git will create a directory with the same name as your repository).

    - Now, cd into the directory and - check the log. Here you'll see the two pointers you are already - familiar with, HEAD and - main (remember, - main and - master are the same thing). But - there are also two new pointers - origin/main and - origin/HEAD. + Now, cd into the directory and check the log. Here you'll see the two + pointers you are already familiar with, HEAD and + main (remember, main and + master are the same thing). But there are also two new pointers + origin/main and origin/HEAD.


    - The origin part refers to the GitHub - repository. It's just how Git names it. So, - origin/master is telling us where the - master branch was in that - repository the last time we checked (in this case the last time we - checked was when we cloned the - repository). The same happens with - HEAD, but it tells us where the + The origin part refers to the GitHub repository. It's just how Git names it. + So, origin/master is telling us where the + master branch was in that repository the last time we checked (in this case + the last time we checked was when we cloned the repository). The same + happens with HEAD, but it tells us where the HEAD was the last time we checked.

    @@ -89,9 +81,8 @@

    Cloning a repository

    - Technically these are called Remote tracking branches. - But they don't work like regular branches. You can't - git switch into them, or + Technically these are called Remote tracking branches. But they don't work like regular branches. + You can't git switch into them, or commit to them.

    @@ -106,11 +97,9 @@

    Cloning a repository

    git remote -v

    - A remote is any repository that is not on the current - working directory. Currently, we only have one remote (the origin - on GitHub). The -v option tells - Git to show us the URLs. These are the URLs that will be used when - talking to that remote. + A remote is any repository that is not on the current working directory. Currently, we only have + one remote (the origin on GitHub). The -v option tells Git to show us the + URLs. These are the URLs that will be used when talking to that remote.

    diff --git a/pages/048/fetching.html b/pages/048/fetching.html index 1e1e7d8..3b17667 100644 --- a/pages/048/fetching.html +++ b/pages/048/fetching.html @@ -30,18 +30,16 @@

    Fetching

    - One thing to always keep in mind when working with GitHub is that - your local repository and the remote repository are not connected - and thus, don't sync up automatically when something changes on - either of them. + One thing to always keep in mind when working with GitHub is that your local repository and the remote + repository are not connected and thus, don't sync up automatically when something changes on either of + them.


    - Suppose a situation like the one described in the diagram below. - We start with both the local and remote repositories synced-up. - They both only have one commit (commit A). Next, we make - a commit on the remote repository. Now we need to tell our local - Git repository to sync up with the remote GitHub repository. + Suppose a situation like the one described in the diagram below. We start with both the local and remote + repositories synced-up. They both only have one commit (commit A). Next, we make a commit on the + remote repository. Now we need to tell our local Git repository to sync up with the remote GitHub + repository.

    @@ -66,15 +64,11 @@

    Fetching

    - As an example, let's head on to GitHub and edit the - README.md file. To do so, click on the pencil icon on the - top-right corner of the file. This will open the file on edit - mode. Now, edit the file. Then, scroll to the bottom of the page - and click on the - - button. If we click on the Code tab, we'll see that next - to the README.md on the list of files, the last commit - time has changed to now. + As an example, let's head on to GitHub and edit the README.md file. To do so, click on the pencil + icon on the top-right corner of the file. This will open the file on edit mode. Now, edit the file. Then, + scroll to the bottom of the page and click on the + button. If we click on the Code tab, we'll see that next to the README.md on the list of + files, the last commit time has changed to now.

    @@ -87,10 +81,9 @@

    Fetching

    - Now we are in the situation described in frame 2 of the diagram. - Our remote repository has one more commit than our local - repository. You can verify this by using the - git log command. + Now we are in the situation described in frame 2 of the diagram. Our remote repository has one more commit + than our local repository. You can verify this by using the git log + command.


    To bring the changes into our local repository we run

    @@ -98,42 +91,33 @@

    Fetching

    git fetch remote branch

    - where remote is the name of the - remote from where we want to - fetch and - branch is the name of the branch - in that remote that we want to fetch. If we omit the - branch option, Git will fetch all - branches, and if we omit the - remote option, Git will assume we - want to fetch the origin remote. + where remote is the name of the remote from where we want to + fetch and branch is the name of the + branch in that remote that we want to fetch. If we omit the branch + option, Git will fetch all branches, and if we omit the remote option, + Git will assume we want to fetch the origin remote.


    - Now if we look at the log again, we'll see that - origin/main and - origin/HEAD have both moved one - commit ahead of the local HEAD and - main. We can also check this by + Now if we look at the log again, we'll see that origin/main and + origin/HEAD have both moved one commit ahead of the local + HEAD and main. We can also check this by running

    git branch -vv

    - Git is now telling us that our local - main is behind the remote by 1 - commit. To bring our main branch - forward we merge the remote tracking branch onto the local by - running + Git is now telling us that our local main is behind the remote by 1 commit. + To bring our main branch forward we merge the remote tracking branch onto + the local by running

    git merge origin/main

    - Now, main and - origin/main are pointing to the same - commit. + Now, main and origin/main are pointing to the + same commit.

    diff --git a/pages/049/pulling.html b/pages/049/pulling.html index be0ea59..70da08e 100644 --- a/pages/049/pulling.html +++ b/pages/049/pulling.html @@ -28,26 +28,23 @@

    Pulling

    - Because syncing up the local and remote repositories is so common, - Git has a special command that will - git fetch and - git merge origin/master in one go + Because syncing up the local and remote repositories is so common, Git has a special command that will + git fetch and git merge origin/master in + one go

    git pull

    - To see an example of this, I've created a new commit on GitHub. - Now we run + To see an example of this, I've created a new commit on GitHub. Now we run

    git pull

    - In the Git Bash image, you can see how Git first fetched the - updates and then automatically performed a merge (fast-forward - merge in this case). + In the Git Bash image, you can see how Git first fetched the updates and then automatically performed a + merge (fast-forward merge in this case).

    @@ -58,24 +55,19 @@

    Pulling

    - Since you will probably be working on teams, most of the time - updating your local repository will not be so straightforward - since while you were making commits on your local repository, - other team members were making commits on their local - repositories. Once done, you'll send your changes to the remote - (an action called pushing which - we'll cover next). But what happens if your local - main branch and the remote - main branch have diverge? + Since you will probably be working on teams, most of the time updating your local repository will not be + so straightforward since while you were making commits on your local repository, other team members were + making commits on their local repositories. Once done, you'll send your changes to the remote (an action + called pushing which we'll cover next). But what happens if your local + main branch and the remote main branch have + diverge?


    - Because updating the local repository involves fetching the origin - and merging, the situations you may encounter are the same as when - you merge two local branches: either 1) the other person changed - some file which does not affect the files you are changing, or 2) - you both updated the same file and you'll have to resolve a merger - conflict when pulling. + Because updating the local repository involves fetching the origin and merging, the situations you may + encounter are the same as when you merge two local branches: either 1) the other person changed some file + which does not affect the files you are changing, or 2) you both updated the same file and you'll have to + resolve a merger conflict when pulling.

    @@ -86,27 +78,24 @@

    Pulling

    - Let's see an example of the first situation: you changed some - files in your local repository that have not been changed in the - remote repository. To do this, first we go back to GitHub and - write yet another line in the README.md file. Then we - create a new local file and commit it. Finally, we + Let's see an example of the first situation: you changed some files in your local repository that have not + been changed in the remote repository. To do this, first we go back to GitHub and write yet another line + in the README.md file. Then we create a new local file and commit it. Finally, we git pull.


    - Because our local and remote - main branches had diverged, Git - used a three-way merge and created a merge commit. + Because our local and remote main branches had diverged, Git used a + three-way merge and created a merge commit.

    - Because this creates a non-linear history, some people prefer - using a git pull --rebase. To see - this, first we need to undo the merge commit. Then we run + Because this creates a non-linear history, some people prefer using a + git pull --rebase. To see this, first we need to undo the merge commit. + Then we run

    git pull --rebase diff --git a/pages/050/pushing.html b/pages/050/pushing.html index 3a49335..edff992 100644 --- a/pages/050/pushing.html +++ b/pages/050/pushing.html @@ -30,35 +30,29 @@

    Pushing

    - Once we are finished making changes locally, you have to - push them on to the remote - repository so that others can see them too. To do this we run + Once we are finished making changes locally, you have to push them on to + the remote repository so that others can see them too. To do this we run

    git push remote branch

    - Here branch is the remote branch to which we want to push - to. If we omit it, then Git will assume you want to push to the - main branch. remote refers - to the remote repository to which you wish to push to. If omitted, - Git will assume that you want to push onto origin. + Here branch is the remote branch to which we want to push to. If we omit it, then Git will assume + you want to push to the main branch. remote refers to the remote + repository to which you wish to push to. If omitted, Git will assume that you want to push onto origin.


    - If this is your first time pushing onto a remote, Git will ask for - your GitHub credentials so that it can authenticate and make sure - you have push access. We'll see how to store them next so that you - don't have to supply them every time you push. + If this is your first time pushing onto a remote, Git will ask for your GitHub credentials so that it can + authenticate and make sure you have push access. We'll see how to store them next so that you don't have + to supply them every time you push.


    - Sometimes, others will have pushed their changes before you. If - so, Git will not let you push your changes until you update your - local repository with the remote one. If this is the case, you - just need to pull before you can push. Keep in mind that when - pulling, you may encounter merge conflicts that you will have to - resolve before being able to push. + Sometimes, others will have pushed their changes before you. If so, Git will not let you push your changes + until you update your local repository with the remote one. If this is the case, you just need to pull + before you can push. Keep in mind that when pulling, you may encounter merge conflicts that you will have + to resolve before being able to push.

    @@ -68,8 +62,7 @@

    Pushing

    - Some people online will tell you that when your changes get - rejected, you should force push by running + Some people online will tell you that when your changes get rejected, you should force push by running

    git push -f @@ -79,15 +72,11 @@

    Pushing

    git push --force

    - You should NEVER - EVER - EVER - EVER force push onto a remote - repository unless you have discussed it with your teammates and - everyone is in line with this action. What a force push does is it - tells GitHub that it should discard all commits ahead of your - local repository, and push your changes. So you are throwing away - your teammates work. + You should NEVER EVER + EVER EVER force push onto a remote repository + unless you have discussed it with your teammates and everyone is in line with this action. What a force + push does is it tells GitHub that it should discard all commits ahead of your local repository, and push + your changes. So you are throwing away your teammates work.

    diff --git a/pages/051/storing_credentials.html b/pages/051/storing_credentials.html index a5f4605..0ffb431 100644 --- a/pages/051/storing_credentials.html +++ b/pages/051/storing_credentials.html @@ -28,19 +28,17 @@

    Storing credentials

    - In order to avoid having to enter our GitHub credentials every - time we need to push, we need to store them in our machine. We - have two options here. If we run + In order to avoid having to enter our GitHub credentials every time we need to push, we need to store them + in our machine. We have two options here. If we run

    git config --global credential.helper cache

    - Git will store our credentials in memory for 15 minutes. If we - want to store them on disk we need to use Keychain on - Mac, or Windows Credential Manager on Windows. Either of - these will encrypt our credentials. There's an option for storing - GitHub credentials on plain text files, but it's not recommended. + Git will store our credentials in memory for 15 minutes. If we want to store them on disk we need to use + Keychain on Mac, or Windows Credential Manager on Windows. Either of these will encrypt + our credentials. There's an option for storing GitHub credentials on plain text files, but it's not + recommended.

    diff --git a/pages/052/sharing_tags.html b/pages/052/sharing_tags.html index 0b489f2..9d3801b 100644 --- a/pages/052/sharing_tags.html +++ b/pages/052/sharing_tags.html @@ -30,18 +30,15 @@

    Sharing tags

    - By default, the push command does - not push local tags onto the remote repository - automatically. We need to specifically tell it to push them. To do - so, we run + By default, the push command does not push local tags onto the + remote repository automatically. We need to specifically tell it to push them. To do so, we run

    git push origin tag_name

    - where tag_name is the name we - have our tag when creating it. If you pushed it by accident and - need to delete it from the remote repository, you need to run + where tag_name is the name we have our tag when creating it. If you + pushed it by accident and need to delete it from the remote repository, you need to run

    git push origin --delete tag_name diff --git a/pages/053/releases.html b/pages/053/releases.html index 5293773..1db9fb5 100644 --- a/pages/053/releases.html +++ b/pages/053/releases.html @@ -30,34 +30,28 @@

    Releases

    - Releases are a GitHub (not Git) feature that is built on top of - tags (every release requires a tag). To create one, go to your - repositories home page and, on the right-hand panel, click on - Releases. You'll be directed to the releases page. Now - click on Create a new release. + Releases are a GitHub (not Git) feature that is built on top of tags (every release requires a tag). To + create one, go to your repositories home page and, on the right-hand panel, click on Releases. + You'll be directed to the releases page. Now click on Create a new release.


    - First, we need to give it a Tag version. If we already - have tags we can use one of those. If we don't have a tag, when we - create the release, GitHub will add it to the latest commit on the - branch that we select. + First, we need to give it a Tag version. If we already have tags we can use one of those. If we + don't have a tag, when we create the release, GitHub will add it to the latest commit on the branch that + we select.


    - Next, select the branch. Generally, programs are released based on - the master branch, but you can select any other branch in your - repository. + Next, select the branch. Generally, programs are released based on the master branch, but you can select + any other branch in your repository.


    - Then, write a Release Title. It can be anything you want. - Here I use the tag name. + Then, write a Release Title. It can be anything you want. Here I use the tag name.


    - After that, we can include our release notes. You have to use - Markdown syntax for it. + After that, we can include our release notes. You have to use Markdown syntax for it.

    @@ -67,15 +61,13 @@

    Releases

    - Below that, you'll see the list of files GitHub will include in - the release. By default, it will include all the source code up to - that point in time, but you can add other files like binaries. + Below that, you'll see the list of files GitHub will include in the release. By default, it will include + all the source code up to that point in time, but you can add other files like binaries.


    - If your release is a pre-release (maybe your software is not - stable yet) you can mark it as a pre-release. When done, just - click on the Publish release button. + If your release is a pre-release (maybe your software is not stable yet) you can mark it as a pre-release. + When done, just click on the Publish release button.

    @@ -85,23 +77,19 @@

    Releases

    - You'll be redirected to the releases panel. Here you can see all - your releases and their notes. On the left-hand side, you can see - the commit based on which the release was done. If you click on - Compare you can compare the state of your code at - different releases. + You'll be redirected to the releases panel. Here you can see all your releases and their notes. On the + left-hand side, you can see the commit based on which the release was done. If you click on + Compare you can compare the state of your code at different releases.


    - Next to your user name and the date on the central panel, GitHub - will show you the number of commits that were pushed to that - branch since that release. Currently is not showing anything - because there aren't any new commits. + Next to your user name and the date on the central panel, GitHub will show you the number of commits that + were pushed to that branch since that release. Currently is not showing anything because there aren't any + new commits.


    - Finally, on the right-hand side, you can choose to - Edit or Delete the release. + Finally, on the right-hand side, you can choose to Edit or Delete the release.

    diff --git a/pages/054/sharing_branches.html b/pages/054/sharing_branches.html index 3d665ac..94ace1a 100644 --- a/pages/054/sharing_branches.html +++ b/pages/054/sharing_branches.html @@ -28,17 +28,16 @@

    Sharing branches

    - By default, the branches we create locally, stay local. If we try - to push a local branch onto the remote repository, Git will throw - an error saying that + By default, the branches we create locally, stay local. If we try to push a local branch onto the remote + repository, Git will throw an error saying that the current branch has no upstream branch. If we run

    git branch -vv

    - Git will show us our local and remote tracking branches, and we - can see which ones have an upstream and which ones don't. + Git will show us our local and remote tracking branches, and we can see which ones have an upstream and + which ones don't.


    You can see all remote tracking branches by running

    @@ -56,30 +55,25 @@

    Sharing branches

    - To link a local branch to a remote branch, the first time we push, - we have to run + To link a local branch to a remote branch, the first time we push, we have to run

    git push -u remote branch_name

    where -u is the short version of - --set-upstream, - remote is the name of the remote - repository we want to push to, and - branch_name is the name of the - branch. If we want to push to the GitHub repository, then - remote should be set to - origin. + --set-upstream, remote is the name of + the remote repository we want to push to, and branch_name is the name of + the branch. If we want to push to the GitHub repository, then remote + should be set to origin.

    - Notice that, in this case, we pushed the branch, without anything - new to commit. We just used the push command to tell GitHub that - there's a new pointer that we are going to be keeping track of. + Notice that, in this case, we pushed the branch, without anything new to commit. We just used the push + command to tell GitHub that there's a new pointer that we are going to be keeping track of.


    We can see this by checking the log with

    @@ -105,30 +99,24 @@

    Sharing branches

    - From now on, whenever we want to push local commits onto the - remote tracking branch, we just use the - git push command, the same as we - did with the master branch. + From now on, whenever we want to push local commits onto the remote tracking branch, we just use the + git push command, the same as we did with the master branch.


    - When we push, Git will tell GitHub to store our commits and to - move the remote feature pointer to - the new commit. It will also update the status of the remote - tracking branch on our local repository. + When we push, Git will tell GitHub to store our commits and to move the remote + feature pointer to the new commit. It will also update the status of the + remote tracking branch on our local repository.

    - The same holds true for mergers. Once you are done working locally - and merge your changes onto the local master branch, you can - simply push, and Git and GitHub will sync up and move the pointers - accordingly (assuming no one else pushed to the remote between the - time you pushed the branch and the time you are trying to push the - merge. If that is the case, there might be conflicts for you to - resolve). + The same holds true for mergers. Once you are done working locally and merge your changes onto the local + master branch, you can simply push, and Git and GitHub will sync up and move the pointers accordingly + (assuming no one else pushed to the remote between the time you pushed the branch and the time you are + trying to push the merge. If that is the case, there might be conflicts for you to resolve).

    @@ -141,19 +129,16 @@

    Sharing branches

    - At some point, once you are done and merged your changes, you're - going to need to delete your branch. To delete the remote branch, - we run + At some point, once you are done and merged your changes, you're going to need to delete your branch. To + delete the remote branch, we run

    git push -d remote branch_name

    - But our local branch is still "linked" to the remote (it's - not...that's why Git is telling us that the remote is gone and - it's not showing up on our list of remote tracking branches, but - the local branch still thinks it's there). Just remember to delete - local branches too by running + But our local branch is still "linked" to the remote (it's not...that's why Git is telling us that the + remote is gone and it's not showing up on our list of remote tracking branches, but the local branch still + thinks it's there). Just remember to delete local branches too by running

    git branch -d branch_name @@ -163,15 +148,13 @@

    Sharing branches

    - When collaborating on a branch, any person can create the remote - branch from their local repository and push it like we just saw. - Another way is to create them directly on GitHub. + When collaborating on a branch, any person can create the remote branch from their local repository and + push it like we just saw. Another way is to create them directly on GitHub.


    - All you have to do is to click on the button that says - main and type the name of the new branch. When you press - Enter, GitHub will create the new branch. + All you have to do is to click on the button that says main and type the name of the new branch. + When you press Enter, GitHub will create the new branch.

    @@ -184,10 +167,9 @@

    Sharing branches

    - At this point, our local Git repository has no idea that a new - branch was created on the remote repository. If we pull changes - from the remote, Git will create a new remote tracking branch, but - not a local branch. To do that we run + At this point, our local Git repository has no idea that a new branch was created on the remote + repository. If we pull changes from the remote, Git will create a new remote tracking branch, but not a + local branch. To do that we run

    @@ -195,16 +177,12 @@

    Sharing branches

    - where branch_name is the name of - our local branch and - remote/branch_name is the name of - the remote and the name of the - branch that we wish to track in - that remote. To make this a - little bit more clear, take a look at the Git Bash image. Here - what we are telling Git that the local branch called - bugfix should be paired with the - remote tracking branch + where branch_name is the name of our local branch and + remote/branch_name is the name of the + remote and the name of the branch that + we wish to track in that remote. To make this a little bit more clear, + take a look at the Git Bash image. Here what we are telling Git that the local branch called + bugfix should be paired with the remote tracking branch origin/bugfix.

    @@ -212,36 +190,29 @@

    Sharing branches

    - At some point, you and your teammates are going to finish working - on that branch. Someone should now remove that branch from the - origin (and his/her local). If you are in charge of doing it, it's - just as what we saw before. + At some point, you and your teammates are going to finish working on that branch. Someone should now + remove that branch from the origin (and his/her local). If you are in charge of doing it, it's just as + what we saw before.


    - If it's not you who's in charge of deleting the remote branch - then: first, remember to switch to master on your local repository - and bring in the changes with a pull. This will sync up your local - repository. It should now show the merge commit your teammate did - before deleting the remote branch. + If it's not you who's in charge of deleting the remote branch then: first, remember to switch to master on + your local repository and bring in the changes with a pull. This will sync up your local repository. It + should now show the merge commit your teammate did before deleting the remote branch.


    - Second, delete your local branch by running - git branch -d branch_name just as - before. If you now check your remote tracking branches, you'll see - that the remote is still there. You need to prune it. To do so, - run + Second, delete your local branch by running git branch -d branch_name + just as before. If you now check your remote tracking branches, you'll see that the remote is still there. + You need to prune it. To do so, run

    git remote prune origin

    - Notice that the above command does not mention any particular - remote tracking branch. This is because it will get rid of all - branches with no upstream set. To make sure everything went OK, - run git branch -r, and the remote - tracking branch should be gone now. + Notice that the above command does not mention any particular remote tracking branch. This is because it + will get rid of all branches with no upstream set. To make sure everything went OK, run + git branch -r, and the remote tracking branch should be gone now.

    diff --git a/pages/055/pull_requests.html b/pages/055/pull_requests.html index cb02486..38ce1b5 100644 --- a/pages/055/pull_requests.html +++ b/pages/055/pull_requests.html @@ -30,11 +30,9 @@

    Pull requests

    - A Pull Request (from now on, PR) is a way of opening a - discussion on a repository so that we can get feedback from other - team members on our code. In many organizations, opening PRs to - merge code into production or staging branches, and reviewing - other's people code is mandatory, even for the most senior + A Pull Request (from now on, PR) is a way of opening a discussion on a repository so that we can + get feedback from other team members on our code. In many organizations, opening PRs to merge code into + production or staging branches, and reviewing other's people code is mandatory, even for the most senior developers.

    @@ -42,12 +40,10 @@

    Pull requests

    - To see a scenario, let's suppose we just created a new commit on a - branch called bugfix and we pushed - it to the remote repository. If we now go to GitHub, we'll see the - message to create a PR. To start creating a PR, click on it. - Alternatively, you can go to the Pull Requests tab and start it - from there. + To see a scenario, let's suppose we just created a new commit on a branch called + bugfix and we pushed it to the remote repository. If we now go to GitHub, + we'll see the message to create a PR. To start creating a PR, click on it. Alternatively, you can go to + the Pull Requests tab and start it from there.

    @@ -57,26 +53,19 @@

    Pull requests

    - You'll see a screen like the one below. First, we need to select - two branches. The base branch is the branch that we want - to merge our code into (here we'll choose main), our - compare branch is the branch that has the code we want to - merge into the base branch (in this case, I called the - branch bugfix). Next to the branch selectors, GitHub is telling us - that this branch can be merged without generating conflicts. This - is will not always be the case. If GitHub tells us that there are - conflicts that will have to be resolved that's OK, first our code - needs to be approved by our teammates anyway. + You'll see a screen like the one below. First, we need to select two branches. The base branch is + the branch that we want to merge our code into (here we'll choose main), our compare branch is + the branch that has the code we want to merge into the base branch (in this case, I called the + branch bugfix). Next to the branch selectors, GitHub is telling us that this branch can be merged without + generating conflicts. This is will not always be the case. If GitHub tells us that there are conflicts + that will have to be resolved that's OK, first our code needs to be approved by our teammates anyway.


    - Below that we can see the summary of changes. GitHub is telling us - that this PR will include 1 commit, with changes to 1 file. After - that, it shows us a graph of the involved commits. At the bottom - we can see the diffs for the different files (you can toggle the - views by pressing the Unified and Split buttons on the right). - When you are done reviewing this page, click on - Create pull request. + Below that we can see the summary of changes. GitHub is telling us that this PR will include 1 commit, + with changes to 1 file. After that, it shows us a graph of the involved commits. At the bottom we can see + the diffs for the different files (you can toggle the views by pressing the Unified and Split buttons on + the right). When you are done reviewing this page, click on Create pull request.

    @@ -88,20 +77,16 @@

    Pull requests

    - In this new screen we need to first enter the PR's title. Because - this PR has only 1 commit, GitHub used the commit message as a PR - title. Usually you should change it to something more meaningful, - related to the task at hand (like feature name or bugfix and the - ID of the bugfix task). + In this new screen we need to first enter the PR's title. Because this PR has only 1 commit, GitHub used + the commit message as a PR title. Usually you should change it to something more meaningful, related to + the task at hand (like feature name or bugfix and the ID of the bugfix task).


    - In the details section of the PR you can write whatever you want. - Usually we list the changes or functions that were implemented - plus a short description of what they do. If there's any part of - your code that you want your teammates to pay special attention - to, this is where you should include that. When ready, click on - the Create pull request button. + In the details section of the PR you can write whatever you want. Usually we list the changes or functions + that were implemented plus a short description of what they do. If there's any part of your code that you + want your teammates to pay special attention to, this is where you should include that. When ready, click + on the Create pull request button.

    @@ -113,22 +98,18 @@

    Pull requests

    - Now, if a reviewer was not assigned automatically, you need to - assign one. You can assign more than one too. The yellow dot next - to each reviewer's name indicates that they are still to respond - to the review request. + Now, if a reviewer was not assigned automatically, you need to assign one. You can assign more than one + too. The yellow dot next to each reviewer's name indicates that they are still to respond to the review + request.


    - From now on I'll be changing roles in this demo playing the role - of the creator of the PR and the reviewer, but I'll always use the - pronoun you since in the real world you'll have to do both: - sometimes you'll be the creator of the PR (when you are sharing - your code with your teammates and need someone to review it), and - sometimes you'll be the reviewer (when another teammate is - submitting code and asking that you review it). When playing the - PR creator's role the screen will be in dark theme. When playing - the role of the reviewer it will be in light theme. + From now on I'll be changing roles in this demo playing the role of the creator of the PR and the + reviewer, but I'll always use the pronoun you since in the real world you'll have to do both: sometimes + you'll be the creator of the PR (when you are sharing your code with your teammates and need someone to + review it), and sometimes you'll be the reviewer (when another teammate is submitting code and asking that + you review it). When playing the PR creator's role the screen will be in dark theme. When playing the role + of the reviewer it will be in light theme.

    @@ -141,19 +122,17 @@

    Pull requests

    - When someone asks for their code to be reviewed by you, GitHub - will send you an email. Upon logging into GitHub you'll see a - message that says that a teammate requested a review from you. - Click on the Add your review button. + When someone asks for their code to be reviewed by you, GitHub will send you an email. Upon logging into + GitHub you'll see a message that says that a teammate requested a review from you. Click on the + Add your review button.

    - You can now add comments to every and any line of code you think - needs one. When you hover over a line, a blue plus sign will - appear. To add a comment click on it. + You can now add comments to every and any line of code you think needs one. When you hover over a line, a + blue plus sign will appear. To add a comment click on it.

    @@ -168,28 +147,24 @@

    Pull requests

    - After adding all of your comments, click on the - Review changes button in the top-right corner. Here you - can add a general message and approve, comment, or request changes - from the PR owner (the teammate who submitted it). + After adding all of your comments, click on the Review changes button in the top-right corner. + Here you can add a general message and approve, comment, or request changes from the PR owner (the + teammate who submitted it).

    - Let's go back to supposing that you are the person who created the - PR now. When the reviewer submits the review, you'll get an email - from GitHub saying that your code has been reviewed. Since in this - case changes were requested, you'll see a red icon next to the - reviewer’s name. + Let's go back to supposing that you are the person who created the PR now. When the reviewer submits the + review, you'll get an email from GitHub saying that your code has been reviewed. Since in this case + changes were requested, you'll see a red icon next to the reviewer's name.


    - Next, you'll go back to the code, implement the requested changes - (if you agree with them of course), and push the new commit onto - the remote repository. Now you can request a new review by - pressing the arrows next to the red icon. + Next, you'll go back to the code, implement the requested changes (if you agree with them of course), and + push the new commit onto the remote repository. Now you can request a new review by pressing the arrows + next to the red icon.

    @@ -202,20 +177,17 @@

    Pull requests

    - Back in the reviewer's role. You received an email from your - teammate saying that there's a new version of the code. You review - it again and since you are now OK with the code, you click on the - Viewed button. Now you submit a new review, this time - approving the changes. + Back in the reviewer's role. You received an email from your teammate saying that there's a new version of + the code. You review it again and since you are now OK with the code, you click on the Viewed + button. Now you submit a new review, this time approving the changes.

    - The person who submitted the PR will now see a green check mark - next to the reviewer's name. So now it's time to merge the PR onto - the base branch. + The person who submitted the PR will now see a green check mark next to the reviewer's name. So now it's + time to merge the PR onto the base branch.

    @@ -228,34 +200,28 @@

    Pull requests

    - Back in the PR's discussion panel you'll see a - Merge pull request at the bottom. Who should merge is - something that depends on the type of project and the culture and - rules of the organization. Some prefer that a person other than - the one who opened the PR merges it, some prefer the person who - created it to merge it. Just follow the rules and customs of your - organization. + Back in the PR's discussion panel you'll see a Merge pull request at the bottom. Who should merge + is something that depends on the type of project and the culture and rules of the organization. Some + prefer that a person other than the one who opened the PR merges it, some prefer the person who created it + to merge it. Just follow the rules and customs of your organization.


    - To merge, all you have to do is select the type of merge and click - on the merge button. + To merge, all you have to do is select the type of merge and click on the merge button.

    - Once done, don't forget to delete the branch. To delete the remote - branch you can just click on delete branch. To delete the local - branch on your computer, remember to first pull, switch to main, - and then delete and prune. + Once done, don't forget to delete the branch. To delete the remote branch you can just click on delete + branch. To delete the local branch on your computer, remember to first pull, switch to main, and then + delete and prune.


    - If you delete a branch by mistake, don't worry. Once you click on - the Delete branch button, it'll change to - Restore branch. + If you delete a branch by mistake, don't worry. Once you click on the Delete branch button, it'll + change to Restore branch.

    @@ -269,13 +235,10 @@

    Pull requests

    - As a side note, if during the PR process conflicts with the - base branch appear, you'll see this message on the PR - panel. You can resolve the conflict the same way as we saw before - using VS Code, or you can click on the - Resolve conflicts button on GitHub. Either way you do it, - the conflict is resolved the same way and the interface is pretty - much the same. + As a side note, if during the PR process conflicts with the base branch appear, you'll see this + message on the PR panel. You can resolve the conflict the same way as we saw before using VS Code, or you + can click on the Resolve conflicts button on GitHub. Either way you do it, the conflict is + resolved the same way and the interface is pretty much the same.

    diff --git a/pages/056/github_issues.html b/pages/056/github_issues.html index 312434e..1a1c86e 100644 --- a/pages/056/github_issues.html +++ b/pages/056/github_issues.html @@ -30,13 +30,11 @@

    GitHub issues

    - GitHub issues are a tool for collaboration. We can use issues to - document bugs or to start discussions with our team. Every issue - needs a clear title and a description of what the issue is about. - Also, on the right-hand side menu, we can assign issues to people - (or to ourselves), label issues, assign them as parts of projects, - or milestones. We can also link issues with PRs. Issues that are - linked to PRs will be closed when the PR is merged. + GitHub issues are a tool for collaboration. We can use issues to document bugs or to start discussions + with our team. Every issue needs a clear title and a description of what the issue is about. Also, on the + right-hand side menu, we can assign issues to people (or to ourselves), label issues, assign them as parts + of projects, or milestones. We can also link issues with PRs. Issues that are linked to PRs will be closed + when the PR is merged.

    @@ -48,14 +46,12 @@

    GitHub issues

    - Here I've created an example issue. Once someone creates an issue, - others con post to the conversation or share their reactions to - what is being said. + Here I've created an example issue. Once someone creates an issue, others con post to the conversation or + share their reactions to what is being said.


    - If we mention an issue in a commit message, it will be shown on - the issue thread. + If we mention an issue in a commit message, it will be shown on the issue thread.


    GitHub issues 3 @@ -70,14 +66,11 @@

    GitHub issues

    - Alternatively, if we think that the issue can be closed after we - push certain changes, we can do so from the commit message. In - order to do so, our commit message must include the pattern - keyword #issue. The valid - keywords are: close, closes, closed, fix, fixes, fixed, resolve, - resolves, resolved. We can close multiple issues with one commit - by using commas to separate them. If we want to include a more - comprehensive message we can do so with a semicolon. + Alternatively, if we think that the issue can be closed after we push certain changes, we can do so from + the commit message. In order to do so, our commit message must include the pattern + keyword #issue. The valid keywords are: close, closes, closed, fix, + fixes, fixed, resolve, resolves, resolved. We can close multiple issues with one commit by using commas to + separate them. If we want to include a more comprehensive message we can do so with a semicolon.

    @@ -91,21 +84,17 @@

    GitHub issues

    - Notice that, even though this was our first issue, GitHub gave it - a number two. That is because issues and PRs use the same counter. - Every time we create a new issue or PR, the counter moves up by - one. + Notice that, even though this was our first issue, GitHub gave it a number two. That is because issues and + PRs use the same counter. Every time we create a new issue or PR, the counter moves up by one.

    - I've created a new issue with the bug label. In the label - tab, we can see all the default labels that all GitHub - repositories come with. We can edit these labels or create new - ones. On the labels tab GitHub will also show us the number of - open issues or PRs that have that label. + I've created a new issue with the bug label. In the label tab, we can see all the default labels + that all GitHub repositories come with. We can edit these labels or create new ones. On the labels tab + GitHub will also show us the number of open issues or PRs that have that label.


    We can assign more than one label per issue.

    @@ -120,20 +109,17 @@

    GitHub issues

    - A related concept to that of issues is milestones. We use - milestones for tasks that are composed of more than one issue. To - create milestones go to the milestones tab (next to the issues - tab). Milestones need a title and can optionally have a due date - and a description. + A related concept to that of issues is milestones. We use milestones for tasks that are composed + of more than one issue. To create milestones go to the milestones tab (next to the issues tab). Milestones + need a title and can optionally have a due date and a description.

    - Once we've created a milestone, we can also create issues and - assign them to the corresponding milestone. We can also create a - label that refers to this milestone. + Once we've created a milestone, we can also create issues and assign them to the corresponding milestone. + We can also create a label that refers to this milestone.

    @@ -146,8 +132,7 @@

    GitHub issues

    - As we work on the new milestone and close issues, GitHub will - update the progress of our milestone. + As we work on the new milestone and close issues, GitHub will update the progress of our milestone.

    From ff3cc14ae147e3bc2536ab0321270dd4c4d9bc0c Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 23:24:57 +0200 Subject: [PATCH 22/24] Update pages --- pages/026/viewing_the_history_of_a_file.html | 10 +-- pages/027/restoring_a_deleted_file.html | 24 ++---- pages/028/blaming.html | 20 ++--- pages/029/tagging.html | 67 ++++++--------- pages/030/what_are_branches.html | 17 ++-- pages/031/working_with_branches.html | 32 +++---- pages/032/comparing_branches.html | 29 +++---- pages/033/stashing.html | 87 +++++++------------- pages/034/merging.html | 29 +++---- 9 files changed, 119 insertions(+), 196 deletions(-) diff --git a/pages/026/viewing_the_history_of_a_file.html b/pages/026/viewing_the_history_of_a_file.html index 55708cd..1c38af7 100644 --- a/pages/026/viewing_the_history_of_a_file.html +++ b/pages/026/viewing_the_history_of_a_file.html @@ -36,13 +36,9 @@

    Viewing the history of a file

    git log file_path/file_name.ext

    - Here we can also use the - --oneline option for showing a - less verbose version of the log, the - --stat option to see stats of - what changed, or the - --patch option to see the actual - changes. + Here we can also use the --oneline option for showing a less verbose + version of the log, the --stat option to see stats of what changed, or + the --patch option to see the actual changes.

    diff --git a/pages/027/restoring_a_deleted_file.html b/pages/027/restoring_a_deleted_file.html index b0f5a0f..bb106b6 100644 --- a/pages/027/restoring_a_deleted_file.html +++ b/pages/027/restoring_a_deleted_file.html @@ -30,31 +30,25 @@

    Restoring a deleted file

    - We can restore files that we deleted in previous commits. Suppose - that we accidentally removed app.py and now we need it - back. The first thing that we need to do is find the last commit - where that file was not deleted. To do that we run + We can restore files that we deleted in previous commits. Suppose that we accidentally removed + app.py and now we need it back. The first thing that we need to do is find the last commit where + that file was not deleted. To do that we run

    git log --oneline -- app.py

    - So far nothing new. Now, since the file will show up on the commit - in which we delete it, the last commit were the file was not - deleted is the second commit from the top: commit - 8eec1d2. What we need to do now is to - git checkout just that file from - that commit. So we run + So far nothing new. Now, since the file will show up on the commit in which we delete it, the last commit + were the file was not deleted is the second commit from the top: commit 8eec1d2. What we need to + do now is to git checkout just that file from that commit. So we run

    git checkout 8eec1d2 app.py

    - Git will take the file as it was at that point in time and place - it in our staging area. That is why if we run a - git status -s we can see that the - file has an A on the left column. - Lastly, we commit the file to the repository. + Git will take the file as it was at that point in time and place it in our staging area. That is why if we + run a git status -s we can see that the file has an + A on the left column. Lastly, we commit the file to the repository.

    diff --git a/pages/028/blaming.html b/pages/028/blaming.html index bd7d416..a3141fd 100644 --- a/pages/028/blaming.html +++ b/pages/028/blaming.html @@ -30,29 +30,23 @@

    Blaming

    - We use blame to find the author - of a particular line. To do so we run + We use blame to find the author of a particular line. To do so we run

    git blame file_path/file_name.ext

    - Git will display the entire file, line by line, with the commit ID - in which that line was last changed and the name of the person who - changed it. We could add the email with the - -e option. + Git will display the entire file, line by line, with the commit ID in which that line was last changed and + the name of the person who changed it. We could add the email with the -e + option.


    - If we don't want to see all the lines in the file we use the - -L option and supply the line - numbers from where to start and end. + If we don't want to see all the lines in the file we use the -L option + and supply the line numbers from where to start and end.

    - - git blame -L start_line,end_line - file_path/file_name.ext - + git blame -L start_line,end_line file_path/file_name.ext
    diff --git a/pages/029/tagging.html b/pages/029/tagging.html index 598469b..ab18482 100644 --- a/pages/029/tagging.html +++ b/pages/029/tagging.html @@ -30,34 +30,28 @@

    Tagging

    - Once our project has reached a stable version, we will release it. - That doesn't mean we'll never work on it again. A common and - recommended practice is to bookmark the commit where a release - happened. To do so we use a tag. + Once our project has reached a stable version, we will release it. That doesn't mean we'll never work on + it again. A common and recommended practice is to bookmark the commit where a release happened. To do so + we use a tag.


    - Now, suppose we want to create a release for our project right - before the point in which we introduced app.py. We check - the log and see that this means creating a - tag at commit a642e12. - To do so we run + Now, suppose we want to create a release for our project right before the point in which we introduced + app.py. We check the log and see that this means creating a tag + at commit a642e12. To do so we run

    git tag v1.0 a642e12

    - This will tell Git that we want to make a - tag called v1.0 at - commit a642e12. If we check the log now, we will see that - Git has added that tag at that commit. + This will tell Git that we want to make a tag called v1.0 at + commit a642e12. If we check the log now, we will see that Git has added that tag at that commit.


    - These type of tags are called - lightweight tags because they are just pointers to a - specific commit. A better way is to use annotated tags. - These tags take a release message too. + These type of tags are called lightweight tags because they are + just pointers to a specific commit. A better way is to use annotated tags. These tags take a + release message too.

    @@ -70,25 +64,22 @@

    Tagging

    - First, let's delete the lightweight tag. To do this we use the - -d option and supply the tag - name, like so + First, let's delete the lightweight tag. To do this we use the -d option + and supply the tag name, like so

    git tag -d v1.0

    - You can check the log now and you'll see that the tag is not there - anymore. + You can check the log now and you'll see that the tag is not there anymore.

    - To create an annotated tag we use the - -a option and supply it a message - with the -m option + To create an annotated tag we use the -a option and supply it a + message with the -m option

    git tag -a v1.0 -m "Version 1.0" a642e12 @@ -98,17 +89,14 @@

    Tagging

    git tag -a v2.0 -m "Version 2.0" c674d68

    - Our log now shows that we have two tags pointing at different - commits. + Our log now shows that we have two tags pointing at different commits.


    - But v2.0 had a bug which we fixed in our last commit. So - we'll release a new version of our program. The difference is that - since we now only fixed a bug instead of introducing new - functionality, we'll increment the tag minor instead of the major. - Since we are releasing a tag at the last commit, we don't need to - supply a commit ID + But v2.0 had a bug which we fixed in our last commit. So we'll release a new version of our + program. The difference is that since we now only fixed a bug instead of introducing new functionality, + we'll increment the tag minor instead of the major. Since we are releasing a tag at the last commit, we + don't need to supply a commit ID

    git tag -a v2.1 -m "Version 2.1" @@ -128,19 +116,16 @@

    Tagging

    git tag -n

    - Once we have tags, we can checkout to those points in our commit - history by name instead of using the commit ID. For example, - running + Once we have tags, we can checkout to those points in our commit history by name instead of using the + commit ID. For example, running

    git checkout v1.0

    - moves the HEAD to the - v1.0 tag. Keep in mind that you are in a - 'detached HEAD' state now, so - you'll need to checkout to - master again when done. + moves the HEAD to the v1.0 tag. Keep in mind that you are in a + 'detached HEAD' state now, so you'll need to + checkout to master again when done.

    diff --git a/pages/030/what_are_branches.html b/pages/030/what_are_branches.html index a95149f..ef05169 100644 --- a/pages/030/what_are_branches.html +++ b/pages/030/what_are_branches.html @@ -30,17 +30,13 @@

    What are branches?

    - Branching allows us to divert from the main line of work, and work - in something different in isolation. This allows us to develop new - features without compromising the stability of our production - code. + Branching allows us to divert from the main line of work, and work in something different in isolation. + This allows us to develop new features without compromising the stability of our production code.


    - Branches in Git are fast and cheap because they are just pointers - to different commits in a commit tree. Likewise, Git knows which - branch we are working on by using another pointer called - HEAD. + Branches in Git are fast and cheap because they are just pointers to different commits in a commit tree. + Likewise, Git knows which branch we are working on by using another pointer called HEAD.

    @@ -53,9 +49,8 @@

    What are branches?

    - When we move from one branch to the other, what Git does is to - reposition the HEAD pointer to the pointer of that - branch. + When we move from one branch to the other, what Git does is to reposition the HEAD pointer to the + pointer of that branch.

    diff --git a/pages/031/working_with_branches.html b/pages/031/working_with_branches.html index 76acd83..7a77081 100644 --- a/pages/031/working_with_branches.html +++ b/pages/031/working_with_branches.html @@ -32,18 +32,15 @@

    Working with branches

    - Suppose we got a bug report. To fix this bug we should first - create a new branch. This way any changes that we do to our code - can be tested before we merge them into production. To create a - new branch we run + Suppose we got a bug report. To fix this bug we should first create a new branch. This way any changes + that we do to our code can be tested before we merge them into production. To create a new branch we run

    git branch new_branch_name

    - If we run git branch, Git will - return a list of the branches our project has. The branch we are - currently in will have an asterisk next to its name. + If we run git branch, Git will return a list of the branches our project + has. The branch we are currently in will have an asterisk next to its name.


    To switch branches we run

    @@ -65,32 +62,29 @@

    Working with branches

    - Now that we are in the new branch, we can work on fixing the bug. - Once we are done, we need to stage and commit our changes. + Now that we are in the new branch, we can work on fixing the bug. Once we are done, we need to stage and + commit our changes.


    - Suppose we've done all that. If we take a look at the log now - we'll see that our bugfix branch is ahead of the master branch. If - we switch back to the master branch, we'll see that the bug is - still there. We still need to merge our branches. + Suppose we've done all that. If we take a look at the log now we'll see that our bugfix branch is ahead of + the master branch. If we switch back to the master branch, we'll see that the bug is still there. We still + need to merge our branches.

    - Once we are done with a branch, we should delete it. To do so we - run + Once we are done with a branch, we should delete it. To do so we run

    git branch -d branch_name

    - Keep in mind that if the changes that you did in that branch have - not been merged into the master branch, Git will complain about - this action. This is to protect you from accidentally deleting - work you still need. To override this protection we use + Keep in mind that if the changes that you did in that branch have not been merged into the master branch, + Git will complain about this action. This is to protect you from accidentally deleting work you still + need. To override this protection we use

    git branch -D branch_name diff --git a/pages/032/comparing_branches.html b/pages/032/comparing_branches.html index 2b564f3..9cda60b 100644 --- a/pages/032/comparing_branches.html +++ b/pages/032/comparing_branches.html @@ -30,18 +30,16 @@

    Comparing branches

    - At some point, we'll have to merge our branches to master. To get - a list of the commits that will be merged into the master branch - when we do so, we use + At some point, we'll have to merge our branches to master. To get a list of the commits that will be + merged into the master branch when we do so, we use

    git log master..branch_name

    - With this, Git will give us a list of all the commits that are in - the other branch, but not in master. Just as before, we can use - the --oneline option to make the - output more concise. + With this, Git will give us a list of all the commits that are in the other branch, but not in master. + Just as before, we can use the --oneline option to make the output more + concise.

    @@ -54,29 +52,26 @@

    Comparing branches

    - If want to see the actual changes we use the - diff command + If want to see the actual changes we use the diff command

    git diff master..branch_name

    - Here Git will show us the diff of - the different files that will be affected by the merge. + Here Git will show us the diff of the different files that will be + affected by the merge.


    - When diffing branches we don't always have to type both branches. - If we want to see the - diff between the branch we are - currently in and another branch we just run + When diffing branches we don't always have to type both branches. If we want to see the + diff between the branch we are currently in and another branch we just + run

    git diff branch_name

    - If we only want a list of the files that will change and the type - of change, we can use the + If we only want a list of the files that will change and the type of change, we can use the --name-status option

    diff --git a/pages/033/stashing.html b/pages/033/stashing.html index 98b1a0a..35c58fc 100644 --- a/pages/033/stashing.html +++ b/pages/033/stashing.html @@ -30,37 +30,30 @@

    Stashing

    - Suppose we are working on a new feature and we realize that we - forgot to create a new branch before starting. We could throw away - our work and create a new branch. But that would - involve...well...throwing away our work. We can solve this - situation by stashing our work. + Suppose we are working on a new feature and we realize that we forgot to create a new branch before + starting. We could throw away our work and create a new branch. But that would involve...well...throwing + away our work. We can solve this situation by stashing our work.


    - As an example, suppose we created the new calc.py on - master and now we want to move it - into a new branch called - calc-functions. First we need to + As an example, suppose we created the new calc.py on master and now + we want to move it into a new branch called calc-functions. First we need to stash our un-tracked file. To so we run

    git stash push -u -m "calc functions"

    - We use the -u option here because - our file was un-tracked. More on that below. Now that we've stash - our changes, we can switch into a new branch with + We use the -u option here because our file was un-tracked. More on that + below. Now that we've stash our changes, we can switch into a new branch with

    git switch -C "calc-functions"

    - This will create a new branch called - calc-functions and the - -C option with tell Git to also - switch into it. Now that we are - in the new branch, we can unpack our stashed changes by running + This will create a new branch called calc-functions and the + -C option with tell Git to also switch + into it. Now that we are in the new branch, we can unpack our stashed changes by running

    git stash pop @@ -74,8 +67,7 @@

    Stashing

    - If you are left wondering how does this work, here's a simplified - explanation. + If you are left wondering how does this work, here's a simplified explanation.

    @@ -88,17 +80,13 @@

    Stashing

    - When we invoke - git stash Git commits our - changes and creates a new type of reference called a - stash from where it can access that new commit - (technically there are several commits involved depending on - what we are stashing, you can read all about it + When we invoke git stash Git commits our changes and creates a new + type of reference called a stash from where it can access that new commit (technically + there are several commits involved depending on what we are stashing, you can read all about it here - - ). + ).

    @@ -108,8 +96,7 @@

    Stashing

    - When we switch branches Git just moves the - HEAD reference to the tip of that branch. + When we switch branches Git just moves the HEAD reference to the tip of that branch.

    @@ -119,9 +106,8 @@

    Stashing

    - Finally, when we pop our - stashed commit, Git adds the content of that commit to the - working directory in that branch. + Finally, when we pop our stashed commit, Git adds the content of + that commit to the working directory in that branch.

    @@ -149,11 +135,9 @@

    Stashing

    - One thing to keep in mind here is the difference between - git stash pop and - git stash apply. They both add - the content of the stash to the working directory of that branch, - but while pop deletes the stash, + One thing to keep in mind here is the difference between git stash pop + and git stash apply. They both add the content of the stash to the + working directory of that branch, but while pop deletes the stash, apply does not.

    @@ -167,15 +151,11 @@

    Stashing

    git stash list

    - Git keeps track of which stash was added first and which one was - added last. The stash at the top of the list is the one that was - added last. When we run - git stash apply (or - pop) this is the stash that will - be applied by default. But each stash has a unique identifier - called stash@{n} where n is its position on the - stash stack. You can use these identifiers (or just the - n number) to reference them when popping or applying. + Git keeps track of which stash was added first and which one was added last. The stash at the top of the + list is the one that was added last. When we run git stash apply (or + pop) this is the stash that will be applied by default. But each stash + has a unique identifier called stash@{n} where n is its position on the stash stack. You + can use these identifiers (or just the n number) to reference them when popping or applying.

    @@ -188,18 +168,16 @@

    Stashing

    - One place in which this references come in handy is when viewing - the changes of a stash. When we have more than one stash we should - check what's in a stash before applying in to the working - directory. To do this we run + One place in which this references come in handy is when viewing the changes of a stash. When we have more + than one stash we should check what's in a stash before applying in to the working directory. To do this + we run

    git stash show n

    - where n is the reference. With - this Git will show us what changes are done in each stash so that - we can choose which one we want to apply. + where n is the reference. With this Git will show us what changes are + done in each stash so that we can choose which one we want to apply.


    Once we select the stash to apply, we can do so with

    @@ -207,8 +185,7 @@

    Stashing

    git stash apply n

    - Once we are done with our stashes we should delete them. Here we - can use + Once we are done with our stashes we should delete them. Here we can use

    git stash drop n diff --git a/pages/034/merging.html b/pages/034/merging.html index 33a895a..12707d6 100644 --- a/pages/034/merging.html +++ b/pages/034/merging.html @@ -30,31 +30,24 @@

    Merging

    - Merging is the action of bringing the changes in one branch onto - another branch. In Git there are two types of mergers: - fast-forward merges, and three-way merges. To - make things clearer, suppose we have a branch called - new-feature that we want to merge - into master. + Merging is the action of bringing the changes in one branch onto another branch. In Git there are two + types of mergers: fast-forward merges, and three-way merges. To make things clearer, + suppose we have a branch called new-feature that we want to merge into + master.


    - Git will use a fast-forward merge if - master and - new-feature have not diverged. This - means that the last common commit for both branches is also the - last commit on the master branch. In - this case, all Git has to do is move the - master pointer to the tip of the + Git will use a fast-forward merge if master and + new-feature have not diverged. This means that the last common commit for + both branches is also the last commit on the master branch. In this case, + all Git has to do is move the master pointer to the tip of the new-feature branch.


    - If the branches have diverged, Git will use a three-way merge. In - this scenario, Git will look at three different commits (thus - three-way merge). The last common ancestor to both branches and - the tip in each branch. Then it will create a new commit (called - merge commit) that integrates all changes. + If the branches have diverged, Git will use a three-way merge. In this scenario, Git will look at three + different commits (thus three-way merge). The last common ancestor to both branches and the tip in each + branch. Then it will create a new commit (called merge commit) that integrates all changes.

    From 9d604fbba44e62971eebb375a71bff423c6a38bd Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 23:29:01 +0200 Subject: [PATCH 23/24] Update pages --- pages/012/viewing_changes.html | 5 +---- pages/017/restoring_a_file.html | 4 +--- pages/020/aliases.html | 9 ++------- pages/054/sharing_branches.html | 4 +--- pages/056/github_issues.html | 4 +--- pages/057/forks.html | 8 ++------ 6 files changed, 8 insertions(+), 26 deletions(-) diff --git a/pages/012/viewing_changes.html b/pages/012/viewing_changes.html index e10d650..71fdaba 100644 --- a/pages/012/viewing_changes.html +++ b/pages/012/viewing_changes.html @@ -108,10 +108,7 @@

    Viewing changes

    how to launch our diff tool. To do this we run

    - - git config --global difftool.vscode.cmd "code --wait --diff - $LOCAL $REMOTE" - + git config --global difftool.vscode.cmd "code --wait --diff $LOCAL $REMOTE"

    For this to work remember that you must have added VS Code to your system path. If you forgot about that, diff --git a/pages/017/restoring_a_file.html b/pages/017/restoring_a_file.html index e70c95b..a5895ed 100644 --- a/pages/017/restoring_a_file.html +++ b/pages/017/restoring_a_file.html @@ -35,9 +35,7 @@

    Restoring a file

    If we deleted a file and we want to restore it to the previous state we run

    - - git restore --source=HEAD~1 file_path/file_name.ext - + git restore --source=HEAD~1 file_path/file_name.ext

    Here we are restoring a deleted file to the version that was available in the commit previous to deleting diff --git a/pages/020/aliases.html b/pages/020/aliases.html index 66066da..4547899 100644 --- a/pages/020/aliases.html +++ b/pages/020/aliases.html @@ -36,10 +36,7 @@

    Aliases

    personalized output like this:

    - - git log --pretty=format:'%Cgreen%an%Creset committed - %Cgreen%h%Creset on %Cgreen%cd%Creset' - + git log --pretty=format:'%Cgreen%an%Creset committed %Cgreen%h%Creset on %Cgreen%cd%Creset'

    Here %an stands for author name, @@ -84,9 +81,7 @@

    Aliases

    Now we can define an alias for un-staging files.

    - - git config --global alias.unstage 'restore --staged .' - + git config --global alias.unstage 'restore --staged .'

    With it we can restore all the files in the staging area with one simple command. diff --git a/pages/054/sharing_branches.html b/pages/054/sharing_branches.html index 94ace1a..8e13dc3 100644 --- a/pages/054/sharing_branches.html +++ b/pages/054/sharing_branches.html @@ -172,9 +172,7 @@

    Sharing branches

    local branch. To do that we run

    - - git switch -C branch_name remote/branch_name - + git switch -C branch_name remote/branch_name

    where branch_name is the name of our local branch and diff --git a/pages/056/github_issues.html b/pages/056/github_issues.html index 1a1c86e..19c7084 100644 --- a/pages/056/github_issues.html +++ b/pages/056/github_issues.html @@ -73,9 +73,7 @@

    GitHub issues

    separate them. If we want to include a more comprehensive message we can do so with a semicolon.

    - - git commit -m "fixes #1, closes #2, resolves #3; Commit message" - + git commit -m "fixes #1, closes #2, resolves #3; Commit message"

    GitHub issues 5 diff --git a/pages/057/forks.html b/pages/057/forks.html index 66b2952..e648caa 100644 --- a/pages/057/forks.html +++ b/pages/057/forks.html @@ -185,9 +185,7 @@

    Forks

    original upstream repository we run

    - - git remote add remote_name remote_url - + git remote add remote_name remote_url

    Here remote_name can be anything you want, but it's most common to call @@ -200,9 +198,7 @@

    Forks

    If you want to change the name of a remote, just run

    - - git remote rename current_name new_name - + git remote rename current_name new_name

    Similarly, to remove a remote, we run

    From 7a606b0e05e34ce209cdfaeac6952462f0590230 Mon Sep 17 00:00:00 2001 From: Daniel Czarnievicz <16988051+daczarne@users.noreply.github.com> Date: Sun, 28 Sep 2025 23:42:26 +0200 Subject: [PATCH 24/24] Update pages --- pages/055/pull_requests.html | 4 ++-- pages/057/forks.html | 2 +- pages/069/introduction_to_github_actions.html | 2 +- pages/070/triggers.html | 2 +- pages/075/environment_variables.html | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pages/055/pull_requests.html b/pages/055/pull_requests.html index 38ce1b5..4dbb1bd 100644 --- a/pages/055/pull_requests.html +++ b/pages/055/pull_requests.html @@ -57,8 +57,8 @@

    Pull requests

    the branch that we want to merge our code into (here we'll choose main), our compare branch is the branch that has the code we want to merge into the base branch (in this case, I called the branch bugfix). Next to the branch selectors, GitHub is telling us that this branch can be merged without - generating conflicts. This is will not always be the case. If GitHub tells us that there are conflicts - that will have to be resolved that's OK, first our code needs to be approved by our teammates anyway. + generating conflicts. This will not always be the case. If GitHub tells us that there are conflicts that + will have to be resolved, that's OK, first our code needs to be approved by our teammates anyway.


    diff --git a/pages/057/forks.html b/pages/057/forks.html index e648caa..51ac1a0 100644 --- a/pages/057/forks.html +++ b/pages/057/forks.html @@ -214,7 +214,7 @@

    Forks

    when we fetch or pull we need to supply the name of the remote from where Git is supposed to fetch or pull. When we omit this, Git - assumes that we want to use the origin. But in this case, we must + assumes that we want to use the origin. But, in this case, we must include it, since we want Git to bring in changes that are not in our origin but in a different remote. So, we run diff --git a/pages/069/introduction_to_github_actions.html b/pages/069/introduction_to_github_actions.html index 24fb643..98b118c 100644 --- a/pages/069/introduction_to_github_actions.html +++ b/pages/069/introduction_to_github_actions.html @@ -57,7 +57,7 @@

    Introduction to GitHub Actions

    Workflows must be written in YAML and placed inside .github/workflows directory in the root of - the project. This files are composed of key:value pairs, with keys separated from values by colons, + the project. These files are composed of key:value pairs, with keys separated from values by colons, :. To nest objects inside of other objects in YAML we just need to indent the keys of the child object with 2 or 4 spaces with respect to the keys of its parent object.

    diff --git a/pages/070/triggers.html b/pages/070/triggers.html index c1e12c2..e207927 100644 --- a/pages/070/triggers.html +++ b/pages/070/triggers.html @@ -94,7 +94,7 @@

    Triggers

    Branches don't necessarily need to be specified by names. They can also be patterns. Patterns of the form 'something/*' will only match branches that start with something, followed by a slash, /, - followed by some other text, but not by additional slashes. To match this branches we need to use + followed by some other text, but not by additional slashes. To match these branches we need to use 'something/**'.


    diff --git a/pages/075/environment_variables.html b/pages/075/environment_variables.html index 68876de..2268acd 100644 --- a/pages/075/environment_variables.html +++ b/pages/075/environment_variables.html @@ -141,7 +141,7 @@

    Environment variables

    To encrypt the file locally we can use tools like GPG. For details on how to use this tool, refer to the encrypted secrets documentation here. - Since this files require a passphrase to be decrypted, that passphrase needs to be added as a repository + Since these files require a passphrase to be decrypted, that passphrase needs to be added as a repository secret. And since the encrypted file itself needs to be available in the runner, workflows that require them must first include a checkout step.