├── trainer └── .keep ├── global ├── _files │ └── share │ │ └── test ├── netways.css ├── .gitattributes ├── trainer │ └── 00_title.md ├── favicon.ico ├── pre │ ├── toc │ │ └── 00_toc.md │ ├── netways │ │ ├── _images │ │ │ ├── solutions.png │ │ │ ├── nms_customers.png │ │ │ ├── nps_customers.png │ │ │ ├── netways-logo-1366.png │ │ │ ├── overview_trainings.png │ │ │ ├── overview_conferences.png │ │ │ ├── 202004_TrainingsLogo_petrol.png │ │ │ └── Schulung_Stammlogo_2000px_ENG.jpg │ │ ├── title │ │ │ └── 00_title.md │ │ └── about │ │ │ └── 00_about.md │ ├── osdc │ │ ├── _images │ │ │ └── OSDC_logo_500x224.png │ │ └── title │ │ │ └── 00_title.md │ ├── osmc │ │ ├── _images │ │ │ └── OSMC_logo_500x217.png │ │ └── title │ │ │ └── 00_title.md │ ├── osbconf │ │ ├── _images │ │ │ └── OSBConf_logo_500x122.png │ │ └── title │ │ │ └── 00_title.md │ ├── hints │ │ └── 00_hints.md │ └── licence │ │ └── 00_licence.md ├── .gitignore ├── post │ ├── 01_thanks.md │ └── 00_feedback.md ├── Makefile ├── layouts │ ├── osdc.tpl │ ├── osmc.tpl │ ├── osbconf.tpl │ ├── netways.tpl │ ├── osdc.css │ └── osmc.css ├── docker-compose.yml ├── showoff.json ├── Dockerfile ├── extras │ ├── Linux-Cheatsheet-English.md │ └── Linux-Cheatsheet-German.md ├── README.md └── wizard.sh ├── netways.css ├── _images ├── mermaid │ ├── deltas.mmd.png │ ├── git-stages.mmd.png │ ├── central-vcs.mmd.png │ ├── decentral-vcs.mmd.png │ ├── workflow-local.mmd.png │ ├── workflow-remote.mmd.png │ ├── workflow-branches.mmd.png │ ├── workflow-diverge.mmd.png │ ├── workflow-github-pr.mmd.png │ ├── workflow-gitlab-mr.mmd.png │ ├── workflow-local.mmd │ ├── workflow-after-rebase.mmd.png │ ├── workflow-before-rebase.mmd.png │ ├── workflow-feature-branches.mmd.png │ ├── workflow-release-branches.mmd.png │ ├── workflow-historical-branches.mmd.png │ ├── workflow-maintenance-branch.mmd.png │ ├── git-stages.mmd │ ├── central-vcs.mmd │ ├── workflow-diverge.mmd │ ├── deltas.mmd │ ├── workflow-remote.mmd │ ├── decentral-vcs.mmd │ ├── workflow-after-rebase.mmd │ ├── workflow-gitlab-mr.mmd │ ├── workflow-github-pr.mmd │ ├── workflow-before-rebase.mmd │ ├── workflow-branches.mmd │ ├── workflow-historical-branches.mmd │ ├── workflow-feature-branches.mmd │ ├── workflow-release-branches.mmd │ └── workflow-maintenance-branch.mmd ├── commits │ └── git_history_tig.png ├── git_gitflow_workflow_01.png ├── git_gitflow_workflow_02.png ├── git_gitflow_workflow_03.png ├── git_gitflow_workflow_04.png ├── server │ ├── git_server_github.png │ └── git_server_gitlab.png ├── ci │ ├── git_gitlab_ci_jobs_stages.png │ ├── git_gitlab_ci_runners_docker.png │ ├── git_gitlab_ci_jobs_stages_failed.png │ └── git_gitlab_ci_pipelines_project_ci_cd.png ├── introduction │ ├── git_shell_powerline.png │ ├── git_shell_powershell.png │ ├── git_gui_client_gitkraken.png │ ├── git_gui_client_sourcetree.png │ └── git_gui_client_github_desktop.png └── integrations │ ├── git_integrations_ide_phpstorm.png │ └── git_integrations_ide_visualstudio.png ├── .gitignore ├── _files └── share │ └── bashrc ├── day2 ├── 01_Workflows │ ├── 01_Intro.md │ ├── 08_Practical_Workflow_Examples.md │ ├── 07_Gitflow.md │ ├── 03_Feature_Branch.md │ ├── 05_Gitlab_Workflow.md │ ├── 09_Rebase_Squash.md │ └── 02_Centralized.md ├── 05_Outlook │ ├── 30_Attributes.md │ ├── 40_Svn_Migration.md │ ├── 31_LFS.md │ ├── 10_Submodules.md │ └── 01_Appendix.md ├── 03_CI │ ├── 01_Intro.md │ └── 04_Gitlab_Pipelines.md ├── 00_Repetition │ └── 01_Intro.md └── 04_Summary │ └── 01_Summary.md ├── render-images.sh ├── day1 ├── 06_Server │ ├── 03_Gitlab_Installation.md │ ├── 02_Gitlab_Introduction.md │ ├── 01_Intro.md │ └── 04_Connect_Local_Remote.md ├── 07_Collaboration │ ├── 01_Intro.md │ ├── 05_Tags.md │ ├── 04_Advanced.md │ └── 02_Collaboration.md ├── 04_Commits │ ├── 01_Intro.md │ ├── 03_Good_Commits.md │ ├── 02_Commits.md │ ├── 05_Amend.md │ └── 04_History.md ├── 03_Basics │ ├── 01_Intro.md │ ├── 02_Start.md │ ├── 05_Gitignore.md │ ├── 04_Status.md │ └── 03_Changes.md ├── 05_Branching │ ├── 03_Reset_Commit.md │ ├── 02_head_smart_pointers.md │ └── 01_Intro.md ├── 00_Organisation │ └── 01_Intro.md └── 01_Introduction │ ├── 02_Gui_Clients.md │ ├── 01_Intro.md │ ├── 03_Configuration.md │ └── 04_Basics.md ├── showoff.json └── README.md /trainer/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /global/_files/share/test: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /netways.css: -------------------------------------------------------------------------------- 1 | global/layouts/netways.css -------------------------------------------------------------------------------- /global/netways.css: -------------------------------------------------------------------------------- 1 | global/layouts/netways.css -------------------------------------------------------------------------------- /global/.gitattributes: -------------------------------------------------------------------------------- 1 | *.deb filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /global/trainer/00_title.md: -------------------------------------------------------------------------------- 1 | !SLIDE noprint subsectionnonum 2 | # Trainer 3 | -------------------------------------------------------------------------------- /global/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/favicon.ico -------------------------------------------------------------------------------- /global/pre/toc/00_toc.md: -------------------------------------------------------------------------------- 1 | !SLIDE printonly 2 | 3 | # Table of Contents 4 | 5 | ~~~TOC~~~ 6 | -------------------------------------------------------------------------------- /global/.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !.gitignore 3 | !.gitattributes 4 | static 5 | stats 6 | trainer 7 | *.pdf 8 | global 9 | -------------------------------------------------------------------------------- /_images/mermaid/deltas.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/deltas.mmd.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vagrant 3 | stats 4 | *.pdf 5 | vm/*.ova 6 | vm/mnt 7 | trainer/ 8 | static/ 9 | \#* 10 | *~ -------------------------------------------------------------------------------- /_images/mermaid/git-stages.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/git-stages.mmd.png -------------------------------------------------------------------------------- /global/post/01_thanks.md: -------------------------------------------------------------------------------- 1 | !SLIDE noprint center 2 | # Thank You 3 | 4 | .large.margin-top-1-3 Thank you for your attention! 5 | -------------------------------------------------------------------------------- /_images/commits/git_history_tig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/commits/git_history_tig.png -------------------------------------------------------------------------------- /_images/git_gitflow_workflow_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/git_gitflow_workflow_01.png -------------------------------------------------------------------------------- /_images/git_gitflow_workflow_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/git_gitflow_workflow_02.png -------------------------------------------------------------------------------- /_images/git_gitflow_workflow_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/git_gitflow_workflow_03.png -------------------------------------------------------------------------------- /_images/git_gitflow_workflow_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/git_gitflow_workflow_04.png -------------------------------------------------------------------------------- /_images/mermaid/central-vcs.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/central-vcs.mmd.png -------------------------------------------------------------------------------- /_images/mermaid/decentral-vcs.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/decentral-vcs.mmd.png -------------------------------------------------------------------------------- /_images/server/git_server_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/server/git_server_github.png -------------------------------------------------------------------------------- /_images/server/git_server_gitlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/server/git_server_gitlab.png -------------------------------------------------------------------------------- /global/post/00_feedback.md: -------------------------------------------------------------------------------- 1 | !SLIDE noprint center 2 | # Feedback 3 | 4 | .large.margin-top-1-3 We look forward to your feedback 5 | -------------------------------------------------------------------------------- /_images/mermaid/workflow-local.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-local.mmd.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-remote.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-remote.mmd.png -------------------------------------------------------------------------------- /_files/share/bashrc: -------------------------------------------------------------------------------- 1 | 2 | source ~/git-prompt.sh 3 | export GIT_PS1_SHOWDIRTYSTATE=1 4 | export PS1='[\u@\h] \W$(__git_ps1 " (%s)") \$ ' 5 | -------------------------------------------------------------------------------- /_images/ci/git_gitlab_ci_jobs_stages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/ci/git_gitlab_ci_jobs_stages.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-branches.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-branches.mmd.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-diverge.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-diverge.mmd.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-github-pr.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-github-pr.mmd.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-gitlab-mr.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-gitlab-mr.mmd.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-local.mmd: -------------------------------------------------------------------------------- 1 | gitGraph 2 | commit id: "a11111" 3 | commit id: "b22222" 4 | commit id: "c33333" tag: "main" 5 | -------------------------------------------------------------------------------- /global/Makefile: -------------------------------------------------------------------------------- 1 | RUNTIME?=docker 2 | VERSION?=0.20.4 3 | 4 | image: 5 | $(RUNTIME) build --pull -t docker.io/netways/showoff:$(VERSION) . 6 | -------------------------------------------------------------------------------- /global/pre/netways/_images/solutions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/netways/_images/solutions.png -------------------------------------------------------------------------------- /_images/ci/git_gitlab_ci_runners_docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/ci/git_gitlab_ci_runners_docker.png -------------------------------------------------------------------------------- /_images/introduction/git_shell_powerline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/introduction/git_shell_powerline.png -------------------------------------------------------------------------------- /global/pre/netways/_images/nms_customers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/netways/_images/nms_customers.png -------------------------------------------------------------------------------- /global/pre/netways/_images/nps_customers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/netways/_images/nps_customers.png -------------------------------------------------------------------------------- /_images/ci/git_gitlab_ci_jobs_stages_failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/ci/git_gitlab_ci_jobs_stages_failed.png -------------------------------------------------------------------------------- /_images/introduction/git_shell_powershell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/introduction/git_shell_powershell.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-after-rebase.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-after-rebase.mmd.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-before-rebase.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-before-rebase.mmd.png -------------------------------------------------------------------------------- /global/pre/osdc/_images/OSDC_logo_500x224.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/osdc/_images/OSDC_logo_500x224.png -------------------------------------------------------------------------------- /global/pre/osmc/_images/OSMC_logo_500x217.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/osmc/_images/OSMC_logo_500x217.png -------------------------------------------------------------------------------- /_images/introduction/git_gui_client_gitkraken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/introduction/git_gui_client_gitkraken.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-feature-branches.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-feature-branches.mmd.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-release-branches.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-release-branches.mmd.png -------------------------------------------------------------------------------- /global/pre/netways/_images/netways-logo-1366.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/netways/_images/netways-logo-1366.png -------------------------------------------------------------------------------- /global/pre/netways/_images/overview_trainings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/netways/_images/overview_trainings.png -------------------------------------------------------------------------------- /_images/ci/git_gitlab_ci_pipelines_project_ci_cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/ci/git_gitlab_ci_pipelines_project_ci_cd.png -------------------------------------------------------------------------------- /_images/introduction/git_gui_client_sourcetree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/introduction/git_gui_client_sourcetree.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-historical-branches.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-historical-branches.mmd.png -------------------------------------------------------------------------------- /_images/mermaid/workflow-maintenance-branch.mmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/mermaid/workflow-maintenance-branch.mmd.png -------------------------------------------------------------------------------- /global/pre/netways/_images/overview_conferences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/netways/_images/overview_conferences.png -------------------------------------------------------------------------------- /global/pre/osbconf/_images/OSBConf_logo_500x122.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/osbconf/_images/OSBConf_logo_500x122.png -------------------------------------------------------------------------------- /_images/integrations/git_integrations_ide_phpstorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/integrations/git_integrations_ide_phpstorm.png -------------------------------------------------------------------------------- /_images/introduction/git_gui_client_github_desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/introduction/git_gui_client_github_desktop.png -------------------------------------------------------------------------------- /_images/integrations/git_integrations_ide_visualstudio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/_images/integrations/git_integrations_ide_visualstudio.png -------------------------------------------------------------------------------- /global/pre/netways/_images/202004_TrainingsLogo_petrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/netways/_images/202004_TrainingsLogo_petrol.png -------------------------------------------------------------------------------- /global/pre/netways/_images/Schulung_Stammlogo_2000px_ENG.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NETWAYS/gitlab-training/HEAD/global/pre/netways/_images/Schulung_Stammlogo_2000px_ENG.jpg -------------------------------------------------------------------------------- /_images/mermaid/git-stages.mmd: -------------------------------------------------------------------------------- 1 | sequenceDiagram 2 | Working Directory->>+Staging Area: add 3 | Staging Area->>+Repository: commit 4 | Repository->>+Working Directory: checkout -------------------------------------------------------------------------------- /_images/mermaid/central-vcs.mmd: -------------------------------------------------------------------------------- 1 | graph RL 2 | subgraph CentralVCS 3 | C{{VersionDB}} 4 | end 5 | C -->|Client A| D[File] 6 | C -->|Client B| E[File] 7 | C -->|Client C| F[File] -------------------------------------------------------------------------------- /_images/mermaid/workflow-diverge.mmd: -------------------------------------------------------------------------------- 1 | gitGraph 2 | commit 3 | commit 4 | branch local/main 5 | checkout local/main 6 | commit 7 | commit 8 | checkout main 9 | commit 10 | commit 11 | -------------------------------------------------------------------------------- /_images/mermaid/deltas.mmd: -------------------------------------------------------------------------------- 1 | graph LR 2 | version1 --> version2 --> version3 --> version4 3 | A[File A] -->A1(Δ1) ---A2( ) --> A3(Δ2) 4 | B[File B] ---B1( ) -->B2(Δ1) --- B3( ) 5 | C[File C] -->C1(Δ1) ---C2( ) --> C3(Δ2) -------------------------------------------------------------------------------- /_images/mermaid/workflow-remote.mmd: -------------------------------------------------------------------------------- 1 | gitGraph 2 | commit id: "a11111" 3 | commit id: "b22222" 4 | commit id: "c33333" 5 | commit id: "d44444" type: HIGHLIGHT 6 | commit id: "e55555" type: HIGHLIGHT tag: "origin/main" 7 | -------------------------------------------------------------------------------- /_images/mermaid/decentral-vcs.mmd: -------------------------------------------------------------------------------- 1 | graph RL 2 | subgraph CentralVCS 3 | C{{VersionDB}} 4 | end 5 | C <--> A 6 | C <--> B 7 | subgraph ClientA 8 | A{{VersionDB}} 9 | end 10 | subgraph ClientB 11 | B{{VersionDB}} 12 | end -------------------------------------------------------------------------------- /_images/mermaid/workflow-after-rebase.mmd: -------------------------------------------------------------------------------- 1 | gitGraph 2 | commit id:"a11111" 3 | commit id:"b22222" 4 | commit id:"c33333" 5 | commit id:"d44444" 6 | branch local/main 7 | checkout local/main 8 | commit id:"y88888" 9 | commit id:"z99999" 10 | -------------------------------------------------------------------------------- /_images/mermaid/workflow-gitlab-mr.mmd: -------------------------------------------------------------------------------- 1 | gitGraph 2 | commit 3 | commit 4 | branch feature/branch 5 | checkout feature/branch 6 | commit 7 | commit 8 | commit type:HIGHLIGHT tag:"Merge Request" 9 | checkout main 10 | merge feature/branch 11 | -------------------------------------------------------------------------------- /_images/mermaid/workflow-github-pr.mmd: -------------------------------------------------------------------------------- 1 | gitGraph 2 | commit 3 | commit 4 | branch fork/of/repository 5 | checkout fork/of/repository 6 | commit 7 | commit 8 | commit type:HIGHLIGHT tag:"Pull Request" 9 | checkout main 10 | merge fork/of/repository 11 | -------------------------------------------------------------------------------- /_images/mermaid/workflow-before-rebase.mmd: -------------------------------------------------------------------------------- 1 | gitGraph 2 | commit id:"a11111" 3 | commit id:"b22222" 4 | branch local/main 5 | checkout local/main 6 | commit id:"y88888" 7 | commit id:"z99999" 8 | checkout main 9 | commit id:"c33333" 10 | commit id:"d44444" 11 | -------------------------------------------------------------------------------- /day2/01_Workflows/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ Git Workflows 3 | 4 | !SLIDE smbullets 5 | # Git Workflow Overview 6 | 7 | Table of contents: 8 | 9 | * Centralized Workflow 10 | * Feature Branch Workflow 11 | * Gitflow Workflow 12 | * Merge/Pull Request Workflow 13 | -------------------------------------------------------------------------------- /render-images.sh: -------------------------------------------------------------------------------- 1 | find _images/mermaid/ -type f -name '*.mmd' -print0 | 2 | while IFS= read -r -d '' line; do 3 | f=$(basename "$line") 4 | echo $f 5 | docker run -u `id -u`:`id -g` --rm -v $(pwd)/_images/mermaid:/data minlag/mermaid-cli -e png -i "/data/${f}" 6 | done 7 | -------------------------------------------------------------------------------- /_images/mermaid/workflow-branches.mmd: -------------------------------------------------------------------------------- 1 | gitGraph 2 | commit 3 | commit 4 | branch fix/login-bug 5 | checkout fix/login-bug 6 | commit 7 | commit 8 | checkout main 9 | commit 10 | commit 11 | branch feature/new-logo 12 | checkout feature/new-logo 13 | commit 14 | -------------------------------------------------------------------------------- /global/layouts/osdc.tpl: -------------------------------------------------------------------------------- 1 |
2 | OSDC 3 |
4 | 5 | ~~~CONTENT~~~ 6 | 7 | 11 | -------------------------------------------------------------------------------- /global/layouts/osmc.tpl: -------------------------------------------------------------------------------- 1 |
2 | OSMC 3 |
4 | 5 | ~~~CONTENT~~~ 6 | 7 | 11 | -------------------------------------------------------------------------------- /global/layouts/osbconf.tpl: -------------------------------------------------------------------------------- 1 |
2 | OSBConf 3 |
4 | 5 | ~~~CONTENT~~~ 6 | 7 | 11 | -------------------------------------------------------------------------------- /global/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | showoff: 5 | build: . 6 | image: netways/showoff:0.19.6 7 | ports: 8 | - "9090:9090" 9 | volumes: 10 | - "$PWD:/training" 11 | environment: 12 | - "LANG=C.UTF-8" 13 | - "LANGUAGE=C.UTF-8" 14 | - "LC_ALL=C.UTF-8" 15 | 16 | -------------------------------------------------------------------------------- /global/layouts/netways.tpl: -------------------------------------------------------------------------------- 1 |
2 | NETWAYS Training 3 |
4 | 5 | ~~~CONTENT~~~ 6 | 7 | 11 | -------------------------------------------------------------------------------- /day1/06_Server/03_Gitlab_Installation.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Git Server Installation 3 | 4 | This training focuses on working with a GitLab instances. 5 | 6 | Manual installation instructions are out of scope. It is recommended to use: 7 | 8 | * The "Omnibus Installation" package 9 | * The GitLab Container Images 10 | * A managed cloud hosting service 11 | -------------------------------------------------------------------------------- /day2/05_Outlook/30_Attributes.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Git - Attributes 3 | 4 | A `.gitattributes` file is a text file that gives attributes to pathnames. 5 | 6 | * Control the file line ending mode on different OS 7 | * Ignore specific files on git archive 8 | 9 | Example: 10 | 11 | @@@ Sh 12 | $ vim .gitattributes 13 | 14 | modules/** eol=lf 15 | -------------------------------------------------------------------------------- /day1/07_Collaboration/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ Collaboration with others 3 | 4 | !SLIDE smbullets 5 | # Collaboration 6 | 7 | A common workflow when working with others is: 8 | 9 | * Each person works locally 10 | * Finished work is pushed to remote repository 11 | * We review and discuss the changes 12 | * We merge the changes into our main branch 13 | -------------------------------------------------------------------------------- /global/pre/hints/00_hints.md: -------------------------------------------------------------------------------- 1 | !SLIDE 2 | # Training Hints 3 | 4 | * Ask questions! Dumb questions do not exist. 5 | * Add your own notes! Having learnt something is reflected best with your own additions. 6 | * Join the conversation! Many of these exercises require real world scenarios and your feedback and questions. 7 | * Work together! Be part of the training team and find solutions together. 8 | -------------------------------------------------------------------------------- /day2/05_Outlook/40_Svn_Migration.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Git - Migration from SVN 3 | 4 | There are tools that are able to preserve the SVN history. 5 | 6 | * Pick a migration route with `svn2git`: https://github.com/nirvdrum/svn2git 7 | * Extract authors, Git needs user/email mapping 8 | * Run `svn2git` with `authors.txt` 9 | 10 | See also: https://docs.gitlab.com/ce/user/project/import/svn.html 11 | -------------------------------------------------------------------------------- /day2/03_CI/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ Continuous Integration 3 | 4 | !SLIDE smbullets 5 | # What is Continuous Integration? 6 | 7 | Continuous integration (CI) is the practice of integrating new code more frequently and securely throughout development. 8 | 9 | * Automated code quality checks (linting, testing) 10 | * Security scanning (dependencies, static analysis) 11 | * Visualize failures and notify users 12 | * Generate Reporting and prepare deployments 13 | -------------------------------------------------------------------------------- /day2/05_Outlook/31_LFS.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Git - Large File Storage (LFS) 3 | 4 | Git LFS replaces large files (audio, videos, datasets, graphics) with text pointers. 5 | 6 | * It is generally not recommended to store binary files in Git 7 | * Git LFS is a plugin to overcome this shortcoming 8 | * Requires a `.gitattributes` file for tracking files 9 | 10 | Installation: 11 | 12 | @@@ Sh 13 | $ git lfs install 14 | 15 | Usage: 16 | 17 | @@@ Sh 18 | $ git lfs track "*." 19 | -------------------------------------------------------------------------------- /day1/04_Commits/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ Git Commits 3 | 4 | !SLIDE 5 | # Git Commits 6 | 7 | Commits are the history or logbook of our project. 8 | 9 | * They can have a subject line and a body 10 | * Keep the subject short and simple 11 | * Add a detailed explanation for larger changes 12 | 13 | Example: 14 | 15 | commit 25037b 16 | Author: Anita Bath 17 | Date: Fri Mar 31 13:37:00 2023 18 | 19 | Change background color of header 20 | 21 | The existing color made text hard to read. 22 | -------------------------------------------------------------------------------- /day1/03_Basics/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ Git Basics 3 | 4 | !SLIDE smbullets 5 | # Git Command Overview 6 | 7 | * Start a working area (clone, init) 8 | * Work on current changes (add, rm) 9 | * Examine the history and state (status, log) 10 | * Grow, mark and tweak the history (branch, checkout, commit, merge, rebase) 11 | * Collaborate (fetch, pull, push) 12 | 13 | ~~~SECTION:handouts~~~ 14 | 15 | **** 16 | 17 | How to list available commands and get help: 18 | 19 | git --help 20 | git clone --help 21 | man git-add 22 | 23 | ~~~ENDSECTION~~~ 24 | -------------------------------------------------------------------------------- /day2/01_Workflows/08_Practical_Workflow_Examples.md: -------------------------------------------------------------------------------- 1 | !SLIDE 2 | # Workflow Examples: Icinga 3 | 4 | A mix of feature branch and gitflow workflow. 5 | 6 | * `master` corresponds to the development branch 7 | * Major releases are created and tagged on `master` 8 | * `support/x.y` branches for bugfix releases of long time support releases 9 | 10 | Organizational workflow: 11 | 12 | * Pull Requests, local and community forks 13 | * Testing via GitHub Actions (Linux) and Appveyor (Windows) 14 | * Developers review and approve PRs, maintainers merge them 15 | * Maintainer prepares and publishes a release 16 | -------------------------------------------------------------------------------- /global/pre/osdc/title/00_title.md: -------------------------------------------------------------------------------- 1 | !SLIDE printonly 2 | 3 | 6 |
7 |
~~~CONFIG:name~~~
8 |
~~~CONFIG:subtitle~~~
9 |
Version: ~~~CONFIG:release~~~
10 |
11 | 12 | !SLIDE noprint 13 | 14 |

~~~CONFIG:name~~~

15 |

~~~CONFIG:subtitle~~~

16 |

~~~CONFIG:author~~~

17 | -------------------------------------------------------------------------------- /global/pre/osmc/title/00_title.md: -------------------------------------------------------------------------------- 1 | !SLIDE printonly 2 | 3 | 6 |
7 |
~~~CONFIG:name~~~
8 |
~~~CONFIG:subtitle~~~
9 |
Version: ~~~CONFIG:release~~~
10 |
11 | 12 | !SLIDE noprint 13 | 14 |

~~~CONFIG:name~~~

15 |

~~~CONFIG:subtitle~~~

16 |

~~~CONFIG:author~~~

17 | -------------------------------------------------------------------------------- /global/pre/osbconf/title/00_title.md: -------------------------------------------------------------------------------- 1 | !SLIDE printonly 2 | 3 | 6 |
7 |
~~~CONFIG:name~~~
8 |
~~~CONFIG:subtitle~~~
9 |
Version: ~~~CONFIG:release~~~
10 |
11 | 12 | !SLIDE noprint 13 | 14 |

~~~CONFIG:name~~~

15 |

~~~CONFIG:subtitle~~~

16 |

~~~CONFIG:author~~~

17 | -------------------------------------------------------------------------------- /global/pre/netways/title/00_title.md: -------------------------------------------------------------------------------- 1 | !SLIDE printonly 2 | 3 | 6 |
7 |
~~~CONFIG:name~~~
8 |
~~~CONFIG:subtitle~~~
9 |
Version: ~~~CONFIG:release~~~
10 |
11 | 12 | !SLIDE noprint 13 | 14 |

~~~CONFIG:name~~~

15 |

~~~CONFIG:subtitle~~~

16 |

~~~CONFIG:author~~~

17 | -------------------------------------------------------------------------------- /_images/mermaid/workflow-historical-branches.mmd: -------------------------------------------------------------------------------- 1 | %%{init: { 'theme': 'default' , 'themeVariables': { 2 | 'git0': '#ff0000', 3 | 'git1': '#00ff00', 4 | 'git2': '#7171ff', 5 | 'git3': '#ff00ff', 6 | 'git4': '#00ffff', 7 | 'git5': '#ffff00', 8 | 'git6': '#ff00ff', 9 | 'git7': '#00ffff' 10 | } } }%% 11 | gitGraph 12 | commit tag:"v0.1" 13 | branch develop 14 | checkout develop 15 | commit 16 | checkout main 17 | checkout develop 18 | commit 19 | checkout main 20 | commit tag:"v0.2" 21 | checkout develop 22 | commit 23 | checkout main 24 | commit tag:"v1.0" 25 | checkout develop 26 | commit 27 | -------------------------------------------------------------------------------- /global/showoff.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NETWAYS Training", 3 | "subtitle": "Open Source Training", 4 | "author": "Open Source Community", 5 | "release": "0.0.1", 6 | 7 | "favicon": "global/favicon.ico", 8 | 9 | "protected": ["presenter", "onepage", "print"], 10 | 11 | "user": "netways", 12 | "password": "awesome", 13 | 14 | "templates":{ 15 | "default": "global/layouts/netways.tpl" 16 | }, 17 | 18 | "sections": [ 19 | {"section": "global/pre/netways/title"}, 20 | {"section": "global/pre/toc"}, 21 | {"section": "global/pre/licence"}, 22 | {"section": "global/pre/netways/about"}, 23 | {"section": "global/pre/hints"}, 24 | 25 | {"section": "global/post"} 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /day1/05_Branching/03_Reset_Commit.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Reset Git Commits 3 | 4 | * `git reset` 5 | * Resets the history up to a specific point 6 | * `--soft` adds changes to the staging area 7 | * `--hard` drops them 8 | * Requires a commit as parameter to which we want to reset to 9 | * `HEAD^` resetting the last commit 10 | * `HEAD~3` resetting the latest 3 commits 11 | 12 | Try it out with the trainer. 13 | 14 | $ git reset --soft HEAD^ # Commit IDs are also possible 15 | $ git reset --hard HEAD^ 16 | 17 | !SLIDE smbullets 18 | # Revert Git Commits 19 | 20 | * `git revert ` 21 | * Reverts some existing commits 22 | * Creates a new commit that will revert the existing commits 23 | 24 | Try it out with the trainer. 25 | 26 | $ git revert HEAD^ # Commit IDs are also possible 27 | $ git revert HEAD~2 28 | -------------------------------------------------------------------------------- /showoff.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GitLab", 3 | "subtitle": "Version Control System & Continuous Integration", 4 | "location": "Nuremberg", 5 | "author": "Feu Mourek, Markus Opolka, Daniel Bodky", 6 | "release": "4.1.2", 7 | 8 | "favicon": "image/global/favicon.ico", 9 | 10 | "protected": ["presenter", "onepage", "print"], 11 | "user": "netways", 12 | "password": "awesome", 13 | 14 | "templates" : { 15 | "default" : "global/layouts/netways.tpl" 16 | }, 17 | 18 | "sections": [ 19 | {"section": "global/pre/netways/title"}, 20 | {"section": "global/pre/toc"}, 21 | {"section": "global/pre/licence"}, 22 | {"section": "global/pre/netways/about"}, 23 | {"section": "global/pre/hints"}, 24 | 25 | {"section":"day1/"}, 26 | {"section":"day2/"}, 27 | 28 | {"section": "global/post"} 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /_images/mermaid/workflow-feature-branches.mmd: -------------------------------------------------------------------------------- 1 | %%{init: { 'theme': 'default' , 'themeVariables': { 2 | 'git0': '#ff0000', 3 | 'git1': '#00ff00', 4 | 'git2': '#7171ff', 5 | 'git3': '#ff00ff', 6 | 'git4': '#00ffff', 7 | 'git5': '#ffff00', 8 | 'git6': '#ff00ff', 9 | 'git7': '#00ffff' 10 | } } }%% 11 | gitGraph 12 | commit tag:"v0.1" 13 | branch develop 14 | checkout develop 15 | commit 16 | branch featureB 17 | checkout featureB 18 | commit 19 | checkout main 20 | checkout develop 21 | commit 22 | checkout featureB 23 | commit 24 | checkout main 25 | commit tag:"v0.2" 26 | checkout featureB 27 | commit 28 | checkout develop 29 | branch featureA 30 | commit 31 | checkout develop 32 | checkout featureA 33 | commit 34 | checkout featureB 35 | commit 36 | checkout develop 37 | merge featureA 38 | commit 39 | checkout main 40 | commit tag:"v1.0" 41 | -------------------------------------------------------------------------------- /day1/04_Commits/03_Good_Commits.md: -------------------------------------------------------------------------------- 1 | !SLIDE 2 | # Good Commits 3 | 4 | Make it easy for you and others to understand the changes over time. 5 | 6 | * Selectively add changes for a commit (do not commit everything) 7 | * Write a short summary based on the changes (what and why) 8 | * You can add references to existing commits or ticket ids 9 | 10 | Over time, commits should tell a story of the history 11 | of your repository and how it came to be the way that it currently is. 12 | 13 | !SLIDE 14 | # Good Commit Messages 15 | 16 | * The subject line is the most important 17 | * Describe why a change is being made in the body 18 | * Do not assume the reviewer understands what the original problem was 19 | * Do not assume the code is self-evident 20 | 21 | Example: 22 | 23 | Improve UI acessibility 24 | 25 | Previously we had red and green buttons. 26 | This made them difficult to differentiate 27 | for colorblind people. 28 | We are now using blue and purple. 29 | 30 | fixes #1 31 | -------------------------------------------------------------------------------- /_images/mermaid/workflow-release-branches.mmd: -------------------------------------------------------------------------------- 1 | %%{init: { 'theme': 'default' , 'themeVariables': { 2 | 'git0': '#ff0000', 3 | 'git1': '#00ff00', 4 | 'git2': '#7171ff', 5 | 'git3': '#ff00ff', 6 | 'git4': '#00ffff', 7 | 'git5': '#ffff00', 8 | 'git6': '#ff00ff', 9 | 'git7': '#00ffff' 10 | } } }%% 11 | gitGraph 12 | commit tag:"v0.1" 13 | branch develop 14 | checkout develop 15 | commit 16 | branch featureB 17 | checkout featureB 18 | commit 19 | checkout main 20 | checkout develop 21 | commit 22 | checkout featureB 23 | commit 24 | checkout main 25 | commit tag:"v0.2" 26 | checkout featureB 27 | commit 28 | checkout develop 29 | branch featureA 30 | commit 31 | checkout develop 32 | checkout featureA 33 | commit 34 | checkout featureB 35 | commit 36 | checkout develop 37 | merge featureA 38 | branch release 39 | checkout release 40 | commit 41 | checkout main 42 | commit tag:"v1.0" 43 | checkout release 44 | merge main 45 | checkout develop 46 | merge release 47 | -------------------------------------------------------------------------------- /day2/00_Repetition/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsectionnonum noprint 2 | # ~~~SECTION:MAJOR~~~ Repetition 3 | 4 | 5 | !SLIDE smbullets noprint 6 | # Let's repeat what we have learned 7 | ## Repository and Branches 8 | 9 | 1. Use `cd` to leave the training repository 10 | 1.1 Make a new directory "repetition" 11 | 1.2 Switch into the new directory 12 | 1.3 Initialise a new repo 13 | 14 | 2. Add a new local name and email in `.git/config` 15 | 2.1 Add a `README.md` file and create a commit 16 | 2.2 Make changes in the `README.md` and amend the commit 17 | 18 | 3. Create and switch to a new `feature/testdata` branch 19 | 3.1 Create a directory called `testdata/` 20 | 3.2 Check the git status 21 | 3.3 Add an empty file called `.keep` in `testdata/` 22 | 3.4 Check the git status again 23 | 24 | 4. Commit all changes in `feature/testdata` 25 | 4.1 Checkout the `main` branch again 26 | 4.2 Cherry-pick the newest commit from `feature/testdata` 27 | 4.3 Look at the history 28 | 29 | **** 30 | 31 | 32 | ~~~ENDSECTION~~~ 33 | 34 | -------------------------------------------------------------------------------- /day1/06_Server/02_Gitlab_Introduction.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # GitLab Introduction 3 | 4 | GitLab is available as self-hosted or cloud based repository management 5 | system. 6 | 7 | * Git repositories 8 | * User and group management and fine granular permissions 9 | * Issue tracking and project management (dashboards, etc.) 10 | * Merge Requests, Code Review, Reporting 11 | * Continuous integration/deployment (CI/CD) 12 | 13 | NWS: https://nws.netways.de/de/apps/gitlab/ 14 | 15 | !SLIDE 16 | # GitLab Editions 17 | 18 | * Free Edition, Free-forever features for individual users 19 | * Premium Edition, Enhance team productivity and coordination 20 | * Faster code reviews 21 | * Enterprise agile planning 22 | * Release controls 23 | * Self-managed reliability 24 | * Ultimate Edition, Organization wide security, compliance, and planning 25 | * Advanced security testing 26 | * Security risk mitigation 27 | * Compliance 28 | * Portfolio management 29 | * Value stream management 30 | 31 | ~~~SECTION:handouts~~~ 32 | 33 | **** 34 | 35 | Overview: https://about.gitlab.com/features/ 36 | 37 | The source code is publicly available for both editions. 38 | You'll need a valid license for running EE in production. 39 | 40 | ~~~ENDSECTION~~~ 41 | -------------------------------------------------------------------------------- /day1/00_Organisation/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets noprint 2 | 3 | # Who are you? 4 | 5 | * Name and Company 6 | * Your role and or daily business 7 | * Any previous experiences with Git 8 | * Your expectations for this training 9 | 10 | !SLIDE subsection 11 | # ~~~SECTION:MAJOR~~~ Training Organisation 12 | 13 | !SLIDE smbullets 14 | # Training Virtual Machine / Notebook 15 | * Base OS is CentOS 16 | * Password-less sudo is configured 17 | * Git and terminal integrations are installed 18 | 19 | * Virtual Machine 20 | * User: training Password: netways0815! 21 | * Is a tmux shell 22 | 23 | * Notebook 24 | * User: training Password: netways 25 | * Uses GNOME 26 | * WiFi is pre-configured 27 | * Exercises use the default terminal 28 | 29 | !SLIDE smbullets 30 | # Terminal session 31 | 32 | Click on the link in your email to join the session 33 | 34 | * Operating system is CentOS 35 | * We use tmux to join your session and help you 36 | * Change the appearance of the terminal as you like 37 | 38 | !SLIDE smbullets 39 | # GitLab Instance 40 | 41 | * We are using a shared GitLab instance hosted on https://nws.netways.de/ 42 | * The instance is a free-forever version 43 | * You should have received user access for the instance and need to set a password 44 | 45 | -------------------------------------------------------------------------------- /day2/05_Outlook/10_Submodules.md: -------------------------------------------------------------------------------- 1 | !SLIDE 2 | # Git - Submodules 3 | 4 | A Git repository can contain other Git repositories via submodules. 5 | 6 | * A submodule is a pointer to a specific commit in another repository 7 | * Independent sub directories with their own history 8 | 9 | Example: 10 | 11 | @@@Sh 12 | $ git submodule add https://github.com/Icinga/puppet-icinga2 13 | $ git status 14 | new file: .gitmodules 15 | new file: puppet-icinga2 16 | $ git submodule 17 | ad5e309... puppet-icinga2 (heads/master) 18 | $ git submodule update --remote 19 | 90f5a89... puppet-icinga2 (heads/master) 20 | 21 | Note: Git submodule removal is not trivial. 22 | 23 | ~~~ENDSECTION~~~ 24 | 25 | !SLIDE 26 | # Git - Subtree 27 | 28 | A Git subtree is another option to include other Git repositories within a Git repository. 29 | 30 | * Independent sub directories, but a shared history 31 | * Either include the entire history into ours, or squash the remote history into one commit 32 | 33 | Example: 34 | 35 | @@@Sh 36 | $ git subtree add --prefix puppet \ 37 | https://github.com/Icinga/puppet-icinga2 HEAD --squash 38 | 39 | Unlike git submodule, git subtree does not create new metadata files (`.gitmodule`). 40 | 41 | ~~~ENDSECTION~~~ 42 | -------------------------------------------------------------------------------- /_images/mermaid/workflow-maintenance-branch.mmd: -------------------------------------------------------------------------------- 1 | %%{init: { 'theme': 'default' , 'themeVariables': { 2 | 'git0': '#ff0000', 3 | 'git1': '#d0661c', 4 | 'git2': '#00ff00', 5 | 'git3': '#7171ff', 6 | 'git4': '#ff00ff', 7 | 'git5': '#00ffff', 8 | 'git6': '#ffff00', 9 | 'git7': '#ff00ff', 10 | 'git8': '#00ffff' 11 | } } }%% 12 | gitGraph 13 | commit tag:"v0.1" 14 | branch hotfix 15 | checkout hotfix 16 | commit 17 | branch develop 18 | checkout develop 19 | commit 20 | branch featureB 21 | checkout featureB 22 | commit 23 | checkout main 24 | checkout hotfix 25 | commit 26 | checkout develop 27 | commit 28 | checkout featureB 29 | commit 30 | checkout main 31 | merge hotfix tag:"v0.2" 32 | checkout featureB 33 | commit 34 | checkout develop 35 | branch featureA 36 | commit 37 | checkout develop 38 | merge hotfix 39 | checkout featureA 40 | commit 41 | checkout featureB 42 | commit 43 | checkout develop 44 | merge featureA 45 | branch release 46 | checkout release 47 | commit 48 | checkout main 49 | commit tag:"v1.0" 50 | checkout release 51 | merge main 52 | checkout develop 53 | merge release -------------------------------------------------------------------------------- /global/pre/licence/00_licence.md: -------------------------------------------------------------------------------- 1 | !SLIDE printonly 2 | 3 | # Licence 4 | 5 | This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License. 6 | 7 | This is a human-readable summary of (and not a substitute for) the license. 8 | 9 | You are free to: 10 | 11 | * Share — copy and redistribute the material in any medium or format 12 | * Adapt — remix, transform, and build upon the material 13 | 14 | Under the following terms: 15 | 16 | * Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. 17 | 18 | * NonCommercial — You may not use the material for commercial purposes. 19 | * ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. 20 | * No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. 21 | 22 | The licensor cannot revoke these freedoms as long as you follow the license terms. 23 | 24 | Full Licence: 25 | 26 | * https://creativecommons.org/licenses/by-nc-sa/4.0/ 27 | * https://creativecommons.org/licenses/by-nc-sa/4.0/deed.de 28 | -------------------------------------------------------------------------------- /global/pre/netways/about/00_about.md: -------------------------------------------------------------------------------- 1 | !SLIDE noprint subsectionnonum 2 | # About NETWAYS 3 | 4 | 5 | !SLIDE noprint 6 | # NETWAYS 7 | 8 | * Open Source Service Company 9 | * Located in Nuremberg, Germany 10 | * Services 11 | * Consulting 12 | * Outsourcing 13 | * Development 14 | * Support 15 | * Web Services 16 | * Trainings 17 | * Events 18 | 19 | 20 | !SLIDE noprint 21 | # NETWAYS Solutions 22 | 23 |
NETWAYS Solutions
24 | 25 | 26 | !SLIDE noprint 27 | # NETWAYS Consulting and Outsourcing Customers 28 | 29 |
NETWAYS Consulting and Outsourcing Customers
30 | 31 | 32 | !SLIDE noprint 33 | # NETWAYS Cloud and Hosting Customers 34 | 35 |
NETWAYS Cloud and Hosting Customers
36 | 37 | 38 | !SLIDE noprint 39 | # NETWAYS Conferences & Camps 40 | 41 |
NETWAYS Conferences & Camps
42 | 43 | 44 | !SLIDE noprint 45 | # NETWAYS Trainings & Workshops 46 | 47 | * Ansible 48 | * Elastic Stack 49 | * Foreman 50 | * GitLab 51 | * Grafana 52 | * Graylog 53 | * Icinga 54 | * Kubernetes 55 | * Prometheus 56 | * Terraform 57 | 58 | Check out: https://www.netways.de/schulungen/ 59 | -------------------------------------------------------------------------------- /day2/05_Outlook/01_Appendix.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ Appendix 3 | 4 | !SLIDE smbullets 5 | # Git - Debugging 6 | 7 | * `git bisect` 8 | * Can be used to invoke a binary search to find the commit that introduced a bug 9 | * `git grep` 10 | * Prints all lines from the commit history matching a pattern 11 | 12 | !SLIDE smbullets 13 | # Git - Restoring deleted file 14 | 15 | Deleted files are still in the history. This is where `git rev-list` comes in handy. 16 | 17 | * `git rev-list -n 1 HEAD -- ` 18 | * Find the last commit which affected the given path 19 | * `git checkout ^ -- ` 20 | * Then checkout the version at the commit before using the caret `^` symbol 21 | 22 | !SLIDE smbullets 23 | # Git - Apply and Create Patches 24 | 25 | Before Merge Requests existed, developers created Git patches to share their code. 26 | 27 | * `git format-patch` 28 | * Creates a Git patch file 29 | * `git apply` 30 | * Apply a Git patch file 31 | * `git am` 32 | * Reads patches from STDIN and applies them 33 | 34 | ~~~SECTION:handouts~~~ 35 | 36 | **** 37 | 38 | `git apply` applies a git patch file to your working tree. 39 | 40 | `git am` reads git patches from your mailbox by default. It also can be used to 41 | read patches from the shell's STDIN (e.g. curl downloading a patch from the web). 42 | The `-s` option allows you to sign off the patch, for example if you have reviewed 43 | the patch from an external committer. 44 | 45 | `git format-patch` requires either a negative number of commits from current HEAD or 46 | a git commit id. It will then create numbered patch files for all required commits. 47 | 48 | ~~~ENDSECTION~~~ 49 | -------------------------------------------------------------------------------- /global/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/ubuntu:lunar 2 | LABEL maintainer="support@netways.de" 3 | 4 | WORKDIR /training 5 | 6 | # Basic showoff and patched wkhtmltopdf dependencies 7 | RUN set -ex; \ 8 | apt-get update && \ 9 | DEBIAN_FRONTEND=noninteractive \ 10 | apt-get install --no-install-recommends -y \ 11 | build-essential \ 12 | curl \ 13 | markdown \ 14 | ruby \ 15 | ruby-dev \ 16 | rubygems \ 17 | xz-utils \ 18 | zlib1g \ 19 | zlib1g-dev \ 20 | libssl3 \ 21 | libxrender-dev \ 22 | libx11-dev \ 23 | libxext-dev \ 24 | libfontconfig1-dev \ 25 | libfreetype6-dev \ 26 | fontconfig \ 27 | libjpeg-turbo8 \ 28 | xfonts-75dpi \ 29 | xfonts-base \ 30 | && apt-get clean \ 31 | && rm -r /var/lib/apt/lists/* 32 | 33 | # wkhtmltopdf needs a patched QT version 34 | ARG wkhtmltox_url=https://github.com/NETWAYS/training-global/releases/download/v0.20.4/wkhtmltox_0.12.6.1-2.jammy_amd64.deb 35 | RUN set -ex; \ 36 | curl -sSL "${wkhtmltox_url}" --output /tmp/wkhtmltox.deb \ 37 | && dpkg -i /tmp/wkhtmltox.deb \ 38 | && rm -f /tmp/wkhtmltox.deb 39 | 40 | # Install showoff Gem 41 | ARG showoff_version=0.20.4 42 | RUN set -ex; \ 43 | gem install showoff --version="$showoff_version" \ 44 | # uri v0.11.0 (installed as dependency for showoff) contains CVE-2023-28755 45 | # so we upgrade and delete the default manually. This might be removed in the future 46 | # Note that the Ruby 3.1.0 path might change when updating the distro 47 | && GEM_HOME=/usr/lib/ruby/gems/3.1.0/ gem install --default uri; rm -f /usr/lib/ruby/gems/3.1.0/specifications/default/uri-0.11*; 48 | 49 | EXPOSE 9090 50 | 51 | CMD ["showoff", "serve"] 52 | -------------------------------------------------------------------------------- /day2/04_Summary/01_Summary.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ What have we learned? 3 | 4 | !SLIDE smbullets 5 | # The basics topics 6 | 7 | * Cloning or initializing repositories 8 | * `git clone` or `git init` 9 | * Working directory, staging area, commit 10 | * `git add`, `git rm`, `git commit` 11 | * There is no thing as too much `git status` 12 | * Viewing the history 13 | * `git log`, `git show`, `git diff` 14 | 15 | ~~~SECTION:handouts~~~ 16 | 17 | **** 18 | 19 | 20 | ~~~ENDSECTION~~~ 21 | 22 | !SLIDE smbullets 23 | # The advanced topics 24 | 25 | * Branching 26 | * `git branch`, `git checkout` 27 | * Remote Repositories 28 | * `git push`, `git fetch`, `git pull` 29 | * Merging and resolving conflicts 30 | * `git merge` 31 | * Rebasing and squashing 32 | * `git rebase -i ` 33 | 34 | ~~~SECTION:handouts~~~ 35 | 36 | **** 37 | 38 | 39 | ~~~ENDSECTION~~~ 40 | 41 | 42 | !SLIDE smbullets 43 | # git Best Practices 44 | 45 | * Set user configuration (name, email) 46 | * Try to write good commit messages 47 | * Do not commit all changes at once - use staging with `git add` and then `git commit` 48 | * Work with branches (features, bugfixes, etc.) whenever possible 49 | * Rebase branches prior to creating a merge request 50 | * Always force a merge commit with `--no-ff` to keep history trees in graphs 51 | 52 | 53 | ~~~SECTION:handouts~~~ 54 | 55 | **** 56 | 57 | 58 | ~~~ENDSECTION~~~ 59 | 60 | !SLIDE smbullets 61 | # Working with GitLab 62 | 63 | * Creating Projects and `git remote` 64 | * Working with Remote Branches 65 | * `git push --force`, `git pull origin my-branch` 66 | * Create Milestone and First Issue 67 | * Create Merge Request 68 | * Creating Pipelines with Jobs 69 | * `.gitlab-ci.yml` 70 | 71 | **This concludes the outlined training content.** 72 | 73 | ~~~SECTION:handouts~~~ 74 | 75 | **** 76 | 77 | 78 | ~~~ENDSECTION~~~ 79 | -------------------------------------------------------------------------------- /day1/06_Server/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ Git Server 3 | 4 | !SLIDE 5 | # Introduction 6 | 7 | A Git Server is a central storage for repositories. 8 | 9 | * Facilitates collaboration between teams 10 | * Offers user based access control 11 | * Can trigger events (e.g. for CI) 12 | 13 | There are many collaboration suites with many features: GitLab, GitHub, Bitbucket, etc. 14 | 15 | They all use Git as the underlying technology to enable version control. 16 | 17 | ~~~SECTION:handouts~~~ 18 | 19 | **** 20 | 21 | There is a variety of Git server tools, web interfaces 22 | and addons out there. 23 | 24 | * Gitea 25 | * Gogs 26 | 27 | In case you don't want to host your own Git server, 28 | there are open source and enterprise hosting options available. 29 | 30 | NETWAYS also provides GitLab hosting services: 31 | 32 | * https://nws.netways.de/de/apps/gitlab/ 33 | 34 | ~~~ENDSECTION~~~ 35 | 36 | !SLIDE smbullets noprint 37 | # GitLab 38 | 39 |
GitLab
40 | 41 | !SLIDE smbullets printonly 42 | # GitLab 43 | 44 |
GitLab
45 | !SLIDE smbullets noprint 46 | # GitHub 47 | 48 |
GitHub
49 | 50 | !SLIDE smbullets printonly 51 | # GitHub 52 | 53 |
GitHub
54 | 55 | !SLIDE smbullets 56 | # Supported Protocols 57 | 58 | Git can use different protocols to transfer data: HTTP, Secure Shell (SSH) and Git. 59 | 60 | * HTTPS 61 | * `https://my-gitlab.nws.netways.de/username/repo.git` 62 | * SSH 63 | * `git@github.com:username/repo.git` 64 | * Git protocol 65 | * `git://domain.com/repo.git` 66 | * Hint: fast, but unencrypted and no authentication 67 | -------------------------------------------------------------------------------- /day1/07_Collaboration/05_Tags.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Git Tags 3 | 4 | Tags are specific points in history, they point to a commit. Useful for: 5 | 6 | * Release software versions based on tags (e.g. v2.9.0) 7 | * Checkout versions based on tags 8 | * Tags can/should follow milestone versions in ticket systems 9 | 10 | They can be *lightweight* or be *annotated*. 11 | 12 | ~~~SECTION:handouts~~~ 13 | 14 | **** 15 | 16 | Example for checking out a tag into a new branch: 17 | 18 | @@@ Sh 19 | $ git checkout -b version01 v0.1 20 | $ git branch 21 | 22 | ~~~ENDSECTION~~~ 23 | 24 | !SLIDE smbullets 25 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add a Git tag 26 | 27 | * Objective: 28 | * Add a Git tag 29 | * Steps: 30 | * Use `git tag` and add the `v0.5` tag 31 | * Verify the added tag with `git tag -l` 32 | * Push tags to remote origin with `git push --tags` 33 | * Open GitLab and navigate into `Repository > Tags` 34 | * Bonus: 35 | * Add a tag description with `git tag -m "End Of Day One Release" v0.5` 36 | 37 | !SLIDE supplemental exercises 38 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add a Git tag 39 | 40 | ## Objective: Add a Git tag 41 | **** 42 | 43 | * Add git tag 44 | 45 | ## Steps: 46 | 47 | * Use `git tag` and add the `v0.4` tag 48 | * Verify the added tag with `git tag -l` 49 | * Push tags to remote origin with `git push --tags` 50 | * Open GitLab and navigate into `Repository > Tags` 51 | 52 | ## Bonus: 53 | 54 | * Add a tag with description: `git tag -m "End Of Day One Release" v0.5` 55 | 56 | !SLIDE supplemental solutions 57 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 58 | **** 59 | 60 | ## Add a Git tag 61 | 62 | **** 63 | 64 | ### Add tag 65 | 66 | @@@ Sh 67 | $ git log 68 | $ git tag v0.4 69 | $ git tag -m "End Of Day One Release" v0.5 70 | 71 | ### Verify tag 72 | 73 | @@@ Sh 74 | $ git tag -l 75 | 76 | ### Push tags to remote origin 77 | 78 | @@@ Sh 79 | $ git push --tags 80 | 81 | ### GitLab 82 | 83 | Navigate into the `training` project in `Repository > Tags`. 84 | -------------------------------------------------------------------------------- /day1/01_Introduction/02_Gui_Clients.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Git GUI Clients 3 | 4 | In this training, we will work with the command-line interface. 5 | 6 | These are a few recommendations for graphical clients: 7 | 8 | * Sourcetree (Windows, macOS) 9 | * GitKraken (Windows, Linux, macOS) 10 | * TortoiseGit (Windows) 11 | * GitExtensions (Windows) 12 | * GitHub Desktop (Windows, macOS) 13 | 14 | ~~~SECTION:handouts~~~ 15 | 16 | **** 17 | 18 | Additional GUI clients can be found here: 19 | 20 | * https://git-scm.com/download/gui/linux 21 | * https://gitextensions.github.io/ 22 | 23 | ~~~ENDSECTION~~~ 24 | 25 | !SLIDE smbullets noprint 26 | # Git GUI Clients: Sourcetree 27 | 28 | GUI Client: Sourcetree 29 | 30 | !SLIDE smbullets printonly 31 | # Git GUI Clients: Sourcetree 32 | 33 | GUI Client: Sourcetree 34 | 35 | ~~~SECTION:handouts~~~ 36 | 37 | **** 38 | 39 | Download: https://www.sourcetreeapp.com/ 40 | 41 | ~~~ENDSECTION~~~ 42 | 43 | !SLIDE smbullets noprint 44 | # Git GUI Clients: Gitkraken 45 | 46 | GUI Client: Gitkraken 47 | 48 | !SLIDE smbullets printonly 49 | # Git GUI Clients: Gitkraken 50 | 51 | GUI Client: Gitkraken 52 | 53 | ~~~SECTION:handouts~~~ 54 | 55 | **** 56 | 57 | Download: https://www.gitkraken.com/ 58 | 59 | ~~~ENDSECTION~~~ 60 | 61 | !SLIDE smbullets noprint 62 | # Git GUI Clients: GitHub Desktop 63 | 64 | GUI Client: GitHub Desktop 65 | 66 | !SLIDE smbullets printonly 67 | # Git GUI Clients: GitHub Desktop 68 | 69 | GUI Client: GitHub Desktop 70 | 71 | ~~~SECTION:handouts~~~ 72 | 73 | **** 74 | 75 | Download: https://desktop.github.com/ 76 | 77 | ~~~ENDSECTION~~~ 78 | -------------------------------------------------------------------------------- /global/extras/Linux-Cheatsheet-English.md: -------------------------------------------------------------------------------- 1 | # Linux Cheatsheet (English) 2 | 3 | ## General 4 | 5 | * Absolute paths start from `/`: `cd /usr/share/local` 6 | * Relative paths start from the current directory: `cd share/local` 7 | * Manpages can be used to get help on a command: `man ` 8 | 9 | ## Navigation 10 | 11 | | Description | Command | 12 | |---|---| 13 | | Clear terminal | `clear` | 14 | | Show path of the current directory | `pwd` | 15 | | Change into a directory | `cd ` | 16 | | List a directory | `ls -l ` | 17 | 18 | ## File/Directory Management 19 | 20 | | Description | Command | 21 | |---|---| 22 | | Create directory | `mkdir ` | 23 | | Remove empty directory | `rmdir ` | 24 | | Remove directory | `rm -ri ` | 25 | | Remove file | `rm ` | 26 | | Copy file | `cp ` | 27 | | Copy multiple files | `cp ` | 28 | | Copy directory | `cp -r ` | 29 | | Move or rename file | `mv ` | 30 | | Change permissions | `chmod u=rwx,g=rx,o=r ` | 31 | | Change ownership | `chown username:groupname ` | 32 | 33 | ## File Editing 34 | 35 | | Description | Command | 36 | |---|---| 37 | | Display the contents of files | `cat ` | 38 | | Read a file | `less ` | 39 | | Open a file with nano | `nano ` | 40 | | Open a file with VIM | `vim ` | 41 | | Execute a file | `source ` | 42 | 43 | ## Software Management 44 | 45 | | Description | Command | 46 | |---|---| 47 | | Install packages (Debian) | `apt install ` | 48 | | Install packages (EL) | `dnf install ` | 49 | | Extract tarball | `tar [-j] [-z] xf ` | 50 | | Download file | `wget ` | 51 | | Talk to HTTP endpoint | `curl -X GET ` | 52 | | Search for regular expression in file | `grep ` | 53 | | Search for regular expression in directory | `grep -r ` | 54 | 55 | ## tmux 56 | 57 | | Description | Command | 58 | |---|---| 59 | | Split pane with horizontal layout | `Ctrl + b %` | 60 | | Split pane with vertical layout | `Ctrl + b "` | 61 | | Switch to next pane | `Ctrl + b o` | 62 | | Toggle fullscreen on current pane | `Ctrl + b z` | 63 | | Close current pane | `Ctrl + b x` | 64 | -------------------------------------------------------------------------------- /global/extras/Linux-Cheatsheet-German.md: -------------------------------------------------------------------------------- 1 | # Linux Cheatsheet (Deutsch) 2 | 3 | ## Allgemein 4 | 5 | * Absolute Pfade fangen bei `/` an: `cd /usr/share/local` 6 | * Relative Pfade fangen im aktuellen Ordner an: `cd share/local` 7 | * Manpages geben Hilfe zu Befehlen: `man ` 8 | 9 | ## Navigation 10 | 11 | | Beschreibung | Befehl | 12 | |---|---| 13 | | Terminal leeren | `clear` | 14 | | Pfad des aktuellen Ordners anzeigen | `pwd` | 15 | | In einen Ordner wechseln | `cd ` | 16 | | Inhalte auflisten | `ls -l ` | 17 | 18 | ## Datei/Ordner Verwaltung 19 | 20 | | Beschreibung | Befehl | 21 | |---|---| 22 | | Ordner erstellen | `mkdir ` | 23 | | Ordner löschen | `rmdir ` | 24 | | Ordner rekursiv löschen | `rm -ri ` | 25 | | Datei löschen | `rm ` | 26 | | Datei kopieren | `cp ` | 27 | | Dateien kopieren | `cp ` | 28 | | Ordner kopieren | `cp -r ` | 29 | | Datei verschieben (oder umbenennen) | `mv ` | 30 | | Zugriffsrechte anpassen | `chmod u=rwx,g=rx,o=r ` | 31 | | Besitzer anpassen | `chown username:groupname ` | 32 | 33 | ## Datei Bearbeitung 34 | 35 | | Beschreibung | Befehl | 36 | |---|---| 37 | | Inhalte von einer oder mehreren Dateien auflisten | `cat ` | 38 | | Datei anzeigen | `less ` | 39 | | Datei in nano editieren | `nano ` | 40 | | Datei in VIM editieren | `vim ` | 41 | | Datei ausführen | `source ` | 42 | 43 | ## Software Management 44 | 45 | | Beschreibung | Befehl | 46 | |---|---| 47 | | Paket installieren (Debian) | `apt install ` | 48 | | Paket installieren (EL) | `dnf install ` | 49 | | TarBall entpacken | `tar [-j] [-z] xf ` | 50 | | Datei herunterladen | `wget ` | 51 | | HTTP Endpunkt ansprechen | `curl -X GET ` | 52 | | Regulären Ausdruck in Datei suchen | `grep ` | 53 | | Regulären Ausdruck in Ordner suchen | `grep -r ` | 54 | 55 | ## tmux 56 | 57 | | Beschreibung | Befehl | 58 | |---|---| 59 | | Fenster horizontal teilen | `Ctrl + b %` | 60 | | Fenster vertikal teilen | `Ctrl + b "` | 61 | | Zum nächsten Fenster wechseln | `Ctrl + b o` | 62 | | Vollbildmodus wechseln | `Ctrl + b z` | 63 | | Aktuelles Fenster schließen | `Ctrl + b x` | 64 | -------------------------------------------------------------------------------- /day1/04_Commits/02_Commits.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Work on Git History 3 | 4 | * `git commit` 5 | * Takes all files from the staging area 6 | * Alternatively `-a` or `--interactive` are possible 7 | * Verbose mode `-v` shows changes compared to latest commit 8 | * Uses the editor configured in `.gitconfig` (vim, nano, etc.) 9 | * `-m` allows for a short commit message without the editor 10 | 11 | Commits use the `user.name` and `user.email` settings to set the commit's author. 12 | 13 | Additionally, the date, time, and the checksum of the previous commit are stored. 14 | 15 | ~~~SECTION:handouts~~~ 16 | 17 | **** 18 | 19 | `git commit` collects and records all changes stages for commit. It uses the configured 20 | user name and email address as commit author. This command opens the configured editor 21 | requiring you to add a commit message. 22 | 23 | You can also create empty commits. This is sometimes done with the initial commit in a repository: 24 | 25 | @@@Sh 26 | git commit --allow-empty -m "Initial commit" 27 | 28 | ~~~ENDSECTION~~~ 29 | 30 | !SLIDE smbullets 31 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Commit Changes 32 | 33 | * Objective: 34 | * Modify files and commit your changes 35 | * Steps: 36 | * Change into `$HOME/training` 37 | * Modify the README.md file and add more docs 38 | * Add the README.md to the staging area 39 | * Commit the change to your Git history with `git commit -v` 40 | * Next steps: 41 | * Use `git log` to verify the commit 42 | 43 | !SLIDE supplemental exercises 44 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Commit Changes 45 | 46 | ## Objective: Commit Changes 47 | **** 48 | 49 | * Modify files and commit your changes 50 | 51 | ## Steps: 52 | 53 | **** 54 | 55 | * Change into `$HOME/training` 56 | * Modify the README.md file and add more text 57 | * Add the README.md to the staging area 58 | * Commit the change to your Git history with `git commit -v` 59 | 60 | ## Next steps: 61 | 62 | **** 63 | 64 | * Use `git log` to verify the history 65 | 66 | !SLIDE supplemental solutions 67 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 68 | **** 69 | 70 | ## Commit Changes 71 | 72 | **** 73 | 74 | ### Add/modify file 75 | 76 | @@@ Sh 77 | $ cd $HOME/training 78 | 79 | $ vim README.md 80 | 81 | `git commit` also has `-a` which should be used with care. 82 | 83 | $ git add README.md 84 | 85 | ### Commit the changed file 86 | 87 | @@@ Sh 88 | $ git status 89 | $ git commit -v README.md 90 | Update training notes 91 | 92 | My first commit :) 93 | 94 | Save and exit. 95 | 96 | ### Verify the Git history 97 | 98 | @@@ Sh 99 | $ git log 100 | -------------------------------------------------------------------------------- /day1/01_Introduction/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ Git Introduction 3 | 4 | !SLIDE smbullets 5 | # Why use Version Control Systems? 6 | 7 | * Version Control Systems (VCS) track changes over time 8 | * They track who changed what and when 9 | * Changes can be compared, reverted, coordinated with others 10 | 11 | Usually VCS are used for source code, text documents, web sites, or other text data. 12 | 13 | There are also data VCS for data science or machine learning projects. 14 | 15 | ~~~SECTION:handouts~~~ 16 | 17 | **** 18 | 19 | The most simple version control system is to copy 20 | directories and add a suffix like the last date it 21 | worked. Though this might cause trouble when you're 22 | in the wrong directory. Afterall it pollutes your 23 | filesystem structure over time. 24 | 25 | Long time ago developers invented version control 26 | systems which store the file revisions in a database. 27 | 28 | ~~~ENDSECTION~~~ 29 | 30 | !SLIDE noprint 31 | # Centralized and Distributed VCS 32 | 33 | * Central VCS 34 | * A central system contains the *version database*, clients work on this system 35 | * Examples: CVS, Subversion 36 | * Decentral VCS 37 | * Clients mirror the *version database* from a central system and work locally 38 | * Examples: Git, Mercurial 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
Central VCS
Decentral VCS
48 | 49 | !SLIDE smbullets printonly 50 | # Centralized and Distributed VCS 51 | 52 | * Central VCS 53 | * A central system contains the *version database*, clients work on this system 54 | * Examples: CVS, Subversion 55 | 56 | Central VCS 57 | 58 | * Decentral VCS 59 | * Clients mirror the *version database* from a central system and work locally 60 | * Examples: Git, Mercurial 61 | 62 | Decentral VCS 63 | 64 | !SLIDE 65 | # The History of Git 66 | 67 | Git was developed by the Linux kernel team in 2005. 68 | 69 | * They originally used BitKeeper, a closed-source commercial tool 70 | * They created Git due to some controversy with BitKeeper 71 | 72 | Their design goals: 73 | 74 | * A fully distributed VCS 75 | * Speed (when working with huge numbers of files) 76 | * Simple design 77 | * Non-linear development (branching) 78 | 79 | Git has become a de facto standard for version control. 80 | 81 | !SLIDE smbullets 82 | # The Git Workflow is local 83 | 84 | In Git we `clone` the data to our local system and work locally. 85 | 86 | * No network latency involved as with other VCS systems 87 | * Faster operations due to the local data 88 | * We can work offline and push changes later (i.e. when traveling) 89 | -------------------------------------------------------------------------------- /day1/01_Introduction/03_Configuration.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Git Configuration 3 | 4 | The Git command-line can be configured in multiple locations: 5 | 6 | * Global for the user 7 | * `$HOME/.gitconfig` 8 | * Local to the repository 9 | * `training/.git/config` 10 | 11 | Optional configuration can also be included: 12 | 13 | [includeIf "gitdir:/path/to/group/"] 14 | path = /path/to/foo.inc 15 | 16 | ~~~ENDSECTION~~~ 17 | 18 | !SLIDE 19 | # Git Configuration Sections 20 | 21 | The Git configuration has different sections. 22 | 23 | * Commit author [`user`] 24 | * Core functionality (e.g. editor, pager) [`core`] 25 | * Colors [`color`] and Aliases [`alias`] 26 | * And many more... 27 | 28 | Example: 29 | 30 | @@@ Sh 31 | [user] 32 | email = name.surname@example.com 33 | name = Name Surname 34 | [core] 35 | editor = nano 36 | [color "diff"] 37 | old = red bold 38 | new = blue bold 39 | 40 | ~~~SECTION:handouts~~~ 41 | 42 | **** 43 | 44 | More information can be found in the documentation at 45 | https://git-scm.com/book/tr/v2/Customizing-Git-Git-Configuration 46 | 47 | ~~~ENDSECTION~~~ 48 | 49 | !SLIDE smbullets 50 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Configure your username and email address 51 | 52 | * Objective: 53 | * Configure your username and email address using Git CLI commands 54 | * Steps: 55 | * Use `git config --global user.name "Your Name"` 56 | * Use `git config --global user.email "name@domain.com"` 57 | * Next steps: 58 | * Verify the changes with `git config --global --list` 59 | 60 | 61 | !SLIDE supplemental exercises 62 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Configure your username and email address 63 | 64 | ## Objective: Configure your username and email address 65 | **** 66 | 67 | * Configure your username and email address using Git CLI commands 68 | 69 | ## Steps: 70 | 71 | **** 72 | 73 | * Use `git config --global user.name "Your Name"` 74 | * Use `git config --global user.email "name@domain.com"` 75 | * Verify the changes with `git config --global --list` 76 | 77 | 78 | !SLIDE supplemental solutions 79 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 80 | **** 81 | 82 | ## Configure your username and email address 83 | 84 | **** 85 | 86 | ### Set the global username 87 | 88 | @@@ Sh 89 | $ git config --global user.name "Name Surname" 90 | 91 | ### Set the global email address 92 | 93 | @@@ Sh 94 | $ git config --global user.email "name.surname@example.com" 95 | 96 | ### Verification 97 | 98 | @@@ Sh 99 | $ git config --global --list 100 | 101 | In addition to that you can open the `.gitconfig` file in your $HOME directory. 102 | 103 | $ less $HOME/.gitconfig 104 | 105 | ### Notes 106 | 107 | You can also use `git config --global --list` to list all configured options. 108 | -------------------------------------------------------------------------------- /day1/04_Commits/05_Amend.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Amend changes to commits 3 | 4 | `git commit --amend` is a convenient way to modify the most recent commit. 5 | 6 | * Change the commit message (e.g. typos or better phrasing) 7 | * Fix a bug in already commited files 8 | * Add missing files into the last commit 9 | 10 | If you amend changes to a specific commit, a new unique commit ID is generated. 11 | 12 | This changes the Git history and we will learn later this might cause issues when collaborating. 13 | 14 | ~~~SECTION:handouts~~~ 15 | 16 | **** 17 | 18 | Amending other commits in Git history is also possible, explained later with `git rebase`. 19 | 20 | ~~~ENDSECTION~~~ 21 | 22 | !SLIDE smbullets 23 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Amend changes to commits 24 | 25 | * Objective: 26 | * Use git amend 27 | * Steps: 28 | * Change into `$HOME/training` 29 | * Modify README.md and add more text 30 | * Add README.md to the staging area and commit the change 31 | * Edit README.md again and add it to the staging area 32 | * Use `git commit --amend README.md` and explain what happens 33 | * Bonus: 34 | * Edit the commit message using `git commit --amend` 35 | 36 | !SLIDE supplemental exercises 37 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Amend changes to commits 38 | 39 | ## Objective: Use git amend 40 | **** 41 | 42 | * Use git amend 43 | 44 | ## Steps: 45 | 46 | **** 47 | 48 | * Change into `$HOME/training` 49 | * Modify README.md and add more text 50 | * Add README.md to the staging area and commit the change 51 | * Edit README.md again and add it to the staging area 52 | * Use `git commit --amend README.md` to add the change to the previous commit 53 | 54 | ## Bonus: 55 | 56 | * Adopt the commit message using `git commit --amend` 57 | 58 | !SLIDE supplemental solutions 59 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 60 | **** 61 | 62 | ## Amend changes to commits 63 | 64 | **** 65 | 66 | ### Add the files 67 | 68 | @@@ Sh 69 | $ cd $HOME/training 70 | 71 | $ vim README.md 72 | 73 | `git commit --amend` adds missing changes to the previous commit. 74 | 75 | ### Add README.md to the staging area and commit the change 76 | 77 | @@@ Sh 78 | $ git add README.md 79 | $ git status 80 | $ git commit -v README.md -m "Add documentation for Amend" 81 | 82 | ### Add a note to README.md again 83 | 84 | @@@ Sh 85 | $ vim README.md 86 | 87 | `git commit --amend` adds missing changes to the previous commit. 88 | I'm also able to edit the commit message. 89 | 90 | $ git add README.md 91 | $ git status 92 | 93 | ### Amend README.md to the previous commit 94 | 95 | @@@ Sh 96 | $ git commit --amend -v README.md 97 | Add documentation for 'git amend' 98 | 99 | Adopt the commit message as additional exercise above. 100 | 101 | @@@ Sh 102 | $ git status 103 | $ git show 104 | -------------------------------------------------------------------------------- /day1/03_Basics/02_Start.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Start a project 3 | 4 | * `git clone` 5 | * Clones a copy of an existing remote repository (i.e. from GitLab) 6 | * Can be modified with `--depth=5` 7 | * `git init` 8 | * Initializes a local empty Git repository 9 | 10 | ~~~SECTION:handouts~~~ 11 | 12 | **** 13 | 14 | `git clone` clones a copy of an existing remote Git repository 15 | 16 | `git init` initializes an empty directory as local Git repository 17 | 18 | When you clone a repository, Git automatically adds a shortcut called 19 | `origin` that points back to the "parent" repository, under the assumption 20 | that you'll want to interact with it further on down the road. This is 21 | called an `origin`. 22 | 23 | ~~~ENDSECTION~~~ 24 | 25 | !SLIDE smbullets 26 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Clone an existing Git repository 27 | 28 | * Objective: 29 | * Clone an existing Git repository 30 | * Steps: 31 | * Navigate to https://github.com/NETWAYS/gitlab-training 32 | * Copy the clone URL 33 | * Navigate into your home directory 34 | * Use `git clone` to clone the remote Git repository 35 | 36 | !SLIDE supplemental exercises 37 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Clone an existing Git repository 38 | 39 | ## Objective: Clone an existing Git repository 40 | **** 41 | 42 | * Clone an existing Git repository 43 | 44 | ## Steps: 45 | 46 | **** 47 | 48 | * Navigate to https://github.com/NETWAYS/gitlab-training 49 | * Copy the clone URL 50 | * Navigate into your home directory 51 | * Use `git clone` to clone the remote Git repository 52 | 53 | !SLIDE supplemental solutions 54 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 55 | **** 56 | 57 | ## Clone an existing Git repository 58 | 59 | **** 60 | 61 | ### Git clone 62 | 63 | @@@ Sh 64 | $ cd $HOME 65 | $ git clone https://github.com/NETWAYS/gitlab-training.git 66 | 67 | !SLIDE smbullets 68 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Initialize a local Git repository 69 | 70 | * Objective: 71 | * Initialize a new Git repository 72 | * Steps: 73 | * Create a new directory called `training` in your home directory 74 | * Change into it 75 | * Run `git init` 76 | 77 | We will be working inside this `training` directory unless noted otherwise. 78 | 79 | !SLIDE supplemental exercises 80 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Initialize a local Git repository 81 | 82 | ## Objective: Initialize Git repository 83 | **** 84 | 85 | * Initialize Git repository 86 | 87 | ## Steps: 88 | 89 | **** 90 | 91 | * Create a new directory called `training` in your home directory 92 | * Change into it 93 | * Run `git init` 94 | 95 | !SLIDE supplemental solutions 96 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 97 | **** 98 | 99 | ## Initialize Git repository 100 | 101 | **** 102 | 103 | ### Create a new Git repository 104 | 105 | @@@ Sh 106 | $ cd $HOME 107 | $ mkdir training 108 | $ cd training 109 | $ git init 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitLab Training 2 | 3 | This [training](https://www.netways.de/trainings/gitlab/) is designed 4 | as a two days hands-on training introducing Git, 5 | GitLab, Workflows, CI/CD and many best practices with GitLab and Git. 6 | 7 | The training participants will get an in-depth insight into the Git basics, 8 | configuration and "good" commits. They also learn about GitLab basics with 9 | repository and user management and continue to practice Git version control 10 | with real-life exercises. 11 | 12 | Moving along from standalone environments, participants collaborate with 13 | others and get an overview on different Git workflows. Solving conflicts, 14 | rebasing, merging and even squasing commits also is practiced. Continuing with 15 | practices, the training dives deep into continuous integration and 16 | delivery (CI/CD) with GitLab, runners and DevOps production pipelines. 17 | 18 | On top of that, the training provides more hints on GitLab usage (project 19 | management, Web IDE, API, etc.), tools, IDEs and UIs 20 | for working with Git and anything proven useful for daily best practice. 21 | 22 | Target audience are developers and Linux administrators. Linux basics 23 | and CLI/editor knowledge is required. 24 | 25 | We have developed our training material based on years of experience in 26 | development, professional services and training. To support our work, 27 | please join the official training sessions and get your ticket at [NETWAYS](https://www.netways.de/trainings/gitlab/). 28 | 29 | * [Handouts](https://github.com/NETWAYS/gitlab-training/releases) 30 | 31 | ## Provide your training 32 | 33 | Requirements: 34 | 35 | * Docker 36 | * https://nws.netways.de GitLab instances for the trainer and participants 37 | 38 | Start the presentation with the default settings: 39 | 40 | ``` 41 | ./global/wizard.sh 42 | [Enter] 43 | [Enter] 44 | ``` 45 | 46 | More instructions [here](https://github.com/NETWAYS/training-global#using-docker-to-build-and-serve-the-slide-deck). 47 | 48 | ## Render mermaid.js 49 | 50 | Many diagrams are rendered using [mermaid.js](https://mermaid.js.org/). The diagrams are stored in `*.mmd` files and are rendered using the mermaid-cli. 51 | 52 | ``` 53 | # Uses a containerized mermaid-cli to render all images 54 | bash render-images.sh 55 | ``` 56 | 57 | To render a single image: 58 | 59 | ``` 60 | docker run -u `id -u`:`id -g` --rm -v $(pwd)/_images/mermaid:/data minlag/mermaid-cli -e png -i "/data/image-to-render.mmd" 61 | ``` 62 | 63 | ### Environment 64 | 65 | The training material focuses on https://nws.netways.de where every attendee 66 | gets their own GitLab instance. 67 | 68 | The [vm/](vm/) directory provides a fallback VM which can be exported 69 | from Vagrant/VirtualBox and is provisioned onto the training notebook @NETWAYS. 70 | 71 | # Contribution 72 | 73 | Patches to fix mistakes or add optional content are always appreciated. If you want to see 74 | changes on the default content of the training we are open for suggestions but keep in mind 75 | that the training is intended for a two day hands-on training. 76 | 77 | The material is licensed under [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/). 78 | -------------------------------------------------------------------------------- /day2/01_Workflows/07_Gitflow.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Gitflow Workflow 3 | 4 | Gitflow is a strict branching model for larger projects 5 | 6 | * Based on Feature Branch Workflow 7 | * It assigns roles to different branches 8 | * Defines interaction between branches for releases 9 | 10 | !SLIDE smbullets noprint 11 | # Gitflow Workflow - Historical Branches 12 | 13 | The main branch is used for release history (including version tags). 14 | 15 | * The main branch is always `stable` and in production 16 | * A development branch is used for feature integration 17 | 18 |
Gitflow Workflow
19 | 20 | !SLIDE smbullets printonly 21 | # Gitflow Workflow - Historical Branches 22 | 23 | The main branch is used for release history (including version tags). 24 | 25 | * The main branch is always `stable` and in production 26 | * A development branch is used for feature integration 27 | 28 |
Gitflow Workflow
29 | 30 | !SLIDE smbullets noprint 31 | # Gitflow Workflow - Feature Branches 32 | 33 | Development happens on feature branches. 34 | 35 | * Feature branches use the development branch as their parent 36 | * Once development is completed, they are merged 37 | 38 |
Gitflow Workflow
39 | 40 | !SLIDE smbullets printonly 41 | # Gitflow Workflow - Feature Branches 42 | 43 | Development happens on feature branches. 44 | 45 | * Feature branches use the development branch as their parent 46 | * Once development is completed, they are merged to `develop` 47 | 48 |
Gitflow Workflow
49 | 50 | !SLIDE smbullets noprint 51 | # Gitflow Workflow - Release Branches 52 | 53 | New releases are prepared on a temporary release branch. 54 | 55 | * Release branches use the development branch as their parent 56 | * Preparation happens on the release branch, they are then merged to `main` 57 | 58 |
Gitflow Workflow
59 | 60 | !SLIDE smbullets printonly 61 | # Gitflow Workflow - Release Branches 62 | 63 | New releases are prepared on a temporary release branch. 64 | 65 | * Release branches use the development branch as their parent 66 | * Release preparation happens on the release branch 67 | * Once the release is ready, they are merged to `main` 68 | 69 |
Gitflow Workflow
70 | 71 | !SLIDE smbullets noprint 72 | # Gitflow Workflow - Maintenance Branches 73 | 74 | Maintenance/hotfix branches are used to quickly patch releases. 75 | 76 | * Hotfix branches the `main` branch as their parent 77 | * Hotfix branches are merged into `main`, tagged and also merged into `develop` 78 | 79 |
Gitflow Workflow
80 | 81 | !SLIDE smbullets printonly 82 | # Gitflow Workflow - Maintenance Branches 83 | 84 | Maintenance/hotfix branches are used to quickly patch releases. 85 | 86 | * Hotfix branches the `main` branch as their parent 87 | * Hotfix branches are merged into `main`, tagged and also merged into `develop` 88 | 89 |
Gitflow Workflow
90 | -------------------------------------------------------------------------------- /day1/04_Commits/04_History.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Examine the Git history 3 | 4 | * `git log` 5 | * Shows the commit history of the current branch 6 | * Supports `-10` notation to show a limited number of commits 7 | * `--oneline` can be used for less output 8 | 9 | * `git blame ` 10 | * Shows the authors of a file line-by-line 11 | * Supports `--color-lines` notation for grouping lines of the same commit 12 | 13 | ~~~SECTION:handouts~~~ 14 | 15 | **** 16 | 17 | `git log` shows the commit history of the current branch. 18 | 19 | `git blame ` shows the author line-by-line of the selected file. 20 | 21 | ~~~ENDSECTION~~~ 22 | 23 | !SLIDE smbullets 24 | # Examine the Git history 25 | 26 | * `git show` 27 | * Prints details of the latest commit 28 | * Commit IDs can be used to show a specific commit 29 | * Supports `-10` notation to show a limited number of commits 30 | * `git diff` 31 | * Show changes between working tree and last commit 32 | * Supports source and target parameters 33 | * Can be used to compare commits, branches, etc. 34 | 35 | ~~~SECTION:handouts~~~ 36 | 37 | **** 38 | 39 | `git show` will print the last commit details. If you want to print a specific commit id, add 40 | it afterwards. 41 | 42 | `git diff` shows changes between the current working tree and the last commit. You can 43 | also compare specific commits. 44 | 45 | ~~~ENDSECTION~~~ 46 | 47 | !SLIDE smbullets 48 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Examine the Commit History 49 | 50 | * Objective: 51 | * Examine the commit history 52 | * Steps: 53 | * Change into `$HOME/training` 54 | * Add and commit remaining changes e.g. `.gitignore` 55 | * Use `git log` to print the current history 56 | * Use `git show` to show specific commits (defaults to the latest) 57 | * Use `git diff` to compare changes between specific revisions 58 | * Use `git blame .gitignore` to see the file's authors 59 | 60 | Bonus: Try `git log` with the `--graph` and `--oneline` option. 61 | 62 | !SLIDE supplemental exercises 63 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Examine the Commit History 64 | 65 | ## Objective: Examine the Commit History 66 | **** 67 | 68 | * Examine the commit history 69 | 70 | ## Steps: 71 | 72 | **** 73 | 74 | * Change into `$HOME/training` 75 | * Add and commit remaining changes e.g. `.gitignore` 76 | * Use `git log` to print the current history 77 | * Use `git show` to show specific commits (defaults to the latest) 78 | * Use `git diff` to compare changes between specific revisions 79 | * Use `git blame .gitignore` to see the authors for the file 80 | 81 | Bonus: Try `git log` with the `--graph` and `--oneline` option. 82 | 83 | !SLIDE supplemental solutions 84 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 85 | **** 86 | 87 | ## Examine the Commit History 88 | 89 | **** 90 | 91 | ### Add and commit remaining changes 92 | 93 | @@@ Sh 94 | $ cd $HOME/training 95 | 96 | $ git status 97 | $ git add .gitignore 98 | $ git commit -v .gitignore -m "Add .gitignore file" 99 | 100 | ### Use git log 101 | 102 | @@@ Sh 103 | $ git log 104 | 105 | ### Use git show 106 | 107 | @@@ Sh 108 | $ git show 109 | $ git show 110 | $ git show -2 111 | 112 | ### Use git diff 113 | 114 | @@@ Sh 115 | $ git diff 116 | $ git diff 117 | 118 | ### Use git blame 119 | 120 | @@@ Sh 121 | $ git blame .gitignore 122 | -------------------------------------------------------------------------------- /day1/03_Basics/05_Gitignore.md: -------------------------------------------------------------------------------- 1 | !SLIDE 2 | # Exclude files with .gitignore 3 | 4 | The `.gitignore` file can be used to exclude files from being tracked by Git. Each line specifies a pattern to ignore. The file is read from top to bottom. 5 | 6 | * Build directories for compilation (e.g. `debug/`, `release/`) 7 | * Files generated at runtime (e.g. test results or stats) 8 | * Temporary files (e.g. `*.tmp`, `temp/`) 9 | * User specific settings or secrets 10 | 11 | Example: 12 | 13 | $ cat .gitignore 14 | release/ 15 | !release/latest 16 | *.tmp 17 | 18 | Personal ignore patterns can be defined in `.git/info/exclude`. 19 | 20 | ~~~SECTION:handouts~~~ 21 | 22 | **** 23 | 24 | You can use wildcard pattern matches for files. 25 | If you'll end the string with a '/' git will only 26 | ignore directories instead of both directories and files 27 | matching the pattern. 28 | 29 | If you want to ignore a file globally in your repository 30 | you can preceed the path with `**/` which means `any directory` 31 | 32 | Example for ignoring a debug file anywhere in your repository: 33 | 34 | **/debug 35 | 36 | If you prefer to keep `.gitignore` files in specific directories 37 | and not a global file, this will also work 38 | 39 | ~~~ENDSECTION~~~ 40 | 41 | !SLIDE smbullets 42 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add .gitignore file and exclude files/directories 43 | 44 | * Objective: 45 | * Add a .gitignore file and exclude files/directories 46 | * Steps: 47 | * Change into `$HOME/training` 48 | * Create a file `generated.tmp` 49 | * Create a directory `debug` with the file `.timestamp` 50 | * Examine the state with `git status` 51 | * Exclude them in a .gitignore file 52 | * Examine the state with `git status` 53 | 54 | !SLIDE supplemental exercises 55 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add .gitignore file and exclude files/directories 56 | 57 | ## Objective: Examine current changes 58 | **** 59 | 60 | * Add .gitignore file and exclude files/directories 61 | 62 | ## Steps: 63 | 64 | * Change into `$HOME/training` 65 | * Create a file `generated.tmp` 66 | * Create a directory `debug` with the file `.timestamp` 67 | * Examine the state with `git status` 68 | * Exclude them in a .gitignore file 69 | * Examine the state with `git status` 70 | 71 | !SLIDE supplemental solutions 72 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 73 | **** 74 | 75 | ## Add .gitignore file and exclude files/directories 76 | 77 | **** 78 | 79 | ### Add file/directory 80 | 81 | Create a dummy file and directory which contains a file itself. This is 82 | for simulating unwanted files in the working directory. 83 | 84 | @@@ Sh 85 | $ cd $HOME/training 86 | 87 | $ touch generated.tmp 88 | $ mkdir debug 89 | $ touch debug/.timestamp 90 | 91 | ### Examine the state with git status 92 | 93 | @@@ Sh 94 | $ git status 95 | On branch main 96 | 97 | Untracked files: 98 | (use "git add ..." to include in what will be committed) 99 | 100 | debug/ 101 | generated.tmp 102 | 103 | ### Add .gitignore file 104 | 105 | @@@ Sh 106 | $ vim .gitignore 107 | *.tmp 108 | debug/ 109 | 110 | Files matching the `*.tmp` pattern in the current directory 111 | will be excluded. Furthermore the `debug` directory (note the 112 | trailing slash). 113 | 114 | ### Examine the state with git status 115 | 116 | @@@ Sh 117 | $ git status 118 | On branch main 119 | 120 | Untracked files: 121 | (use "git add ..." to include in what will be committed) 122 | 123 | .gitignore 124 | 125 | 126 | We'll learn how to add and commit the untracked `.gitignore` file 127 | in later examples. 128 | -------------------------------------------------------------------------------- /day1/01_Introduction/04_Basics.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Core Concepts of Git 3 | 4 | * All work is done in a **repository**, it contains our files 5 | * Snapshots track changes in these files, these are called **commits** 6 | * A chain of these commits is called a **branch** 7 | 8 | !SLIDE smbullets 9 | # Git Commit 10 | 11 | A Commit is a snapshot in time, containing: an author, a timestamp and the current state of the files. 12 | 13 | Git stores compressed snapshots (aka BLOBs) of the files, not diffs. It keeps track of changes with checksums (SHA) of these BLOBs. 14 | 15 | If a file does not change between commits, Git just refers back to the previous commit. 16 | 17 |
Git Snapshots
18 | 19 | !SLIDE smbullets 20 | # Git Branch 21 | 22 | Since each commit has a pointer to the commit directly before it (its parent), they form a chain (or linked list). 23 | 24 | This chain is called a branch. 25 | 26 | Branches represent an isolated line of development. 27 | 28 |
Feature Branch Workflow
29 | 30 | !SLIDE smbullets noprint 31 | # The Three States 32 | 33 | Files in a repository go through three states before being version controlled. 34 | 35 | * Working directory ("modified") 36 | * Staging area ("staged") 37 | * Git directory ("committed") 38 | 39 | Analogy: Writing on a desk or packing a parcel. 40 | 41 |
Git Stages
42 | 43 | !SLIDE smbullets printonly 44 | # The Three States 45 | 46 | Files in a repository go through three states before being version controlled. 47 | 48 | * Working directory ("modified") 49 | * Staging area ("staged") 50 | * Git directory ("committed") 51 | 52 |
Git Stages
53 | 54 | ~~~SECTION:handouts~~~ 55 | 56 | **** 57 | 58 | `Modified` means that you have changed the file but have not committed 59 | it to your Git database yet. 60 | 61 | `Staged` means that you have marked a modified or added file in its 62 | current version to go into your next commit snapshot. 63 | 64 | `Committed` means that the data is safely stored in your local database. 65 | 66 | The `working directory` is a single checkout of one version of the project. 67 | These files are pulled out of the compressed database in the Git directory 68 | and placed on disk for you to use or modify. 69 | 70 | The `staging area` is a file, generally located in your Git directory, that 71 | stores information about what will go into your next commit. 72 | It is sometimes referred to as the "index", but it’s also common to refer 73 | to it as the staging area. 74 | 75 | The `Git directory` is where Git stores the metadata and object database 76 | for your project. This is the most important part of Git, and it is what 77 | is copied when you clone a repository from another computer. 78 | 79 | ~~~ENDSECTION~~~ 80 | 81 | !SLIDE smbullets 82 | # The Git Commit Workflow 83 | 84 | * Modify files in the `working directory` 85 | * Stage the files in the `staging area` ("git add") to prepare a commit 86 | * Create a snapshot ("git commit") 87 | * Takes all files from the `staging area` 88 | * Stores the snapshot permanently in the `.git directory` 89 | 90 | ~~~SECTION:handouts~~~ 91 | 92 | **** 93 | 94 | * If a particular version of a file is in the `.git directory`, it’s considered `committed` 95 | 96 | * `Staged` means that the file has been modified and it was added to the staging area 97 | 98 | * `Modified` means that the file was changed since it was checked out but has not been staged yet 99 | 100 | ~~~ENDSECTION~~~ 101 | -------------------------------------------------------------------------------- /day1/05_Branching/02_head_smart_pointers.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # What is "HEAD" in Git? 3 | 4 | `HEAD` is a pointer to the latest commit in the current branch. 5 | 6 | `HEAD` can be used in Git commands as reference. 7 | 8 | * `HEAD^` identifies the second latest commit. 9 | * `HEAD~9` points to the tenth latest commit. Counting starts at zero. 10 | 11 | Hint: Git stores this information in the file `.git/HEAD`. 12 | 13 | !SLIDE smbullets 14 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Show the second latest commit 15 | 16 | * Objective: 17 | * Use `HEAD` and only show the second latest commit 18 | * Steps: 19 | * Change into `$HOME/training` 20 | * Combine `git show` with `HEAD^` or `HEAD~1` 21 | 22 | !SLIDE supplemental exercises 23 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Show the second latest commit 24 | 25 | ## Objective: Show the second latest commit 26 | **** 27 | 28 | * Show the second latest commit 29 | 30 | ## Steps: 31 | 32 | **** 33 | 34 | * Change into `$HOME/training` 35 | * Use `HEAD` and only show the second latest commit 36 | 37 | 38 | !SLIDE supplemental solutions 39 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 40 | **** 41 | 42 | ## Show the second latest commit 43 | 44 | **** 45 | 46 | ### Example 47 | 48 | @@@ Sh 49 | $ cd $HOME/training 50 | $ git show HEAD^ 51 | 52 | or 53 | 54 | @@@ Sh 55 | $ git show HEAD~1 56 | 57 | !SLIDE smbullets 58 | # Branches and "HEAD" 59 | 60 | Branch names are also pointers to their respective latest commit. 61 | 62 | This means, you don't need to change branches to 63 | 64 | * Show different branch histories 65 | * Show specific commits where you don't know the commit ID 66 | * Compare branches and committed code 67 | 68 | Example: 69 | 70 | $ git show main 71 | commit b825ff86e4022a8fbcf52cb5a1d9a1984bd2a310 (main) 72 | 73 | 74 | ~~~SECTION:handouts~~~ 75 | 76 | **** 77 | 78 | We can view the content of the branch name pointer as such: 79 | 80 | cat .git/refs/heads/feature/foobar 81 | fefe5d45980e72488e633b8ffbb25293d22389886 82 | 83 | ~~~ENDSECTION~~~ 84 | 85 | !SLIDE smbullets 86 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Show history of different branch 87 | 88 | * Objective: 89 | * Use `git log` on the main branch and other branches 90 | * Steps: 91 | * Create a new branch aside from main, if not existing: `git checkout -b feature/docs` 92 | * Switch to the main branch 93 | * Use `git log feature/docs` 94 | * Bonus: 95 | * Modify files and commit changes 96 | * Diff current HEAD against `feature/docs` branch 97 | 98 | !SLIDE supplemental exercises 99 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Show history of different branch 100 | 101 | ## Objective: Delete the branch 102 | **** 103 | 104 | * Use `git log` on the main branch and other branches 105 | 106 | ## Steps: 107 | 108 | **** 109 | 110 | * Create a new branch aside from main, if not existing: `git checkout -b feature/docs` 111 | * Switch to the main branch 112 | * Use `git log feature/docs` 113 | 114 | ## Bonus: 115 | 116 | **** 117 | 118 | * Modify files and commit changes 119 | * Diff current HEAD against `feature/docs` branch 120 | 121 | !SLIDE supplemental solutions 122 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 123 | **** 124 | 125 | ## Show history of different branch 126 | 127 | **** 128 | 129 | ### Create a new branch, if not exisiting 130 | 131 | @@@ Sh 132 | $ git checkout main 133 | $ git checkout -b feature/dpcs 134 | 135 | ### Switch to the main branch 136 | 137 | @@@ Sh 138 | $ git checkout main 139 | 140 | ### Show the history of the other branch 141 | 142 | @@@ Sh 143 | $ git show feature/docs 144 | 145 | ### Commit change on main 146 | 147 | @@@ Sh 148 | $ echo "I understand HEAD now" >> README.md 149 | $ git add README.md 150 | $ git commit -v README.md -m "What I've learned so far: HEAD" 151 | 152 | ### Show diff between HEAD and branch 153 | 154 | @@@ Sh 155 | $ git diff HEAD feature/docs 156 | -------------------------------------------------------------------------------- /day1/03_Basics/04_Status.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Examine the current state 3 | 4 | * `git status` 5 | * Shows current working tree status 6 | * Shows modified files and untracked files 7 | * Shows contents of the staging area 8 | * `--short` can be used for less output 9 | 10 | ~~~SECTION:handouts~~~ 11 | 12 | **** 13 | 14 | `git status` shows the current working tree status. 15 | Untracked files and changes (not) staged for a commit. 16 | 17 | ~~~ENDSECTION~~~ 18 | 19 | !SLIDE smbullets 20 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Examine current changes 21 | 22 | * Objective: 23 | * Examine current changes 24 | * Steps: 25 | * Change into `$HOME/training` 26 | * Edit README.md and add more text 27 | * Use `git status` to see unstaged changes 28 | * Add the changed files to the staging area 29 | * Use `git status` again 30 | 31 | !SLIDE supplemental exercises 32 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Examine current changes 33 | 34 | ## Objective: Examine current changes 35 | **** 36 | 37 | * Examine current changes 38 | 39 | ## Steps: 40 | 41 | * Change into `$HOME/training` 42 | * Edit README.md 43 | * Use `git status` to see unstaged changes 44 | * Add the changed files to the staging area 45 | * Use `git status` again 46 | 47 | 48 | !SLIDE supplemental solutions 49 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 50 | **** 51 | 52 | ## Examine current changes 53 | 54 | **** 55 | 56 | ### Change files 57 | 58 | @@@ Sh 59 | $ cd $HOME/training 60 | 61 | $ vim README.md 62 | # Git Training Notes 63 | 64 | I've learned about `git add` already 65 | 66 | ``` 67 | git status 68 | ``` 69 | 70 | Modify and save the file. 71 | 72 | ### Use git status 73 | 74 | @@@ Sh 75 | $ git status 76 | 77 | You'll recognize the unstaged changes compared to your staging area. 78 | 79 | ### Add the change to the staging area 80 | 81 | @@@ Sh 82 | $ git add README.md 83 | 84 | ### Use git status again 85 | 86 | @@@ Sh 87 | $ git status 88 | 89 | 90 | !SLIDE smbullets 91 | # Examine the current state: Diff 92 | 93 | * `git diff` 94 | * Compares changes between modified working tree and latest commit 95 | * The output is a unified diff similar to `diff -ur file1 file2` 96 | 97 | Later we will learn how to compare other objects (i.e. commits and branches). 98 | 99 | ~~~SECTION:handouts~~~ 100 | 101 | **** 102 | 103 | `git diff` shows changes between the current working tree and the last commit. You can also compare specific commits. 104 | 105 | ~~~ENDSECTION~~~ 106 | 107 | !SLIDE smbullets 108 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Use Git Diff 109 | 110 | * Objective: 111 | * Use `git diff` 112 | * Steps: 113 | * Change into `$HOME/training` 114 | * Edit README.md 115 | * Use `git diff` to compare unstaged changes 116 | * Add the changed file to the staging area 117 | * Use `git diff` again 118 | * Explain what `git diff --staged` does 119 | 120 | !SLIDE supplemental exercises 121 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Use Git Diff 122 | 123 | ## Objective: Play with Git Diff 124 | **** 125 | 126 | * Use `git diff` 127 | 128 | ## Steps: 129 | 130 | * Change into `$HOME/training` 131 | * Edit README.md 132 | * Use `git diff` to compare unstaged changes 133 | * Add the changed file to the staging area 134 | * Use `git diff` again 135 | * Explain what `git diff --staged` does 136 | 137 | !SLIDE supplemental solutions 138 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 139 | **** 140 | 141 | ## Play with Git Diff 142 | 143 | **** 144 | 145 | ### Change files 146 | 147 | @@@ Sh 148 | $ vim README.md 149 | 150 | I've also learned the difference between local changes and the staging area. 151 | 152 | Modify and save the file. 153 | 154 | ### Use git diff 155 | 156 | @@@ Sh 157 | $ git diff 158 | 159 | You'll recognize the unstaged changes compared to your staging area. 160 | 161 | ### Add the change to the staging area 162 | 163 | @@@ Sh 164 | $ git add README.md 165 | 166 | ### Use git diff again 167 | 168 | @@@ Sh 169 | $ git diff 170 | 171 | ### Use git diff --staged 172 | 173 | @@@ Sh 174 | $ git diff --staged 175 | 176 | This compares the staged changes for the commit with the latest committed changes. 177 | -------------------------------------------------------------------------------- /day1/03_Basics/03_Changes.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Add current changes 3 | 4 | * `git add` 5 | * Adds new files from the working directory to the staging area 6 | * Adds modified files to the staging area 7 | * `-A` adds all files. Question: When is this applicable? 8 | * `git mv` 9 | * Renames files tracked by Git 10 | 11 | ~~~SECTION:handouts~~~ 12 | 13 | **** 14 | 15 | `git add` will add the file(s) and their content to the staging area 16 | waiting for the commit. This applies to both, new files and also modified 17 | files. 18 | 19 | If you're using `-A` to add all files, you need to ensure that 20 | unwanted files are not added. Learn more about `git rm --cached` in the next 21 | slide to selectively unstage added changes. 22 | 23 | `git mv` renames an existing file tracking the change for the commit. If you 24 | manually move the file, you will need to rm and add it again. 25 | 26 | ~~~ENDSECTION~~~ 27 | 28 | !SLIDE smbullets 29 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add a new README.md file 30 | 31 | * Objective: 32 | * Add a new README.md file 33 | * Steps: 34 | * Change into `$HOME/training` 35 | * Create README.md and add `# GitLab Training Notes` as first line 36 | * Hint: You can keep notes from the training in the `README.md` file 37 | * Use `git add` to add README.md to the staging area 38 | * Next steps: 39 | * Verify the change with `git status` 40 | 41 | Markdown is a markup language that is rendered by GitLab as HTML. 42 | Best practice is to have a README.md file written in Markdown in every project, which is great for documentation. 43 | 44 | !SLIDE supplemental exercises 45 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add a new README.md file 46 | 47 | ## Objective: Add a new README.md file to the current change area 48 | **** 49 | 50 | * Add a new README.md file 51 | 52 | Hint: https://www.markdownguide.org/basic-syntax/ 53 | 54 | ## Steps: 55 | 56 | **** 57 | 58 | * Change into `$HOME/training` 59 | * Create README.md and add `# GitLab Training Notes` as first line 60 | * Use `git add` to add the file to the current staging area 61 | * Verify the change with `git status` 62 | 63 | 64 | !SLIDE supplemental solutions 65 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 66 | **** 67 | 68 | ## Add a new README.md file 69 | 70 | **** 71 | 72 | ### Example 73 | 74 | @@@ Sh 75 | $ cd $HOME/training 76 | $ echo "# GitLab Training Notes" > README.md 77 | $ git add README.md 78 | $ git status 79 | 80 | ~~~ENDSECTION~~~ 81 | 82 | !SLIDE smbullets 83 | # Remove changes 84 | 85 | * `git rm --cached` 86 | * Removes files from the staging area 87 | * Hint: This comes in handy with `git add -A` before 88 | * `git rm` 89 | * Removes the files from working tree and Git repository 90 | * Note: Once committed, files will be visible in the Git history, and can be restored from it 91 | 92 | ~~~SECTION:handouts~~~ 93 | 94 | **** 95 | 96 | `git rm --cached` resets files added to the staging area. You can also use it to 97 | reset commits from the history. 98 | 99 | This also is helpful when you need to add 95 out of 100 changes. First, use `git add -A` 100 | and then selectively unstage the unwanted 5 changes. 101 | 102 | `git rm` removes the file from the working tree and also from the staging area. 103 | 104 | ~~~ENDSECTION~~~ 105 | 106 | !SLIDE smbullets 107 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Reset File from Staging Area 108 | 109 | * Objective: 110 | * Remove a file from the staging area 111 | * Steps: 112 | * Change into `$HOME/training` 113 | * Remove the previously added README.md file from the staging area with `git rm --cached README.md` 114 | * Verify it with `git status` and explain what happened 115 | * Re-add the README.md and examine again with `git status` 116 | 117 | !SLIDE supplemental exercises 118 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Reset File from Staging Area 119 | 120 | ## Objective: Reset File from Staging Area 121 | **** 122 | 123 | * Remove a file from staging area 124 | 125 | ## Steps: 126 | 127 | **** 128 | 129 | * Change into `$HOME/training` 130 | * Remove the previously added `README.md` file from the staging area with `git rm --cached README.md` 131 | * Verify it with `git status` and explain what happened 132 | * Re-add the `README.md` and examine again with `git status` 133 | 134 | !SLIDE supplemental solutions 135 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 136 | **** 137 | 138 | ## Remove file from staging area. 139 | 140 | **** 141 | 142 | ### Example 143 | 144 | @@@ Sh 145 | $ cd $HOME/training 146 | 147 | $ git status 148 | 149 | $ git rm --cached README.md 150 | 151 | $ git status 152 | 153 | $ git add README.md 154 | 155 | $ git status 156 | -------------------------------------------------------------------------------- /global/README.md: -------------------------------------------------------------------------------- 1 | # NETWAYS Training global artifacts 2 | 3 | This repository holds global artifacts for a specific NETWAYS training. For example, layouts, templates and images 4 | resides here. 5 | 6 | ## How to use 7 | 8 | ### 1. Add global resource directory to your project 9 | 10 | The global resource dir is introduced by using git subtree mechanism. This keeps the training repository clear from 11 | special git instructions and let users easily clone and use the repository. In addition, the external code (global) can 12 | be patched locally if needed and pinned to a specific version. 13 | 14 | #### Add a new remote to git 15 | ```bash 16 | $ git remote add global https://github.com/NETWAYS/training-global.git 17 | $ git fetch global 18 | remote: Counting objects: 157, done. 19 | remote: Compressing objects: 100% (122/122), done. 20 | remote: Total 157 (delta 24), reused 154 (delta 21), pack-reused 0 21 | Receiving objects: 100% (157/157), 27.82 MiB | 913.00 KiB/s, done. 22 | Resolving deltas: 100% (24/24), done. 23 | From https://github.com/NETWAYS/training-global 24 | * [new branch] master -> global/master 25 | ``` 26 | 27 | #### Create a new subtree named global 28 | ```bash 29 | $ git subtree add --squash --prefix=global/ global master 30 | git fetch global master 31 | From https://github.com/NETWAYS/training-global 32 | * branch master -> FETCH_HEAD 33 | Added dir 'global' 34 | ``` 35 | 36 | ### 2. Create a directory to provide trainer introduction 37 | 38 | This is probably easy but we want to achieve that changes in this directory does not influence the source code from our 39 | training. 40 | 41 | ```bash 42 | $ mkdir trainer 43 | $ touch trainer/.keep 44 | $ echo 'trainer/' >> .gitignore 45 | $ git add -f trainer/ # Force add to git because it is in .gitignore 46 | $ git commit -m "Add directory for trainer introduction" 47 | ``` 48 | 49 | After this step you are able to copy files into the directory which are not captured by the git commit staging process. 50 | 51 | ### 3. Link stylesheet to root level 52 | 53 | ```bash 54 | $ ln -s global/layouts/netways.css 55 | ``` 56 | 57 | This step seems ugly and we totally agree with you. In order to print and convert the training slides into pdf, this 58 | step is absolutely needed to succeed. 59 | 60 | ### 4. Create a showoff.json stub file 61 | 62 | ```json 63 | { 64 | "name": "My awesome training", 65 | "subtitle": "Train awesome stuff", 66 | "author": "Colt Seavers & Howie Munson", 67 | "release": "0.9.0", 68 | 69 | "favicon": "global/favicon.ico", 70 | 71 | "protected": ["presenter", "onepage", "print"], 72 | 73 | "user": "netways", 74 | "password": "awesome", 75 | 76 | "templates" : { 77 | "default": "global/layouts/netways.tpl" 78 | }, 79 | 80 | "sections": [ 81 | {"section": "global/pre/netways/title"}, 82 | {"section": "global/pre/toc"}, 83 | {"section": "trainer"}, 84 | {"section": "global/pre/netways/about"}, 85 | {"section": "global/pre/hints"}, 86 | 87 | {"section": "sections/..."}, 88 | 89 | {"section": "global/post"} 90 | ] 91 | } 92 | ``` 93 | 94 | After the file is created you're able to start the slide deck (showoff): 95 | 96 | ```bash 97 | $ showoff serve 98 | ``` 99 | 100 | ## Update global directory from GitHub 101 | 102 | ```bash 103 | $ git fetch global 104 | $ git subtree pull --squash --prefix=global/ global master 105 | ``` 106 | 107 | Please make sure that no changed files present or staged commits pending. 108 | 109 | ## Using a Containers to build and serve the slide deck 110 | 111 | ### Building the Image 112 | 113 | ```bash 114 | make image 115 | make image RUNTIME=podman 116 | ``` 117 | 118 | ### Run showoff 119 | 120 | ```bash 121 | docker run -it --rm -v "$PWD:/training" -p "9090:9090" netways/showoff:0.20.4 122 | ``` 123 | 124 | ### Build static html files 125 | 126 | ```bash 127 | docker run -it --rm -v "$PWD:/training" netways/showoff:0.20.4 \ 128 | showoff static print 129 | ``` 130 | 131 | ### Create PDF from static html files 132 | 133 | ```bash 134 | docker run -it --rm -v "$PWD:/training" \ 135 | netways/showoff:0.20.4 \ 136 | wkhtmltopdf -s A5 --print-media-type \ 137 | --footer-left \[page\] --footer-right '© NETWAYS' \ 138 | static/index.html test.pdf 139 | ``` 140 | 141 | ### NETWAYS Training Wizard 142 | 143 | Alternatively you can simply run the NETWAYS training wizard: 144 | 145 | ``` 146 | $ ./global/wizard.sh 147 | ########################### 148 | NETWAYS Training Wizard 149 | ########################### 150 | 151 | ### LAYOUT ### 152 | 153 | [1] NETWAYS 154 | [2] OSMC 155 | [3] OSDC 156 | [4] OSBConf 157 | 158 | Which Layout? [1-4] (Default: 1): 159 | 160 | ### MODE ### 161 | 162 | [1] serve 163 | [2] print 164 | 165 | Which mode? [1-2] (Default: 1): 2 166 | 167 | ### PRINT ### 168 | 169 | [1] Handouts 170 | [2] Handouts & Solutions 171 | [3] Handouts & Exercises & Solutions 172 | [4] Exercises & Solutions 173 | 174 | What to print? [1-4] (Default: 2): 1 175 | Which version? (Default: 0.0.1): 176 | ``` 177 | -------------------------------------------------------------------------------- /day2/01_Workflows/03_Feature_Branch.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets noprint 2 | # Feature Branch Workflow 3 | 4 | Instead of working on `main` development happens in named branches. 5 | 6 | * No interference with the main codebase 7 | * Feature branches can be rebased against a stable `main` branch on demand 8 | * Ideally, the `main` branch would not contain broken code 9 | 10 |
Feature Branch Workflow
11 | 12 | !SLIDE smbullets printonly 13 | # Feature Branch Workflow 14 | 15 | Instead of working on `main` development happens in named branches. 16 | 17 | * No interference with the main codebase 18 | * Feature branches can be rebased against a stable `main` branch on demand 19 | * Ideally, the `main` branch would not contain broken code 20 | 21 |
Feature Branch Workflow
22 | 23 | !SLIDE smbullets 24 | # Feature Branch Workflow - Creating Branches 25 | 26 | A new branch is created for a particular feature (or bugfix). 27 | 28 | * Feature branches can be pushed for collaboration with other developers 29 | * Feature branches are eventually merged into `main` and deleted 30 | 31 | Hint: Use descriptive branch names, e.g. `feature/docs-workflows` or `fix/login-bug`. 32 | 33 | !SLIDE smbullets 34 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Use Feature Branches 35 | 36 | * Objective: 37 | * Create a new feature branch `feature/docs-workflows` 38 | * Steps: 39 | * Change into `$HOME/training` 40 | * Use `git checkout -b feature/docs-workflows` to create a new feature branch based on the main 41 | * Add and commit changes 42 | * Push the branch to your central repository 43 | 44 | !SLIDE supplemental exercises 45 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Use Feature Branches 46 | 47 | ## Objective: Create a new feature branch 48 | **** 49 | 50 | * Create a new feature branch 51 | 52 | ## Steps: 53 | 54 | **** 55 | 56 | * Change into `$HOME/training` 57 | * Use `git checkout -b feature/docs-workflows` to create a new feature branch based on the main 58 | * Add and commit changes 59 | * Push the branch to your central repository 60 | 61 | !SLIDE supplemental solutions 62 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 63 | **** 64 | 65 | ## Use Feature Branches 66 | 67 | **** 68 | 69 | ### Create a new branch 70 | 71 | The new branch `feature/docs-workflows` will be based on the `main` branch. 72 | 73 | @@@ Sh 74 | $ cd $HOME/training 75 | $ git checkout main 76 | $ git checkout -b feature/docs-workflows 77 | 78 | ### Add and commit changes 79 | 80 | @@@ Sh 81 | $ vim README.md 82 | 83 | ## Workflows 84 | 85 | Central Workflow and now feature workflows with descriptive branch names. 86 | 87 | $ git add README.md 88 | $ git commit -v README.md -m "Update docs for Git workflows" 89 | 90 | ### Push your feature branch 91 | 92 | @@@ Sh 93 | $ git push -u origin feature/docs-workflows 94 | 95 | 96 | !SLIDE smbullets 97 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Merge Feature Branches 98 | 99 | * Objective: 100 | * Update and merge feature branch `feature/docs-workflows` 101 | 102 | * Steps: 103 | * Checkout the feature branch `feature/docs-workflows` 104 | * Edit `README.md`, add and commit the changes 105 | * Diff the feature branch to the current main with `git diff main` 106 | * Checkout the `main` branch, merge the feature branch as non-fast-forward with `--no-ff` 107 | * Show the history tree inside GitLab and explain why the forced merge commit with `--no-ff` is important 108 | 109 | !SLIDE supplemental exercises 110 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Merge Feature Branches 111 | 112 | ## Objective: Merge Feature Branches 113 | **** 114 | 115 | * Update and merge feature branch `feature/docs-workflows` 116 | 117 | ## Steps: 118 | 119 | **** 120 | 121 | * Change into `$HOME/training` 122 | * Checkout the feature branch `feature/docs-workflows` 123 | * Edit `README.md`, add and commit the changes 124 | * Diff the feature branch to the current main with `git diff main` 125 | * Checkout the `main` branch 126 | * Merge the feature branch as non-fast-forward with `--no-ff` 127 | * Show the history tree inside GitLab 128 | 129 | ## Bonus: 130 | 131 | **** 132 | 133 | * Explain why the forced merge commit with `--no-ff` is important 134 | 135 | !SLIDE supplemental solutions 136 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 137 | **** 138 | 139 | ## Merge Feature Branches 140 | 141 | **** 142 | 143 | ### Checkout the feature branch and add a commit 144 | 145 | @@@ Sh 146 | $ cd $HOME/training 147 | $ git checkout feature/docs-workflows 148 | $ vim README.md 149 | 150 | I'm learning about workflows today. 151 | 152 | $ git add README.md 153 | $ git commit -v README.md -m "Update docs for workflows" 154 | $ git push origin feature/docs-workflows 155 | 156 | ### Checkout the feature branch and compare it with the main branch 157 | 158 | @@@ Sh 159 | $ git branch 160 | $ git checkout feature/docs-workflows 161 | $ git diff main feature/docs 162 | 163 | ### Checkout the main and merge the feature branch 164 | 165 | @@@ Sh 166 | $ git checkout main 167 | $ git merge --no-ff feature/docs-workflows 168 | 169 | In this commit message, I may add a reference to a GitLab issue like this 170 | to automatically resolve it after merge. 171 | 172 | fixes #12 173 | -------------------------------------------------------------------------------- /day2/01_Workflows/05_Gitlab_Workflow.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets noprint 2 | # GitLab Workflow 3 | 4 | A workflow similar to feature branches. 5 | 6 | * Manage branch access with roles and permissions 7 | * Create `Merge Requests` from branches, CI runs tests/builds automatically 8 | * Review and inline code comments 9 | * Project maintainer merges requests and manages issues/milestones/releases 10 | 11 |
GitLab Workflow
12 | 13 | !SLIDE smbullets printonly 14 | # GitLab Workflow 15 | 16 | * Manage branch access with roles and permissions 17 | * Create `Merge Requests` from branches, CI runs tests/builds automatically 18 | * Review and inline code comments 19 | * Project maintainer merges requests and manages issues/milestones/releases 20 | 21 |
GitLab Workflow
22 | 23 | !SLIDE supplemental solutions 24 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 25 | **** 26 | 27 | ## Create Milestone and First Issue 28 | 29 | **** 30 | 31 | Follow the instructions and ask the trainer for help. 32 | 33 | !SLIDE smbullets 34 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Create Merge Request 35 | 36 | * Objective: 37 | * Create merge request from feature branch 38 | 39 | * Steps: 40 | * Create/checkout the branch `feature/docs-merge-request` 41 | * Edit `README.md`, add, commit and push the changes 42 | * Open the proposed GitLab URL in your browser 43 | * Fill in the merge request and add `fixes #1` as description 44 | * Merge the MR and tick `delete source branch` 45 | * Analyze the history in GitLab and open issue #1 46 | 47 | * Bonus: 48 | * Run `git fetch --prune` and `git branch -d feature/docs-merge-request` 49 | 50 | ~~~SECTION:handouts~~~ 51 | 52 | **** 53 | 54 | For future branch cleanups, you'll need to compare the deleted 55 | remote branch references from `git fetch --prune` with the local 56 | branch names, review them and then delete them. 57 | 58 | @@@Sh 59 | $ git branch -vv | grep 'origin/.*: gone]' | awk '{print $1}' 60 | $ git branch -vv | grep 'origin/.*: gone]' | awk '{print $1}' | xargs git branch -d 61 | 62 | ~~~ENDSECTION~~~ 63 | 64 | !SLIDE supplemental exercises 65 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Create Merge Request 66 | 67 | ## Objective: Create Merge Request 68 | **** 69 | 70 | * Create Merge Request 71 | 72 | ## Steps: 73 | 74 | **** 75 | 76 | * Create/checkout the branch `feature/docs-merge-request` 77 | * Edit `README.md`, add, commit and push the changes 78 | * Open the proposed GitLab URL in your browser 79 | * Fill in the merge request and add `fixes #1` as description 80 | * Merge the MR and tick `delect source branch` 81 | * Analyze the history in GitLab and open issue #1 82 | 83 | ## Bonus: 84 | 85 | **** 86 | 87 | * Run `git fetch --prune` and `git branch -d feature/docs-merge-request` 88 | 89 | !SLIDE supplemental solutions 90 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 91 | **** 92 | 93 | ## Create Merge Request 94 | 95 | **** 96 | 97 | ### Checkout the feature branch, add, commit and push changes 98 | 99 | @@@ Sh 100 | $ cd $HOME/training 101 | $ git checkout main 102 | $ git checkout -b feature/docs-merge-request 103 | $ vim README.md 104 | 105 | Let's create a merge request with GitLab. 106 | 107 | $ git add README.md 108 | $ git commit -v README.md -m "Update docs for merge requests" 109 | $ git push -u origin feature/docs-merge-request 110 | 111 | ### Navigate into GitLab and create merge request 112 | 113 | GitLab puts the URL into the shell output when pushing the branch. 114 | 115 | @@@ Sh 116 | $ git push -u origin feature/docs-merge-request 117 | Total 6 (delta 4), reused 0 (delta 0) 118 | remote: To create a merge request for feature/docs-merge-request, visit: 119 | remote: https://[...].nws.netways.de/root/training/merge_requests/new?merge_request%5Bsource_branch%5D=feature%2Fdocs-merge-request 120 | To https://[...].nws.netways.de/root/training.git 121 | * [new branch] feature/docs-merge-request -> feature/docs-merge-request 122 | Branch 'feature/docs-merge-request' set up to track remote branch 'feature/docs-merge-request' from 'origin'. 123 | 124 | 125 | Open the URL in your browser. 126 | 127 | Specify a topic and description. Add `fixes #1` into the MR's description. 128 | 129 | Create the merge request. Add a comment inline to the source code 130 | and see what happens in the interface. 131 | 132 | Merge the MR and tick `delete source branch`. 133 | 134 | Open the previously created issue and verify that is was closed 135 | by merging the MR. 136 | 137 | 138 | ### Update local index and delete the branch 139 | 140 | @@@ Sh 141 | $ git fetch --prune 142 | $ git branch -d feature/docs-merge-request 143 | 144 | ### Pull changes to local main after merge 145 | 146 | @@@ Sh 147 | $ git checkout main 148 | $ git pull 149 | 150 | !SLIDE smbullets 151 | # Forking Repositories 152 | 153 | A Fork is a server-side copy of a repository. 154 | 155 | If you have no write access to a repository you can fork it. Then: 156 | 157 | * Commit and push into the copy 158 | * Create a `Merge/Pull Request` in the original repo 159 | * Maintainers of the original repo can review and then merge your changes 160 | 161 | GitLab and GitHub support creating forks. 162 | 163 | ~~~SECTION:handouts~~~ 164 | 165 | **** 166 | 167 | References: 168 | 169 | * GitHub: https://guides.github.com/introduction/flow/ 170 | * GitLab: https://docs.gitlab.com/ce/workflow/forking_workflow.html 171 | 172 | ~~~ENDSECTION~~~ 173 | -------------------------------------------------------------------------------- /global/wizard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DIR=$(pwd) 3 | CLANG=${CLANG:-C.UTF-8} 4 | IMAGE=${IMAGE:-netways/showoff:0.20.4} 5 | CNAME=${CNAME:-showoff} 6 | TRAINING=${TRAINING:-$(basename "$DIR")} 7 | RUNTIME=${RUNTIME:-$(command -v docker)} 8 | GIT=${GIT:-$(command -v git)} 9 | SCRIPT_DIR=$(cd $(dirname $0); pwd -P) 10 | NO_RESET=${NO_RESET:-""} 11 | 12 | # Run given command in the showoff container 13 | execdocker () { 14 | if [[ -n $($RUNTIME ps -aq -f name=$CNAME 2> /dev/null) ]]; then 15 | $RUNTIME rm -f $CNAME 2> /dev/null 16 | fi 17 | 18 | case $RUNTIME in 19 | *podman*) USERNS=keep-id;; 20 | *) USERNS=host;; 21 | esac 22 | 23 | $RUNTIME run \ 24 | -it \ 25 | --name=$CNAME \ 26 | --rm \ 27 | -p 9090:9090 \ 28 | --user $(id -u) \ 29 | --userns=$USERNS \ 30 | -v "$DIR:/training:z" \ 31 | -e "LANG=$CLANG" \ 32 | -e "LANGUAGE=$CLANG" \ 33 | -e "LC_ALL=$CANG" \ 34 | $IMAGE \ 35 | $1 36 | } 37 | 38 | # Generate handouts as showoff HTML and convert HTML to PDF 39 | printhandouts () { 40 | echo -e "\n--- RUN SHOWOFF STATIC FOR HANDOUTS ---" 41 | execdocker "showoff static print" 42 | # Removes showoff's Section markers for PDF output 43 | sed -i 's/~~~.*~~~ //g' static/index.html 44 | echo -e "\n--- RUN WKHTMLTOPDF FOR HANDOUTS ---" 45 | execdocker "wkhtmltopdf --enable-local-file-access --load-error-handling ignore -s ${FORMAT} --print-media-type --footer-left [page] --footer-right ©NETWAYS static/index.html ${TRAINING}_${1}_${FORMAT}-handouts.pdf" 46 | } 47 | 48 | # Generate exercises as showoff HTML and convert HTML to PDF 49 | printexercises () { 50 | echo -e "\n--- RUN SHOWOFF STATIC FOR EXERCISES ---" 51 | execdocker "showoff static supplemental exercises" 52 | # Removes showoff's Section markers for PDF output 53 | sed -i 's/~~~.*~~~ //g' static/index.html 54 | echo -e "\n--- RUN WKHTMLTOPDF FOR EXERCISES ---" 55 | execdocker "wkhtmltopdf --enable-local-file-access --load-error-handling ignore -s ${FORMAT} --print-media-type --footer-left [page] --footer-right ©NETWAYS static/index.html ${TRAINING}_${1}_${FORMAT}-exercises.pdf" 56 | } 57 | 58 | # Generate solutions as showoff HTML and convert HTML to PDF 59 | printsolutions () { 60 | echo -e "\n--- RUN SHOWOFF STATIC FOR SOLUTIONS ---" 61 | execdocker "showoff static supplemental solutions" 62 | # Removes showoff's Section markers for PDF output 63 | sed -i 's/~~~.*~~~ //g' static/index.html 64 | echo -e "\n--- RUN WKHTMLTOPDF FOR SOLUTIONS ---" 65 | execdocker "wkhtmltopdf --enable-local-file-access --load-error-handling ignore -s ${FORMAT} --print-media-type --footer-left [page] --footer-right ©NETWAYS static/index.html ${TRAINING}_${1}_${FORMAT}-solutions.pdf" 66 | } 67 | 68 | setlayout () { 69 | find . -maxdepth 1 -type l -name *.css -delete 70 | ln -s global/layouts/$1.css . 71 | } 72 | 73 | # Create reference if it doesn't exist 74 | ln -sf . global 75 | 76 | if [[ ! -x $RUNTIME ]]; then 77 | echo "Command '${RUNTIME}' not found, exit" 78 | exit 1 79 | fi 80 | 81 | if [[ ! -x $GIT ]]; then 82 | echo "Command 'git' not found, exit" 83 | exit 1 84 | fi 85 | 86 | # Wizard 87 | 88 | clear 89 | 90 | echo "###########################" 91 | echo " NETWAYS Training Wizard " 92 | echo "###########################" 93 | 94 | echo -e "\n### LAYOUT ###" 95 | 96 | echo -e " 97 | [1] NETWAYS 98 | [2] OSMC 99 | [3] OSDC 100 | [4] OSBConf\n" 101 | 102 | LAYOUT_DEFAULT=1 103 | read -p "Which Layout? [1-4] (Default: "$LAYOUT_DEFAULT"): " LAYOUT 104 | LAYOUT="${LAYOUT:-$LAYOUT_DEFAULT}" 105 | 106 | while [[ $LAYOUT != [1-4] ]]; do 107 | echo "Invalid option, try again..." 108 | read -p "What to print? [1-4] (Default: "$LAYOUT_DEFAULT"): " LAYOUT 109 | LAYOUT="${LAYOUT:-$LAYOUT_DEFAULT}" 110 | done 111 | 112 | case "$LAYOUT" in 113 | 1) LAYOUT=netways 114 | sed -i 's|^[ \t\s]*"default":.*| "default": "global/layouts/netways.tpl"|' showoff.json;; 115 | 2) LAYOUT=osmc 116 | sed -i 's|^[ \t\s]*"default":.*| "default": "global/layouts/osmc.tpl"|' showoff.json;; 117 | 3) LAYOUT=osdc 118 | sed -i 's|^[ \t\s]*"default":.*| "default": "global/layouts/osdc.tpl"|' showoff.json;; 119 | 4) LAYOUT=osbconf 120 | sed -i 's|^[ \t\s]*"default":.*| "default": "global/layouts/osbconf.tpl"|' showoff.json;; 121 | esac 122 | 123 | setlayout $LAYOUT 124 | 125 | echo -e "\n### FORMAT ###" 126 | 127 | echo -e " 128 | [1] A5 129 | [2] A4\n" 130 | 131 | FORMAT_DEFAULT=1 132 | read -p "Which format? [1-2] (Default: "$FORMAT_DEFAULT"): " FORMAT 133 | FORMAT="${FORMAT:-$FORMAT_DEFAULT}" 134 | 135 | while [[ $FORMAT != [1-2] ]]; do 136 | echo "Invalid option, try again..." 137 | read -p "Which format? [1-2] (Default: "$FORMAT_DEFAULT"): " FORMAT 138 | FORMAT="${FORMAT:-$FORMAT_DEFAULT}" 139 | done 140 | 141 | case "$FORMAT" in 142 | 1) FORMAT=A5;; 143 | 2) FORMAT=A4;; 144 | esac 145 | 146 | echo -e "\n### MODE ###" 147 | 148 | echo -e " 149 | [1] serve 150 | [2] print\n" 151 | 152 | MODE_DEFAULT=1 153 | read -p "Which mode? [1-2] (Default: "$MODE_DEFAULT"): " MODE 154 | MODE="${MODE:-$MODE_DEFAULT}" 155 | 156 | if [[ $MODE == 1 ]]; then 157 | echo "--- RUN SHOWOFF SERVE ---" 158 | execdocker "showoff serve" 159 | elif [[ $MODE == 2 ]]; then 160 | echo -e "\n### PRINT ###" 161 | 162 | echo -e " 163 | [1] Handouts 164 | [2] Handouts & Solutions 165 | [3] Handouts & Exercises & Solutions 166 | [4] Exercises & Solutions\n" 167 | 168 | PRINT_DEFAULT=2 169 | read -p "What to print? [1-4] (Default: "$PRINT_DEFAULT"): " PRINT 170 | PRINT="${PRINT:-$PRINT_DEFAULT}" 171 | 172 | while [[ $PRINT != [1-4] ]]; do 173 | echo "Invalid option, try again..." 174 | read -p "What to print? [1-4] (Default: "$PRINT_DEFAULT"): " PRINT 175 | PRINT="${PRINT:-$PRINT_DEFAULT}" 176 | done 177 | 178 | VERSION_DEFAULT=`grep release showoff.json | cut -f2 -d: | tr -d '"' | tr -d " " | tr -d ","` 179 | read -p "Which version? (Default: "$VERSION_DEFAULT"): " VERSION 180 | VERSION="${VERSION:-$VERSION_DEFAULT}" 181 | 182 | case "$PRINT" in 183 | 1) printhandouts $VERSION;; 184 | 2) printhandouts $VERSION 185 | printsolutions $VERSION;; 186 | 3) printhandouts $VERSION 187 | printexercises $VERSION 188 | printsolutions $VERSION;; 189 | 4) printexercises $VERSION 190 | printsolutions $VERSION;; 191 | esac 192 | fi 193 | -------------------------------------------------------------------------------- /day1/05_Branching/01_Intro.md: -------------------------------------------------------------------------------- 1 | !SLIDE subsection 2 | # ~~~SECTION:MAJOR~~~ Git Branching 3 | 4 | !SLIDE 5 | # Working with Git branches 6 | 7 | Branches are useful to develop features/fixes in an isolated 8 | environment. 9 | 10 | * The default branch is usually called `main` 11 | * Note: Historically it was `master`, many vendors are now moving to `main` 12 | * We can create dedicated branches for development 13 | * We can switch branches to work on things in parallel 14 | * Once we are done developing we merge the dedicated branch into `main` 15 | 16 |
Feature Branch Workflow
17 | 18 | !SLIDE smbullets 19 | # Git Branch CLI commands 20 | 21 | * `git branch` 22 | * Creates a new branch 23 | * Deletes existing branches 24 | * Lists all available branches 25 | * `git checkout` 26 | * Switches between branches 27 | * `git merge` 28 | * Incorporates commits from a branch into the current one 29 | 30 | ~~~SECTION:handouts~~~ 31 | 32 | **** 33 | 34 | `git branch` allows you to list, create and delete branches. 35 | 36 | `git checkout` will switch between branches. 37 | 38 | `git merge` incorporate commits from one branch into the current one. 39 | 40 | ~~~ENDSECTION~~~ 41 | 42 | !SLIDE smbullets 43 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Show the current branch 44 | 45 | * Objective: 46 | * Show the current branch 47 | * Steps: 48 | * Change into `$HOME/training` 49 | * Use `git branch` to highlight the current branch 50 | 51 | !SLIDE supplemental exercises 52 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Show the current branch 53 | 54 | ## Objective: Show the current branch 55 | **** 56 | 57 | * Show the current branch 58 | 59 | ## Steps: 60 | 61 | **** 62 | 63 | * Change into `$HOME/training` 64 | * Use `git branch` to highlight the current branch 65 | 66 | 67 | !SLIDE supplemental solutions 68 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 69 | **** 70 | 71 | ## Show the current branch 72 | 73 | **** 74 | 75 | ### Example 76 | 77 | @@@ Sh 78 | $ cd $HOME/training 79 | 80 | $ git branch 81 | * main 82 | 83 | !SLIDE smbullets 84 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Create and checkout a new branch 85 | 86 | * Objective: 87 | * Create and checkout a new branch 88 | * Steps: 89 | * Change into `$HOME/training` 90 | * Create a new branch `feature/docs` based off `main` with `git branch feature/docs main` 91 | * List the branches with `git branch` 92 | * Checkout the new branch with `git checkout feature/docs` 93 | * Bonus: 94 | * Explain `git checkout -b feature/more-docs` 95 | 96 | !SLIDE supplemental exercises 97 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Create and checkout a new branch 98 | 99 | ## Objective: Create and checkout a new branch 100 | **** 101 | 102 | * Create and checkout a new branch 103 | 104 | ## Steps: 105 | 106 | **** 107 | 108 | * Change into `$HOME/training` 109 | * Create a new branch `feature/docs` based off `main` with `git branch feature/docs main` 110 | * List the branches with `git branch` 111 | * Checkout the new branch with `git checkout feature/docs` 112 | 113 | ## Bonus: 114 | 115 | * Verify how `git checkout -b feature/more-docs` works 116 | * Explain how it helps here 117 | 118 | **** 119 | 120 | !SLIDE supplemental solutions 121 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 122 | **** 123 | 124 | ## Create and checkout a new branch 125 | 126 | **** 127 | 128 | ### Create the branch 129 | 130 | @@@ Sh 131 | $ cd $HOME/training 132 | 133 | $ git branch feature/docs main 134 | 135 | ### List the branches 136 | 137 | @@@ Sh 138 | $ git branch 139 | * main 140 | feature/docs 141 | 142 | ### Checkout the created branch 143 | 144 | @@@ Sh 145 | $ git checkout feature/docs 146 | $ git branch 147 | main 148 | * feature/docs 149 | 150 | ### Use it all at once 151 | 152 | `git checkout -b` creates a new branch from the current branch 153 | and does the checkout afterwards. That way you'll safe some time 154 | when working with branches quite often. 155 | 156 | @@@ Sh 157 | $ git checkout main 158 | $ git checkout -b feature/more-docs 159 | 160 | !SLIDE smbullets 161 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Merge the branch 162 | 163 | * Objective: 164 | * Use `git merge` to merge the new branch 165 | * Steps: 166 | * Change into `$HOME/training` 167 | * Edit the README.md and commit the change 168 | * Switch to the main branch 169 | * Use `git merge feature/docs` to merge the branch 170 | 171 | !SLIDE supplemental solutions 172 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 173 | **** 174 | 175 | ## Merge the branch 176 | 177 | **** 178 | 179 | ### Checkout the main branch 180 | 181 | @@@ Sh 182 | $ cd $HOME/training 183 | 184 | $ git checkout feature/docs 185 | $ vim README.md 186 | $ git add README.md 187 | $ git commit -m "Update README" 188 | 189 | ### Merge the branch 190 | 191 | @@@ Sh 192 | $ git checkout main 193 | $ git merge feature/docs 194 | 195 | !SLIDE smbullets 196 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Delete the branch 197 | 198 | * Objective: 199 | * Delete the previously created branch 200 | * Steps: 201 | * Change into `$HOME/training` 202 | * Use `git branch -d` to delete the feature/docs branch 203 | * Bonus: 204 | * Try to delete the branch you are currently on 205 | 206 | !SLIDE supplemental exercises 207 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Delete the branch 208 | 209 | ## Objective: Delete the branch 210 | **** 211 | 212 | * Delete the previously created branch 213 | 214 | ## Steps: 215 | 216 | **** 217 | 218 | * Change into `$HOME/training` 219 | * Switch to the main branch 220 | * Use `git branch -d feature/docs` to delete the feature/docs branch 221 | 222 | ## Bonus: 223 | 224 | **** 225 | 226 | * Try to delete the branch you are currently on 227 | 228 | !SLIDE supplemental solutions 229 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 230 | **** 231 | 232 | ## Delete the branch 233 | 234 | **** 235 | 236 | ### Checkout the main branch 237 | 238 | @@@ Sh 239 | $ cd $HOME/training 240 | 241 | $ git checkout main 242 | 243 | ### Delete the previously created branch 244 | 245 | @@@ Sh 246 | $ git branch -d feature/docs 247 | 248 | ### Try to delete the current branch 249 | 250 | @@@ Sh 251 | $ git checkout main 252 | $ git branch -d main 253 | -------------------------------------------------------------------------------- /day2/01_Workflows/09_Rebase_Squash.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Rewriting History: Rebase and Squash 3 | 4 | Developers from open source projects sometimes ask you 5 | to `rebase` your history or even `squash` 6 | all commits into one commit. 7 | 8 | Squashing in Git means to combine multiple commits into one. 9 | 10 | commit1 => commit 11 | commit2 12 | commit3 13 | 14 | This is recommended when you have a lot of WIP commits, 15 | to clean up your history, so it only has meaningful commits. 16 | 17 | `git rebase` can also be used to perform various 18 | actions on the repository's history. 19 | 20 | !SLIDE smbullets 21 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Rebase and squash commits 22 | 23 | * Objective: 24 | * Rebase and squash commits 25 | * Steps: 26 | * Add 3 commits to the `main` branch and push them 27 | * Use `git rebase -i HEAD~3` to start the interactive mode. `HEAD~3` takes the last 3 commits compared to current HEAD 28 | * Use `pick` for the top commit 29 | * Replace `pick` with `squash` for the other commits 30 | * Save and edit the final commit message 31 | * Use `git log` to verify the history 32 | 33 | ~~~SECTION:handouts~~~ 34 | 35 | **** 36 | 37 | `git rebase` can also be used to `edit` the commits in your history. 38 | This is helpful if you want to amend changes to the test commit. Or if 39 | they are missing issue references, or just contain wrong information. 40 | 41 | This is a common scenario for code reviews before merging the actual 42 | history into the development branches. 43 | 44 | ~~~ENDSECTION~~~ 45 | 46 | !SLIDE supplemental exercises 47 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Rebase and squash commits 48 | 49 | ## Objective: Rebase and squash commits 50 | **** 51 | 52 | * Rebase and squash commits 53 | 54 | ## Steps: 55 | 56 | * Add 3 commits to the `main` branch and push them 57 | * Use `git rebase -i HEAD~3` to start the interactive mode. `HEAD~3` takes the last 3 commits compared to current HEAD 58 | * Use `pick` for the top commit` 59 | * Replace `pick` with `squash` for the other commits 60 | * Save and edit the final commit message 61 | * Use `git log` to verify the history 62 | 63 | ## Bonus: 64 | 65 | * Push the changed commit history using `git push -f` and explain what happens 66 | 67 | !SLIDE supplemental solutions 68 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 69 | **** 70 | 71 | ## Rebase and squash commits 72 | 73 | **** 74 | 75 | ### Add 3 commits to your history 76 | 77 | If you do not have any. 78 | 79 | @@@ Sh 80 | $ git checkout main 81 | 82 | @@@ Sh 83 | $ echo "# Rebase and Squash" >> README.md 84 | $ git commit -av -m "commit1" 85 | $ echo " " >> README.md 86 | $ git commit -av -m "commit2" 87 | $ echo "git rebase -i is interactive" >> README.md 88 | $ git commit -av -m "commit3" 89 | 90 | @@@ Sh 91 | $ git push 92 | 93 | ### Use git rebase to squash three commits 94 | 95 | Use the interactive mode by specifying the `-i` parameter. 96 | `HEAD~3` uses the commit range three commits to the current 97 | HEAD commit. 98 | 99 | @@@ Sh 100 | $ git rebase -i HEAD~3 101 | 102 | The interactive mode opens the editor you are familiar with 103 | from commit messages. 104 | 105 | ### Choose the commits to squash 106 | 107 | @@@ Sh 108 | pick 5a31d9e commit1 109 | squash ce90e16 commit2 110 | squash ed6a68f commit3 111 | 112 | !SLIDE smbullets 113 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Force Push and Protected Branches 114 | 115 | * Objective: 116 | * Try to force push and learn about protected branches in GitLab 117 | * Steps: 118 | * Run `git push -f` in the main branch 119 | * Explain the error 120 | * Navigate into `GitLab > Project > Settings > Repository` 121 | * Temporarily unprotected the `main` branch 122 | * Run `git push -f` again 123 | * Protect the `main` branch again and discuss with the trainer 124 | 125 | ~~~SECTION:handouts~~~ 126 | 127 | **** 128 | 129 | Read more about protected branches and why they are useful here: 130 | https://about.gitlab.com/2014/11/26/keeping-your-code-protected/ 131 | 132 | Possible use cases for protecting branches: 133 | 134 | * Releases are tagged from the `main` branch, no-one should be allowed 135 | to modify this history at any point in time 136 | * In case you are supporting older versions, you'll probably have `release/x.y` 137 | or `support/x.y` branches. No-one is allowed to override anything in there 138 | 139 | In case a commit gets lost, either being deleted or the history is rewritten, 140 | the corresponding release tag points to nothing. Meaning to say, that release 141 | is broken. 142 | 143 | Therefore it is advised to protect sensitive branches in the project's repository. 144 | 145 | **Hint**: Project maintainers can edit the settings. If you have the requirement 146 | to make this a permanent setting as administrator, you can e.g. use the REST API 147 | to always force this setting with a small script and cronjob. 148 | 149 | ~~~ENDSECTION~~~ 150 | 151 | !SLIDE supplemental exercises 152 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Force Push and Protected Branches 153 | 154 | ## Objective: Force Push and Protected Branches 155 | **** 156 | 157 | * Try to force push and learn about protected branches in GitLab 158 | 159 | ## Steps: 160 | 161 | * Run `git push -f` in the main branch 162 | * Explain the error 163 | * Navigate into `GitLab > Project > Settings > Repository` 164 | * Temporarily unprotected the `main` branch 165 | * Run `git push -f` again 166 | * Protect the `main` branch again and discuss with the trainer 167 | 168 | !SLIDE supplemental solutions 169 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 170 | **** 171 | 172 | ## Force Push and Protected Branches 173 | 174 | ### Force Push 175 | 176 | @@@ Sh 177 | $ git checkout main 178 | $ git push -f 179 | 180 | ### Unprotect the main 181 | 182 | Navigate into `GitLab > Project > Settings > Repository` 183 | and choose `Protected Branches > Expand`. 184 | 185 | Select the `main` branch and click `Unprotect`. 186 | 187 | ### Force Push Again 188 | 189 | @@@ Sh 190 | $ git push -f 191 | 192 | ### Protect the main branch again 193 | **** 194 | 195 | Navigate into `GitLab > Project > Settings > Repository` 196 | and choose `Protected Branches > Expand`. 197 | 198 | Add `main` as protected branch, and set all options to 199 | `maintainers` again. 200 | 201 | !SLIDE 202 | # Don't Force Push a shared branch 203 | 204 | * You pulled the 3 commits now being squashed in main 205 | * Your colleague force pushed the branch with 1 squashed commit 206 | * You cannot rebase anymore 207 | * Instead, you need to reset your local branch to the remote branch base 208 | 209 | Discuss this with the trainer. 210 | 211 | $ git fetch 212 | $ git checkout feature/new-backend 213 | $ git reset --hard origin/feature/new-backend 214 | 215 | Alernatives: `git revert` which allows to document an undo. 216 | -------------------------------------------------------------------------------- /day1/07_Collaboration/04_Advanced.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Advanced Git Commands: Stash 3 | 4 | * `git stash` 5 | * Moves the current working directory to a temporary stack 6 | * The stash is only local, not stored in the central repository 7 | * Useful when changing branches or pulling 8 | * Use with care, apply and drop changes immediately after changing back 9 | 10 | Example: 11 | 12 | @@@ Sh 13 | $ git stash 14 | Saved working directory and index state WIP on main: 4b4f6c2 15 | 16 | $ git stash apply 17 | On branch main 18 | Your branch is up to date with 'origin/main'. 19 | 20 | Changes to be committed: 21 | (use "git restore --staged ..." to unstage) 22 | new file: 23 | 24 | $ git stash drop 25 | Dropped refs/stash@{0} (43d879b99aca12b6175c5362339b177af22589a9) 26 | 27 | ~~~SECTION:handouts~~~ 28 | 29 | **** 30 | 31 | `git stash` allows you put your current changes on a temporary stack (`stash`). 32 | This comes in handy when you want to change branches with a different history 33 | where your uncommitted changes will not apply. 34 | Use `git stash apply` to copy them from the stash to your working directory again. 35 | Use `git stash drop` to remove your stashed changes. 36 | 37 | You can stash multiple uncommitted 38 | stages, `git stash list` will list them. 39 | 40 | ~~~ENDSECTION~~~ 41 | 42 | !SLIDE smbullets 43 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Learn more about git stash 44 | 45 | * Objective: 46 | * Learn more about git stash 47 | * Steps: 48 | * Change into `$HOME/training` 49 | * Edit `README.md` 50 | * Examine the status with git status 51 | * Stash your current changes to the working directory 52 | * Run git status again 53 | * Examine the stash with `git stash list` and `git stash show -p` 54 | * Fetch the previously stashed changes with `git stash apply` 55 | * Drop the stashed changes with `git stash drop` 56 | 57 | !SLIDE supplemental exercises 58 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Learn more about git stash 59 | 60 | ## Objective: Learn more about git stash 61 | **** 62 | 63 | * Learn more about git stash 64 | 65 | ## Steps: 66 | 67 | * Change into `$HOME/training` 68 | * Edit `README.md` 69 | * Examine the status with git status 70 | * Stash your current changes to the working directory 71 | * Run git status again 72 | * Examine the stash with `git stash list` and `git stash show -p` 73 | * Fetch the previously stashed changes with `git stash apply` 74 | * Drop the stashed changes with `git stash drop` 75 | 76 | !SLIDE supplemental solutions 77 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 78 | **** 79 | 80 | 81 | ## Learn more about git stash 82 | 83 | **** 84 | 85 | ### Edit README and add docs 86 | 87 | @@@ Sh 88 | $ cd $HOME/training 89 | $ vim README.md 90 | 91 | Now I am learning how to use git stash and temporarily drop the changes 92 | e.g. to change into another branch. 93 | 94 | ### Examine the state with git status 95 | 96 | @@@ Sh 97 | $ git status 98 | 99 | ### Stash changes 100 | 101 | @@@ Sh 102 | $ git stash 103 | Saved working directory and index state WIP on main: 31dcde5 Add docs for git push 104 | HEAD is now at 31dcde5 Add docs for git push 105 | 106 | ### Examine the state with git status 107 | 108 | @@@ Sh 109 | $ git status 110 | On branch main 111 | nothing to commit, working tree clean 112 | 113 | ### Examine the stash list 114 | 115 | @@@ Sh 116 | $ git stash list 117 | stash@{0}: WIP on main: 31dcde5 Add docs for git push 118 | 119 | @@@ Sh 120 | $ git stash show -p 121 | 122 | diff --git a/README.md b/README.md 123 | index 2081a37..550db95 100644 124 | --- a/README.md 125 | +++ b/README.md 126 | @@ -15,3 +15,7 @@ Now for real. 127 | ``` 128 | git commit --amend 129 | ``` 130 | + 131 | +## Git Stash 132 | + 133 | +`git stash` 134 | 135 | ### Fetch previously stashed changes 136 | 137 | @@@ Sh 138 | $ git stash apply 139 | 140 | On branch main 141 | Your branch is up to date with 'origin/main'. 142 | 143 | Changes to be committed: 144 | (use "git restore --staged ..." to unstage) 145 | new file: README.md 146 | 147 | ### Drop the stashed changes 148 | 149 | @@@ Sh 150 | $ git stash drop 151 | 152 | Dropped refs/stash@{0} (a9f28340e6d536a9179307bd26169368e450161f) 153 | 154 | 155 | !SLIDE smbullets 156 | # Advanced Git Commands: Cherry-Pick 157 | 158 | * `git cherry-pick` 159 | * Integrates a specific commit into your working tree 160 | * Hint: When the base commit differs, the checksum changes, thus new commit ID 161 | * `-x` can be used to keep a reference to the original commit 162 | 163 | Example use-case: backporting patches to older software version. 164 | 165 | Example: 166 | 167 | $ git cherry-pick -x ef5d1c2 168 | 169 | 170 | !SLIDE smbullets 171 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Learn more about git cherry-pick 172 | 173 | * Objective: 174 | * Learn more about git cherry-pick 175 | * Steps: 176 | * Create and checkout the `feature/docs-hotfix` branch 177 | * Edit `README.md` and commit the change 178 | * Use `git log -1` to examine the Git commit 179 | * Checkout the main branch 180 | * Use `git cherry-pick -x ` 181 | * Verify the commit with `git show` 182 | 183 | !SLIDE supplemental exercises 184 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Learn more about git cherry-pick 185 | 186 | ## Objective: Learn more about git cherry-pick 187 | **** 188 | 189 | * Learn more about git cherry-pick 190 | 191 | ## Steps: 192 | 193 | * Create and checkout the `feature/docs-hotfix` branch 194 | * Edit `README.md` and commit the change 195 | * Use `git log -1` to examine the Git commit 196 | * Checkout the main branch 197 | * Use `git cherry-pick -x ` 198 | * Verify the commit with `git show` 199 | 200 | !SLIDE supplemental solutions 201 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 202 | **** 203 | 204 | ## Learn more about git cherry-pick 205 | 206 | **** 207 | 208 | ### Create and checkout the feature/docs-hotfix branch 209 | 210 | @@@ Sh 211 | $ git checkout -b feature/docs-hotfix 212 | 213 | ### Edit README and commit the change 214 | 215 | @@@ Sh 216 | $ cd $HOME/training 217 | $ vim README.md 218 | 219 | Now I am learning how to use git cherry-pick. This change will be cherry-picked 220 | into the main branch simulating a hot-fix. 221 | 222 | $ git commit -av -m "Update docs for cherry-pick" 223 | 224 | ### Fetch Commit ID 225 | 226 | @@@ Sh 227 | $ git show -1 228 | commit 550ccc6c65832d43969f44a03692772a30fa39fb (HEAD -> feature/docs-hotfix) 229 | 230 | ### Checkout the main branch 231 | 232 | @@@ Sh 233 | $ git checkout main 234 | 235 | #### Cherry-pick the commit 236 | 237 | @@@ Sh 238 | $ git cherry-pick 550ccc6c65832d43969f44a03692772a30fa39fb 239 | 240 | [main 0460d16] Update docs for cherry-pick 241 | Date: Thu Jan 24 14:52:19 2019 +0100 242 | 1 file changed, 3 insertions(+) 243 | 244 | ### Verify the commit 245 | 246 | @@@ Sh 247 | $ git show 248 | commit 2f3a0096017051d9ab86774282203dc6c9827ee4 (HEAD -> main) 249 | Author: Guy Incognito 250 | Date: Thu Jan 24 14:52:19 2019 +0100 251 | 252 | Update docs for cherry-pick 253 | 254 | (cherry picked from commit 550ccc6c65832d43969f44a03692772a30fa39fb) 255 | -------------------------------------------------------------------------------- /day2/01_Workflows/02_Centralized.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Centralized Workflow 3 | 4 | The simplest possible workflow: 5 | 6 | * Developers clone the central repository 7 | * They work with local copies 8 | * Pulling from the remote repository is optional 9 | 10 | ~~~SECTION:handouts~~~ 11 | 12 | **** 13 | 14 | Compared to other VCS systems, Git provides the advantage of 15 | also storing a local copy of the repository and branches. 16 | 17 | That way a developer can work isolated on changes on its own 18 | while other developers can do the same. These isolated environments 19 | ensure that each developers works independantly from other 20 | changes in the project. 21 | 22 | In addition to that the Git branching model provides a fail-safe mechanism 23 | for integrating and sharing code changes between repositories. 24 | 25 | ~~~ENDSECTION~~~ 26 | 27 | !SLIDE smbullets noprint 28 | # Centralized Workflow - Publish Changes 29 | 30 | * Developers push their local main branch 31 | * Stored in central repository 32 | * Adds all local commits that are not in the central main branch 33 | 34 | Local Repository 35 |
36 | 37 | Remote Repository 38 |
39 | 40 | !SLIDE smbullets printonly 41 | # Centralized Workflow - Publish Changes 42 | 43 | * Developers push their local main branch 44 | * Stored in central repository 45 | * Adds all local commits that are not in the central main branch 46 | 47 | Local Repository 48 |
49 | 50 | Remote Repository 51 |
52 | 53 | !SLIDE smbullets noprint 54 | # Centralized Workflow - Managing Conflicts 55 | 56 | * Central repository's commit history is important 57 | * If local commit history diverges, pushing changes is denied 58 | 59 |
Diverged Remote
60 | 61 | !SLIDE smbullets printonly 62 | # Centralized Workflow - Managing Conflicts 63 | 64 | * Central repository's commit history is important 65 | * If local commit history diverges, pushing changes is denied 66 | 67 |
Diverged Remote
68 | 69 | !SLIDE smbullets 70 | # Centralized Workflow - Merge Conflicts 71 | 72 | * When merging Git will try to automatically integrate new changes 73 | * Conflicts arise when the same lines in a file have changed 74 | * Git cannot automatically determine what is correct 75 | * `>>>` marks conflicts and show the differences 76 | * `===` is the barrier between the two states 77 | 78 | Important: those markers need to be deleted from the files 79 | 80 | Example: 81 | 82 | @@@Sh 83 | <<<<<<< HEAD 84 | What is on HEAD 85 | ======= 86 | What is on other branch 87 | >>>>>>> other-branch 88 | 89 | !SLIDE smbullets 90 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Collaborate in a central repository 91 | 92 | * Objective: 93 | * Create conflicting history tree 94 | * Steps: 95 | * Open the GitLab project `training` 96 | * Open `README.md` using the Gitlab Web IDE 97 | * Edit `README.md`, add `This change is on the remote.` 98 | * Stage & commit the change to main 99 | * Local steps: 100 | * Change into `training` directory on your local machine 101 | * Edit `README.md`, add `This is my local change.` 102 | * Commit and try to push, explain the error message 103 | 104 | !SLIDE supplemental exercises 105 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Collaborate in a central repository 106 | 107 | ## Objective: Create conflicting history tree 108 | **** 109 | 110 | * Create conflicting history tree 111 | 112 | ## Steps: 113 | 114 | **** 115 | 116 | * Open the GitLab project `training` 117 | * Open `README.md` using the Gitlab Web IDE 118 | * Stage & commit the change to main 119 | 120 | ## Local CLI Steps: 121 | 122 | **** 123 | 124 | * Change into `training` directory on your local machine 125 | * Edit `README.md`, add `This is my local change.` 126 | * Commit and try to push, explain the error message 127 | 128 | 129 | !SLIDE supplemental solutions 130 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 131 | **** 132 | 133 | ## Create conflicting history tree 134 | 135 | **** 136 | 137 | ### Create remote commit in GitLab 138 | 139 | Navigate into the `training` project in GitLab and select 140 | the `Repository` view. 141 | 142 | Click onto `README.md` and choose to edit it from the browser. 143 | 144 | Add `This change is from my colleague.` at the bottom of the file. 145 | 146 | Stage and commit the change to the main branch. 147 | 148 | ### Create local commit on the CLI 149 | 150 | Change into the `training` directory, edit the `README.md` file 151 | and commit the changes. 152 | 153 | @@@ Sh 154 | $ cd $HOME/training 155 | $ vim README.md 156 | 157 | ... 158 | 159 | This is my local change. 160 | 161 | $ git commit -av -m "Update docs for conflicts" 162 | 163 | ### Try to push the commit 164 | 165 | @@@ Sh 166 | $ git push 167 | 168 | This will fail as the history is now diverged and pushing 169 | in a non-fast forward fashion is not allowed. 170 | 171 | 172 | !SLIDE smbullets noprint 173 | # Centralized Workflow - Managing Conflicts: Rebase History 174 | 175 | * Fetch the remote history 176 | * Rebase local changes on top of it for a linear history 177 | 178 |
Before Rebase
179 | 180 |
After Rebase
181 | 182 | !SLIDE smbullets printonly 183 | # Centralized Workflow - Managing Conflicts: Rebase History 184 | 185 | * Fetch the remote history 186 | * Rebase local changes on top of it for a linear history 187 | 188 |
Before Rebase
189 | 190 |
After Rebase
191 | 192 | ~~~SECTION:handouts~~~ 193 | 194 | **** 195 | 196 | 197 | ~~~ENDSECTION~~~ 198 | 199 | !SLIDE smbullets 200 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Resolve conflicts in a central repository 201 | 202 | * Objective: 203 | * Rebase your local history with the remote repository 204 | * Steps: 205 | * Fetch remote with `git fetch` 206 | * Compare changes with `git diff origin/main` 207 | * Rebase with `git rebase origin/main` 208 | * Resolve possible merge conflicts, add them 209 | * Continue with `git rebase --continue`, push rebased history 210 | 211 | ~~~SECTION:handouts~~~ 212 | 213 | **** 214 | Instead of `git fetch` and `git rebase` you can also use 215 | the `git pull` command with the additional `--rebase` flag. 216 | 217 | If you forget the `--rebase` flag it will still work 218 | but generate merge commits. This will merge your commits 219 | in historical order but not rebase them on top of the existing 220 | history. 221 | 222 | When using a centralized workflow it is generally better to use `rebase`. 223 | 224 | ~~~ENDSECTION~~~ 225 | 226 | !SLIDE supplemental exercises 227 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Resolve conflicts in a central repository 228 | 229 | ## Objective: Rebase your local history with the remote repository 230 | **** 231 | 232 | * Rebase your local history with the remote repository 233 | 234 | ## Steps: 235 | 236 | **** 237 | 238 | * Fetch remote with `git fetch` 239 | * Compare changes with `git diff origin/main` 240 | * Rebase with `git rebase origin/main` 241 | * Resolve possible merge conflicts, add them 242 | * Continue with `git rebase --continue`, push rebased history 243 | 244 | !SLIDE supplemental solutions 245 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 246 | **** 247 | 248 | ## Rebase your local history with the remote repository 249 | 250 | **** 251 | 252 | ### Fetch and diff the remote changes 253 | 254 | @@@ Sh 255 | $ git fetch 256 | 257 | $ git diff origin/main 258 | 259 | ### Rebase your local history 260 | 261 | Rebase your local history against the remote origin main branch. 262 | 263 | @@@ Sh 264 | $ git rebase origin/main 265 | 266 | ### Resolve merge probblems 267 | 268 | @@@ Sh 269 | $ git status 270 | $ vim README.md 271 | 272 | Search for conflicts in vim: 273 | 274 | />>> 275 | 276 | Resolve the conflicts, add the file and continue the rebase. 277 | 278 | @@@ Sh 279 | $ git add README.md 280 | $ git rebase --continue 281 | 282 | 283 | ### Push the changes to the remote repository 284 | 285 | $ git push origin main 286 | -------------------------------------------------------------------------------- /day2/03_CI/04_Gitlab_Pipelines.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # GitLab Pipelines 3 | 4 | Pipelines are the top-level component of continuous integration. 5 | 6 | * Jobs, which define what to do. 7 | * Stages, which define when to run the jobs. 8 | * If all jobs in a stage succeed, the pipeline moves forward 9 | * If any job in a stage fails, the pipeline ends early 10 | 11 | Example: 12 | 13 | Clone Code => Test => Build => Deploy 14 | 15 | ~~~SECTION:handouts~~~ 16 | 17 | **** 18 | 19 | Reference: 20 | 21 | https://docs.gitlab.com/ee/ci/pipelines/ 22 | 23 | ~~~ENDSECTION~~~ 24 | 25 | !SLIDE smbullets noprint 26 | # GitLab Pipelines: Basic Pipelines 27 | 28 |
GitLab Pipelines
29 | 30 | * Runs all steps in stage concurrently before starting next stage 31 | * Not the most efficient 32 | * Easy to maintain 33 | 34 | !SLIDE smbullets printonly 35 | # GitLab Pipelines: Example 36 | 37 |
GitLab Pipelines
38 | 39 | !SLIDE smbullets 40 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Build a Pipeline 41 | 42 | * Objective: 43 | * Build a job pipeline with stages 44 | * Steps: 45 | * Edit the `.gitlab-ci.yml` and add `stages` 46 | * Place your jobs in stages using `stage:` 47 | 48 | Incomplete example: 49 | 50 | @@@Yaml 51 | stages: 52 | - test 53 | - build 54 | 55 | lint_markdown: 56 | stage: test 57 | 58 | convert_markdown: 59 | stage: build 60 | 61 | ~~~SECTION:handouts~~~ 62 | 63 | **** 64 | 65 | Documentation: https://docs.gitlab.com/ce/ci/yaml/README.html#stage 66 | 67 | ~~~ENDSECTION~~~ 68 | 69 | !SLIDE supplemental exercises 70 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: CI: Pipelines 71 | 72 | ## Create HTML docs from Markdown 73 | **** 74 | 75 | * Build a job pipeline with stages 76 | 77 | ## Steps: 78 | 79 | * Edit .gitlab-ci.yml and add stages 80 | * Add jobs to stages 81 | * Commit the changes 82 | * Check the GitLab Job Pipelines 83 | 84 | Hint: You can add `[ci skip]` or `[skip ci]` to your commit message. 85 | 86 | !SLIDE supplemental solutions 87 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 88 | **** 89 | 90 | ## Build a job pipeline with stages 91 | 92 | **** 93 | 94 | ### Edit .gitlab-ci.yml and add stages 95 | 96 | @@@ Sh 97 | $ vim .gitlab-ci.yml 98 | 99 | stages: 100 | - test 101 | - build 102 | 103 | ### Add jobs to stages 104 | 105 | @@@Yaml 106 | ... 107 | 108 | lint_markdown: 109 | stage: test 110 | 111 | ... 112 | 113 | convert_markdown: 114 | stage: build 115 | 116 | ### Complete example 117 | 118 | @@@Yaml 119 | image: alpine:latest 120 | 121 | before_script: 122 | - apk update && apk add python py-pip 123 | - pip install --break-system-packages markdown Pygments pymarkdownlnt 124 | 125 | stages: 126 | - test 127 | - build 128 | 129 | lint_markdown: 130 | stage: test 131 | script: 132 | - pymarkdown scan README.md 133 | allow_failure: true 134 | 135 | convert_markdown: 136 | stage: build 137 | script: 138 | - python -m markdown README.md > README.html 139 | artifacts: 140 | paths: 141 | - README.html 142 | expire_in: 1 week 143 | 144 | ### Commit and push the changes 145 | 146 | @@@ Sh 147 | $ git commit -av -m "CI: Add pipelines" 148 | $ git push 149 | 150 | ### Check the GitLab Job Pipelines 151 | 152 | This is an example of how to do it from a CLI, the Gitlab WebIDE is an obvious alternative. 153 | 154 | 155 | !SLIDE smbullets 156 | # GitLab Pipelines: Directed Acyclic Graph Pipelines 157 | 158 | Instead of stages we can use the `needs` keyword to define dependencies between jobs 159 | 160 | * Builds relationships between jobs 161 | * Ignore stage ordering and run some jobs without waiting for others 162 | 163 | Example: 164 | 165 | @@@Yaml 166 | build_a: 167 | stage: build 168 | script: 169 | - echo "This job builds something quickly." 170 | 171 | test_a: 172 | stage: test 173 | needs: [build_a] 174 | script: 175 | - echo "This test job will start as soon as build_a finishes." 176 | 177 | !SLIDE smbullets 178 | # GitLab Pipelines: Schedules 179 | 180 | Pipeline schedules can be used to also run pipelines at specific intervals. 181 | 182 | * Pipelines are normally run based on certain conditions being met 183 | * Navigate to `CI / CD > Schedules` to create a new pipeline 184 | * Pipelines can be scheduled using Cron syntax 185 | 186 | Try it out with the trainer. 187 | 188 | !SLIDE 189 | # GitLab Pipelines: Triggers and Rules 190 | 191 | We can use the `trigger` keyword to start other pipelines: 192 | 193 | * Multi-project pipeline or Child pipeline 194 | 195 | We can use the `rules` keyword to include or exclude jobs. 196 | 197 | Example: 198 | 199 | @@@Yaml 200 | stages: 201 | - test 202 | run_a_jobs: 203 | stage: test 204 | trigger: 205 | include: a/.gitlab-ci.yml 206 | rules: 207 | - changes: 208 | - a/* 209 | 210 | ~~~SECTION:handouts~~~ 211 | 212 | **** 213 | 214 | Rules are evaluated in order until the first match when the pipeline is created. Depending on the configuration, a job is either included or excluded. 215 | 216 | The `rules` keyword accepts an array of rules defined with: if, changes , exists, allow_failure, variables, when. 217 | 218 | ~~~ENDSECTION~~~ 219 | 220 | !SLIDE smbullets small 221 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: CI: Pipeline Rules 222 | 223 | * Objective: 224 | * Add a job to publish our HTML 225 | * Steps: 226 | * Add a new job `publish` 227 | * Use `rules` to start this job only when we add tags 228 | * Use `release` to add a release for the `publish` job 229 | 230 | Incomplete example: 231 | 232 | @@@Yaml 233 | publish: 234 | stage: deploy 235 | rules: 236 | - if: $CI_COMMIT_TAG 237 | release: 238 | tag_name: '$CI_COMMIT_TAG' 239 | description: '$CI_COMMIT_TAG_MESSAGE' 240 | 241 | Hint: Requires the release-cli tool. 242 | 243 | ~~~SECTION:handouts~~~ 244 | 245 | **** 246 | 247 | Releases can have custom assets, for example compiled executables. These are added via URLs and can thus 248 | be also hosted outside of GitLab. 249 | 250 | A GitLab Release automatically adds the project's source code as a default asset. 251 | 252 | ~~~ENDSECTION~~~ 253 | 254 | 255 | !SLIDE supplemental exercises 256 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: CI: Pipeline Rules 257 | 258 | ## Add a job to publish our HTML 259 | **** 260 | 261 | * Add a job to publish our HTML 262 | 263 | ## Steps: 264 | 265 | * Add a new job `publish` 266 | * Use `rules` to start this job only when we add tags 267 | * Use `needs` to add a dependency on the `build` job 268 | 269 | !SLIDE supplemental solutions 270 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 271 | **** 272 | 273 | ## Add a job to publish our HTML 274 | 275 | **** 276 | 277 | ### Add a job to publish our HTML 278 | 279 | @@@Yaml 280 | publish: 281 | stage: publish 282 | before_script: 283 | - wget -O /usr/local/bin/release-cli 284 | https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-linux-amd64 285 | - chmod +x /usr/local/bin/release-cli 286 | script: 287 | - echo "Creating a new Release" 288 | rules: 289 | - if: $CI_COMMIT_TAG 290 | release: 291 | tag_name: '$CI_COMMIT_TAG' 292 | ref: '$CI_COMMIT_SHA' 293 | description: '$CI_COMMIT_TAG_MESSAGE' 294 | 295 | --- 296 | 297 | !SLIDE smbullets 298 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: CI: Trigger Pipeline Rules 299 | 300 | * Objective: 301 | * Trigger the new job by creating a Git tag 302 | * Steps: 303 | * Use the Web UI to create a new tag `v1.0` with the message: 304 | * `The End of the Training Release. Hooray!` 305 | * Verify the `publish` job 306 | * View the Release in the Web UI 307 | 308 | !SLIDE supplemental exercises 309 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: CI: Trigger Pipeline Rules 310 | 311 | ## Trigger the new job by creating a Git tag 312 | **** 313 | 314 | * Trigger the new job by creating a Git tag 315 | 316 | ## Steps: 317 | 318 | * Use the Web UI to create a new tag `v1.0` with the message: 319 | * `The End of the Training Release. Hooray!` 320 | * Verify the `publish` job 321 | 322 | !SLIDE supplemental solutions 323 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 324 | **** 325 | 326 | ## Trigger the new job by creating a Git tag 327 | 328 | **** 329 | 330 | ### Trigger the new job by creating a Git tag 331 | 332 | * Open GitLab and navigate into `Repository > Tags` 333 | * Click on `New Tag` and create a new `v1.0` tag with the message: 334 | * `The End of the Training Release. Hooray!` 335 | -------------------------------------------------------------------------------- /day1/07_Collaboration/02_Collaboration.md: -------------------------------------------------------------------------------- 1 | !SLIDE smbullets 2 | # Collaboration: Push History 3 | 4 | * `git push` 5 | * Pushes the local history to the remote repository 6 | * Halts if the remote history diverged from your local history 7 | * `git remote` 8 | * Adds remote repository URLs (default `origin`) 9 | * Lists and removes remote repository URLs 10 | * `git branch -r` 11 | * Lists remote branches, prefixed with the remote name, e.g. `origin/main` 12 | 13 | ~~~SECTION:handouts~~~ 14 | 15 | **** 16 | 17 | `git push` updates remote references and pushes your local commit history to the remote repository. 18 | 19 | `git remote` allows you to configure and list the remote repository. By default this is called `origin`. 20 | 21 | ~~~ENDSECTION~~~ 22 | 23 | !SLIDE smbullets 24 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Learn more about git push 25 | 26 | * Objective: 27 | * Learn more about git push 28 | * Steps: 29 | * Change into `$HOME/training` 30 | * Edit `README.md` and notes about `git push` 31 | * Add and commit the changes 32 | * Push the changes 33 | * Bonus: 34 | * List all remote branches with `git branch -r` 35 | 36 | !SLIDE supplemental exercises 37 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Learn more about git push 38 | 39 | ## Objective: Learn more about git push 40 | **** 41 | 42 | * Learn more about git push 43 | 44 | ## Steps: 45 | 46 | * Change into `$HOME/training` 47 | * Edit `README.md` and add notes about `git push` 48 | * Add and commit the changes 49 | * Push the changes 50 | 51 | ## Bonus: 52 | 53 | * List all remote branches with `git branch -r` 54 | 55 | !SLIDE supplemental solutions 56 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 57 | **** 58 | 59 | ## Learn more about git push 60 | 61 | **** 62 | 63 | ### Make changes 64 | 65 | @@@ Sh 66 | $ cd $HOME/training 67 | $ git checkout main 68 | 69 | $ vim README.md 70 | 71 | Now I know how to publish my changes to my NWS hosted GitLab server. 72 | 73 | $ git add README.md 74 | $ git commit -v README.md -m "Add docs for git push" 75 | 76 | ### Push changes 77 | 78 | @@@ Sh 79 | $ git push origin main 80 | 81 | ### List remote branches 82 | 83 | @@@ Sh 84 | $ git branch -r 85 | 86 | !SLIDE 87 | # Collaboration: Branch Tracking 88 | 89 | A *tracking branch* is a local branch that is connected to a remote branch. 90 | 91 | * We can now push without the need to be specific(`git push origin main`) 92 | * Git can now inform you about "unpushed" and "unpulled" commits (`git status`) 93 | * `git branch -a` lists all branches 94 | * `git branch -vv` lists tracking branches 95 | 96 | Example: 97 | 98 | @@@ Sh 99 | git branch -vv 100 | *master f2cce0c [origin/master] Rename test directory 101 | wip-foobar d92a5ad Why wont it work?! 102 | 103 | Hint: There are various `push` methods that can be configured. 104 | 105 | ~~~SECTION:handouts~~~ 106 | 107 | **** 108 | 109 | There are various `push` methods: 110 | 111 | * `simple` - pushes the current branch with the same name on the remote 112 | * `current` - push the current branch to update a branch with the same name on the receiving end 113 | * `nothing` - do not push anything (error out) unless a refspec is given 114 | 115 | References: 116 | 117 | https://git-scm.com/docs/git-config/#Documentation/git-config.txt-pushdefault 118 | 119 | ~~~ENDSECTION~~~ 120 | 121 | !SLIDE smbullets 122 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Configure a tracking branch 123 | 124 | * Objective: 125 | * Set the origin/main as tracking branch for main 126 | * Steps: 127 | * Change into `$HOME/training` 128 | * Push with `git push` explain the error 129 | * Push with `git push --set-upstream origin main` 130 | * Push again with `git push` 131 | * Bonus: 132 | * Verify the tracking branches with `git branch -vv` 133 | 134 | !SLIDE supplemental exercises 135 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Configure a tracking branch 136 | 137 | ## Objective: Set the origin/main as tracking branch for main 138 | **** 139 | 140 | * Set the origin/main as tracking branch for main 141 | 142 | ## Steps: 143 | 144 | * Change into `$HOME/training` 145 | * Push with `git push` explain the error 146 | * Push with `git push --set-upstream origin main` 147 | * Push again with `git push` 148 | 149 | ## Bonus: 150 | 151 | * Verify the tracking branches with `git branch -vv` 152 | 153 | !SLIDE supplemental solutions 154 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 155 | **** 156 | 157 | ## Set the origin/main as tracking branch for main 158 | 159 | **** 160 | 161 | ### Make changes 162 | 163 | @@@ Sh 164 | $ cd $HOME/training 165 | $ git checkout main 166 | 167 | $ git push 168 | $ # fatal: The current branch foobar has no upstream branch. 169 | $ git push --set-upstream origin main 170 | $ git push 171 | 172 | ### List tracking branches 173 | 174 | @@@ Sh 175 | $ git branch -vv 176 | 177 | 178 | !SLIDE smbullets 179 | # Deleting Remote Branches 180 | 181 | You have learned that you can create remote (feature) branches. But what if 182 | you want to delete such branches? 183 | 184 | `git push origin ` is short for `git push origin :`. 185 | 186 | Pushing `NULL` into a remote branch will delete it. 187 | 188 | `git push origin :` 189 | 190 | Hint: You can delete branches in GitLab/GitHub too. 191 | 192 | !SLIDE smbullets 193 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Delete remote branch 194 | 195 | * Objective: 196 | * Delete remote branch 197 | * Steps: 198 | * Change into `$HOME/training` 199 | * Create or identify a remote branch `feature/docs-wrong-name` 200 | * Delete the remote branch 201 | 202 | !SLIDE supplemental exercises 203 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Delete remote branch 204 | 205 | ## Objective: Delete remote branch 206 | **** 207 | 208 | * Delete remote branch 209 | 210 | ## Steps: 211 | 212 | * Change into `$HOME/training` 213 | * Create or identify a remote branch `feature/docs-wrong-name` 214 | * Delete the remote branch 215 | 216 | !SLIDE supplemental solutions 217 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 218 | **** 219 | 220 | ## Delete remote branch 221 | 222 | **** 223 | 224 | ### Create and push remote branch 225 | 226 | If you do not have any. 227 | 228 | @@@ Sh 229 | $ cd $HOME/training 230 | $ git checkout main 231 | $ git checkout -b feature/docs-wrong-name 232 | $ git push -u origin feature/docs-wrong-name 233 | 234 | ### Identify remote branch to delete 235 | 236 | @@@ Sh 237 | $ git branch -r 238 | feature/docs-wrong-name 239 | 240 | ### Delete remote branch 241 | 242 | @@@ Sh 243 | $ git push origin :feature/docs-wrong-name 244 | 245 | Now verify it is gone (Hint: `-r` lists remote branches). 246 | 247 | @@@ Sh 248 | $ git fetch 249 | $ git branch -r 250 | 251 | !SLIDE smbullets 252 | # Collaboration: Get History 253 | 254 | * `git fetch` 255 | * Downloads data from a remote repository 256 | * The changes from the remote repository are not integrated into local branches 257 | * `git pull` 258 | * Downloads data from a remote repository and integrates them into local branches 259 | * git pull runs `git fetch` and either `git rebase` or `git merge` behind the scences 260 | 261 | ~~~SECTION:handouts~~~ 262 | 263 | **** 264 | 265 | `git fetch` downloads objects and references from another remote repository. 266 | 267 | `git pull` invokes a fetch and updates the local history with commits from the remote repository. 268 | 269 | ~~~ENDSECTION~~~ 270 | 271 | !SLIDE smbullets 272 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Learn more about git fetch and git pull 273 | 274 | * Objective: 275 | * Learn more about git fetch and git pull 276 | * Steps: 277 | * Go to your project repository in GitLab 278 | * Edit the `README.md` in your browser and commit the change to main 279 | * Run `git fetch` and explain `git diff main origin/main` 280 | * Run `git pull` 281 | * Explain the difference 282 | 283 | !SLIDE supplemental exercises 284 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Learn more about git fetch and git pull 285 | 286 | ## Objective: Learn more about git fetch and git pull 287 | **** 288 | 289 | * Learn more about git fetch and git pull 290 | 291 | ## Steps: 292 | 293 | * Go to your project repository in GitLab 294 | * Edit the `README.md` in your browser and commit the change to main 295 | * Run `git fetch` and explain `git diff main origin/main` 296 | * Run `git pull` 297 | * Explain the difference 298 | 299 | ## Bonus: 300 | 301 | * Repeat push and pull multiple times 302 | 303 | !SLIDE supplemental solutions 304 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 305 | **** 306 | 307 | ## Learn more about git fetch and git pull 308 | 309 | **** 310 | 311 | ### Go to GitLab, edit README.md and commit the change 312 | 313 | Navigate into the `training` project and choose `Repository`. 314 | 315 | Click on the `README.md` file and choose to `edit` it directly. 316 | Add some documentation like `This change was done via GitLab web.`. 317 | 318 | Stage and commit the change directly to main. 319 | 320 | ### Fetch changes 321 | 322 | Change to the CLI again and fetch the changes. 323 | 324 | @@@ Sh 325 | $ git fetch 326 | 327 | Compare this with your local commit history - you'll see that there are 328 | not changes pulled yet. 329 | 330 | @@@ Sh 331 | $ git log 332 | $ git diff main origin/main 333 | 334 | ### Pull changes 335 | 336 | @@@ Sh 337 | $ git pull 338 | 339 | Check the local commit history - now your local history has been 340 | updated with the remote history. 341 | 342 | @@@ Sh 343 | $ git log 344 | $ git diff main origin/main 345 | -------------------------------------------------------------------------------- /day1/06_Server/04_Connect_Local_Remote.md: -------------------------------------------------------------------------------- 1 | 2 | !SLIDE smbullets 3 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Create GitLab Project 4 | 5 | * Objective: 6 | * Create a new GitLab project for the current user 7 | * Steps: 8 | * Click the `+` in the top left corner 9 | * Choose `New Project` 10 | * Add the name `training` 11 | * Leave it as `Private` 12 | * Untick `Initialize repository with a README` for an empty project 13 | * Create the project 14 | * Note: 15 | * Learn about the project view and the HTTPS clone URL 16 | 17 | !SLIDE supplemental exercises 18 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Create GitLab Project 19 | 20 | ## Objective: Create a new GitLab project for the current user 21 | **** 22 | 23 | * Create a new GitLab project for the current user 24 | 25 | ## Steps: 26 | 27 | **** 28 | 29 | * Click the `+` in the top left corner 30 | * Choose `New Project` 31 | * Add the name `training` 32 | * Leave it as `Private` 33 | * Untick `Initialize repository with a README` for an empty project 34 | * Create the project 35 | 36 | ## Note: 37 | 38 | **** 39 | 40 | * Learn about the project view and the HTTPS clone URL 41 | 42 | 43 | !SLIDE supplemental solutions 44 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 45 | **** 46 | 47 | ## Create a new GitLab project for the current user 48 | 49 | **** 50 | ### Add Project 51 | 52 | GitLab provides a `New Project` link underneath the `+` icon in the top left corner. 53 | 54 | Fill in the `Project name` form with `training`, untick `Initialize repository with a README` for an empty project and leave the 55 | other options as default. 56 | 57 | ### Project View 58 | 59 | You'll notice the `HTTPS` URL centered below the project name. 60 | 61 | We will be using this remote URL for connecting our local repository 62 | in the next step. 63 | 64 | Right now the repository is empty and does not contain any file. 65 | GitLab offers you to add new files, e.g. a README.md file or LICENSE details 66 | directly in the browser. In the background, it is still comitting 67 | the changes to the Git repository. 68 | 69 | !SLIDE 70 | # GitLab Issues and Boards 71 | 72 | Issues can be used for planning and tracking work (feature requests, bugfixes, questions). 73 | 74 | Issues can be annotated with labels. 75 | 76 | Milestones allow you to organize issues into a cohesive group. 77 | 78 | The issue board is a software project management tool used to plan, organize, and visualize a workflow for a feature or product release. 79 | 80 | * Kanban or Scrum board 81 | * Filter by labels 82 | * Drag & drop issues 83 | 84 | !SLIDE 85 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Create Milestone and Issues 86 | 87 | * Objective 88 | * Create Milestone `v1.0` 89 | * Create Issue `Update documentation` 90 | 91 | * Steps: 92 | * Navigate into `Plan > Milestones` 93 | * Select `New Milestone` and use `v1.0` as title 94 | * Navigate to `Plan > Issues` and select `New issue` 95 | * Use `Update documentation` as title, add a description 96 | * Assign the `v1.0` milestone 97 | 98 | * Bonus: 99 | * Add labels to the new issue 100 | 101 | !SLIDE supplemental exercises 102 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Create Milestone and Issues 103 | 104 | ## Objective: Create Milestone and First Issue 105 | **** 106 | 107 | * Create Milestone and First Issue 108 | 109 | ## Steps: 110 | 111 | **** 112 | 113 | * Navigate into `Plan > Milestones` 114 | * Select `New Milestone` and use `v1.0` as title 115 | * Navigate to `Plan > Issues` and select `New issue` 116 | * Use `Update documentation` as title, add a description 117 | * Assign the `v1.0` milestone 118 | 119 | !SLIDE smbullets 120 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add Project Members 121 | 122 | * Objective 123 | * Add the trainers as Project members 124 | 125 | * Steps: 126 | * Navigate into `Manage > Members` 127 | * Use `Invite members` and search for the trainers 128 | * Select the `Developer` role and add the trainers 129 | 130 | * Bonus 131 | * Add a colleague or participant as `Guest` 132 | 133 | !SLIDE supplemental exercises 134 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add Project Members 135 | 136 | ## Objective: Add the trainers as Project members 137 | **** 138 | 139 | * Add the trainers as Project members 140 | 141 | ## Steps: 142 | 143 | **** 144 | 145 | * Navigate into `Manage > Members` 146 | * Use `Invite members` and search for the trainers 147 | * Select the `Developer` role and add the trainers 148 | 149 | !SLIDE 150 | # GitLab Project Snippets 151 | 152 | With GitLab snippets, you can store and share bits of code and text with other users. 153 | 154 | * Snippet visibility can differ from the project's visibility 155 | * Snippets are version controlled and have syntax highlighting 156 | * URL is stable and can be shared 157 | 158 | Example use cases: 159 | 160 | * Guides for less code-savvy people 161 | * Documentation for hard to automate but regular tasks 162 | 163 | Can be cloned because they are stored with Git. 164 | 165 | Try it out with the trainer. 166 | 167 | ~~~ENDSECTION~~~ 168 | 169 | !SLIDE 170 | # GitLab Project Wiki 171 | 172 | Every wiki is a separate Git repository, within the project. 173 | 174 | * Supports Markdown, Rdoc, AsciiDoc, and Org for content 175 | * Hierarchical links possible 176 | * Mermaid diagrams and charts can be included 177 | 178 | Example use cases: 179 | 180 | * Additional documentation for the project 181 | 182 | Can be cloned because they are stored with Git. 183 | 184 | Try it out with the trainer. 185 | 186 | ~~~ENDSECTION~~~ 187 | 188 | !SLIDE smbullets 189 | # Connect Local Repository to Remote Server 190 | 191 | Endpoints for the remote servers are called `remote` in Git. 192 | 193 | * Communication is done via SSH/HTTPS (SSH is recommended) 194 | * We need a remote for: `clone`, `push`, `pull` 195 | * We can have multiple remotes (e.g. fork, upstream) 196 | 197 | For training purposes we've started to work offline in `$HOME/training`. 198 | 199 | Now we want to publish the local commits to a newly created Git repository 200 | in GitLab. 201 | 202 | ~~~SECTION:handouts~~~ 203 | 204 | **** 205 | 206 | **SSH Keys** 207 | 208 | Generate a new SSH key pair on your client. 209 | 210 | ``` 211 | ssh-keygen -t ed25519 212 | ``` 213 | 214 | Copy the public key into your GitLab settings. 215 | 216 | ``` 217 | cat $HOME/.ssh/id_ed25519.pub 218 | ``` 219 | 220 | User > Settings > SSH Keys 221 | 222 | ~~~ENDSECTION~~~ 223 | 224 | !SLIDE smbullets 225 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add the repository as remote origin 226 | 227 | * Objective: 228 | * Add the GitLab project as remote origin 229 | * Steps 230 | * Open the project in GitLab and extract the `HTTPS` clone URL 231 | * Navigate into your local repository in `$HOME/training` 232 | * Use `git remote add origin ` 233 | * Push the main branch with `git push origin main` 234 | 235 | !SLIDE supplemental exercises 236 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add the repository as remote origin 237 | 238 | ## Objective: Add the repository as remote origin 239 | **** 240 | 241 | * Add the repository as remote origin 242 | 243 | ## Steps: 244 | 245 | **** 246 | 247 | * Open the project in GitLab and extract the `HTTPS` clone URL 248 | * Navigate into your local repository 249 | * Use `git remote add origin ` 250 | * Push the main branch with `git push origin main` 251 | 252 | !SLIDE supplemental solutions 253 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 254 | **** 255 | 256 | ## Add the repository as remote origin 257 | 258 | **** 259 | 260 | ### Add the remote origin 261 | 262 | @@@ Sh 263 | $ cd $HOME/training.git 264 | $ git remote add origin https://[...].nws.netways.de/root/training.git 265 | $ git fetch 266 | 267 | ### Push the history 268 | 269 | @@@ Sh 270 | $ git push 271 | 272 | This will not work since the local branch does not follow the remote branch. 273 | Use `--set-upstream` as proposed by the cli output. Short form is `-u`. 274 | 275 | @@@ Sh 276 | $ cd $HOME/training.git 277 | $ git remote add origin https://[...].nws.netways.de/root/training.git 278 | $ git push origin main 279 | 280 | ### Set default push method 281 | 282 | Git versions prior 2.0 did not define the default push method. The default behaviour 283 | was to use the same local branch name for the remote branch name. 284 | 285 | The new default method should be `simple` which ensures that the local branches 286 | will only be pushed to remote branches which `git pull` is following. 287 | 288 | Our setup did not clone the repository (which includes a virtual git pull). Therefore 289 | the local main branch does not follow a remote branch. 290 | 291 | In order to fix that, add the default push method to your global configuration. 292 | 293 | @@@ Sh 294 | git config --global push.default simple 295 | 296 | ### Push and update all branches 297 | 298 | `git push -u origin main` creates a new remote branch, updates the tracking to the 299 | local current branch and pushes all references/commits. 300 | 301 | If you want to sync all local branches, you can omit the branch name in the command and 302 | use `--all` instead. 303 | 304 | @@@ Sh 305 | git push -u origin --all 306 | 307 | Keep in mind that syncing all your local branches might create unwanted remote branches. 308 | Those can be there just for testing things, or are not meant for the public domain. 309 | 310 | !SLIDE smbullets 311 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add a credential cache 312 | 313 | * Objective: 314 | * Add the credential cache to the configuration 315 | * Steps 316 | * Go to your terminal 317 | * Use `git config credential.helper 'cache --timeout=99999'` 318 | 319 | This is only for the training. In reality use SSH authentication. 320 | 321 | !SLIDE supplemental exercises 322 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Add a credential cache 323 | 324 | ## Objective: Add the credential cache to the configuration 325 | **** 326 | 327 | * Add the credential cache to the configuration 328 | 329 | ## Steps: 330 | 331 | **** 332 | 333 | * Go to your terminal 334 | * Use `git config credential.helper 'cache --timeout=99999'` 335 | 336 | This is only for the training. In reality use SSH authentication. 337 | 338 | !SLIDE supplemental solutions 339 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 340 | **** 341 | 342 | ## Add a credential cache 343 | 344 | **** 345 | 346 | ### Add a credential cache 347 | 348 | @@@ Sh 349 | $ cd $HOME/training.git 350 | $ git config credential.helper 'cache --timeout=99999' 351 | 352 | This will make git save the credentials you enter the first time you 353 | interact with the server and use them for `99999` seconds before you need to re-enter them. 354 | 355 | This is only for the training. In reality use SSH authentication. 356 | 357 | !SLIDE smbullets 358 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Explore Project History 359 | 360 | * Objective: 361 | * Learn more about GitLab and the project's history 362 | * Compare the local history to the remote project's history 363 | * Steps: 364 | * Click on `Files > History` in the project view and examine the Git commits 365 | * Run `git log` on your shell and compare them to GitLab 366 | * Bonus: 367 | * Use `Repository > Graph` in GitLab 368 | 369 | !SLIDE supplemental exercises 370 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Explore Project History 371 | 372 | ## Objective: Learn more about the project history 373 | 374 | **** 375 | 376 | * Learn more about GitLab and the project's history 377 | * Compare the local history to the remote project's history 378 | 379 | ## Steps: 380 | 381 | **** 382 | 383 | * Click on `Files > History` in the project view and examine the Git commits 384 | * Run `git log` on your shell and compare them to GitLab 385 | 386 | ## Bonus: 387 | 388 | * Use `Repository > Graph` in GitLab 389 | 390 | !SLIDE supplemental solutions 391 | # Lab ~~~SECTION:MAJOR~~~.~~~SECTION:MINOR~~~: Proposed Solution 392 | **** 393 | 394 | ## Examine GitLab's project history 395 | 396 | **** 397 | 398 | ### Project History 399 | 400 | Choose `History` and look at the Git commits, their author, subject and timestamp. 401 | 402 | Compare it to the local `git log` entries. 403 | 404 | ### GitLab Graphs 405 | 406 | Navigate into `Repository > Graph` to get an alternative history view. 407 | -------------------------------------------------------------------------------- /global/layouts/osdc.css: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | Corrections for strange CSS rules by showoff 3 | ************************************************/ 4 | 5 | .code { 6 | white-space: unset; 7 | } 8 | .content.code p { 9 | font-family: monospace; 10 | white-space: pre; 11 | } 12 | 13 | .content.center { 14 | position: unset; 15 | top: unset; 16 | -webkit-transform: unset; 17 | -ms-transform: unset; 18 | transform: unset; 19 | } 20 | 21 | @media screen { 22 | /* The following assumes we'd get 24px (1.5em) by default: 24 / (16 x 0.8 x 0.8) */ 23 | .slide.small .content.small .net-header, 24 | .slide.small .content.small .net-footer { 25 | font-size: 234.375%; 26 | } 27 | 28 | /* The following assumes we'd get 24px (1.5em) by default: 24 / (16 x 0.7 x 0.7) */ 29 | .slide.smaller .content.smaller .net-header, 30 | .slide.smaller .content.smaller .net-footer { 31 | font-size: 306.122449%; 32 | } 33 | 34 | /* The following assumes the same as above, but is for non-container elements */ 35 | .slide.small .content.small .net-header + h1:not(.section-title) { 36 | font-size: 3.515625em; 37 | } 38 | .slide.smaller .content.smaller .net-header + h1:not(.section-title) { 39 | font-size: 4.591836735em; 40 | } 41 | } 42 | 43 | @media print { 44 | /* The following assumes we'd get 16px (1em) by default: 16 / (16 x 0.8) */ 45 | .content.small .net-header, 46 | .content.small .net-footer { 47 | font-size: 125%; 48 | } 49 | 50 | /* The following assumes we'd get 16px (1em) by default: 16 / (16 x 0.7) */ 51 | .content.smaller .net-header, 52 | .content.smaller .net-footer { 53 | font-size: 142.8571429%; 54 | } 55 | 56 | /* The following assumes the same as above, but is for non-container elements */ 57 | .content.small .net-header + h1:not(.section-title) { 58 | font-size: 1.875em; 59 | } 60 | .content.smaller .net-header + h1:not(.section-title) { 61 | font-size: 2.142857144em; 62 | } 63 | } 64 | 65 | /************************************************* 66 | Layout 67 | 68 | !!!!!!!!!!!!!!!!!!!! 69 | Please pay attention that all layout styles do not 70 | depend on any raw pixel sizes. Hence when adjusting 71 | anything, please use percent or em as size unit. 72 | And adjust dependent elements, paddings, margins 73 | accordingly. Thank you! 74 | !!!!!!!!!!!!!!!!!!!! 75 | 76 | ************************************************/ 77 | 78 | .net-header img { 79 | margin-right: 1.5em; 80 | } 81 | 82 | .content .net-header + h1:not(.section-title) { 83 | line-height: 100%; 84 | font-size: 1.5em; 85 | padding: .1em .25em; 86 | border-bottom: none; 87 | } 88 | 89 | .content.subsection .net-header + h1:not(.section-title), 90 | .content.subsectionnonum .net-header + h1:not(.section-title) { 91 | display: inline-block; 92 | margin-top: 3em; 93 | font-size: 2em; 94 | } 95 | 96 | .center .net-header + h1 { 97 | text-align: left; 98 | } 99 | 100 | @media screen { 101 | .slide:not(.small):not(.smaller) { 102 | font-size: 1.5em; /* Already done by showoff, but in case they'll change it in the future.. */ 103 | } 104 | 105 | .net-header { 106 | height: 4.104166667em; 107 | padding-bottom: .0625em; 108 | } 109 | 110 | .subsection .net-header, 111 | .subsectionnonum .net-header, 112 | #pre_osdc_title_00_title1 .net-header, 113 | #global_pre_osdc_title_00_title1 .net-header { 114 | border-bottom: .0625em solid black; 115 | padding-bottom: 0; 116 | } 117 | 118 | .net-header img { 119 | /* Solves that the image overlays the header's border. 120 | #preso's transformation still produces artifacts, though.. */ 121 | margin-top: -.0625em; 122 | /* Yep, applied on every slide. Otherwise we'll get flickering when switching slides */ 123 | } 124 | 125 | .content .net-header + h1:not(.section-title) { 126 | margin: 0; 127 | color: white; 128 | background: #2d2e52; 129 | } 130 | 131 | .net-footer { 132 | position: absolute; 133 | bottom: 0; 134 | width: 100%; 135 | color: white; 136 | background: #2d2e52; 137 | } 138 | 139 | .net-footer * { 140 | font-size: 62.5%; 141 | } 142 | 143 | .net-footer :first-child { 144 | display: inline-block; 145 | margin: .5em 1em; 146 | } 147 | 148 | .net-footer :last-child { 149 | float: right; 150 | margin: .5em 1em; 151 | } 152 | } 153 | 154 | @media print { 155 | .slide:not(.small):not(.smaller) { 156 | font-size: 1em; /* Already done by showoff, but in case they'll change it in the future.. */ 157 | } 158 | 159 | .net-header { 160 | height: 4em; 161 | border-bottom: .0625em solid black; 162 | } 163 | 164 | .net-header img { 165 | height: 80%; /* The negative margin workaround does not work with wkhtmltopdf.. */ 166 | width: 6em; 167 | } 168 | 169 | #pre_osdc_title_00_title1 .net-header, 170 | #global_pre_osdc_title_00_title1 .net-header { 171 | display: none; 172 | } 173 | 174 | .content:not(.subsection):not(.subsectionnonum) .net-header + h1:not(.section-title) { 175 | margin: .3em 0; 176 | } 177 | 178 | .subsection .net-header + h1:not(.section-title), 179 | .subsectionnonum .net-header + h1:not(.section-title) { 180 | width: 13.6em; /* Without this explicit slide max-width wkhtmltopdf is unable to produce proper line breaks */ 181 | color: white; 182 | background: #2d2e52; 183 | } 184 | 185 | .net-footer { 186 | display: none; 187 | } 188 | } 189 | 190 | /************************************************* 191 | Global styles 192 | ************************************************/ 193 | 194 | @media screen { 195 | .title-name { 196 | overflow: auto; 197 | } 198 | 199 | .title-name p { 200 | float: right; 201 | margin: 1em 0; 202 | padding: .25em; 203 | font-size: 2.5em; 204 | color: white; 205 | background: black; 206 | } 207 | 208 | .title-subtitle { 209 | overflow: auto; 210 | } 211 | 212 | .title-subtitle p { 213 | float: right; 214 | margin: 1em 0; 215 | padding: .25em; 216 | font-size: 1.5em; 217 | color: black; 218 | background: #2d2e52; 219 | } 220 | 221 | .title-author p { 222 | font-size: 1.35em; 223 | } 224 | } 225 | 226 | @media print { 227 | .title-logo { 228 | margin: 1em; 229 | } 230 | 231 | .title-logo img { 232 | margin: 0 auto; 233 | } 234 | 235 | .title-cover { 236 | margin: 0.5em; 237 | margin-top: 4em; 238 | padding: 1em; 239 | height: 25.5em; 240 | color: white; 241 | background: #2d2e52; 242 | } 243 | 244 | .title-name { 245 | font-size: 2em; 246 | } 247 | 248 | .title-release { 249 | margin-top: 2em; 250 | } 251 | 252 | .title-footer { 253 | margin-top: 23.5em; 254 | text-align: right; 255 | font-weight: bold; 256 | } 257 | } 258 | 259 | /************************************************* 260 | Slide styles 261 | ************************************************/ 262 | 263 | @media screen { 264 | /** 265 | Please note: 266 | 4.166666667em = Header height 267 | 1.8em = h1 height 268 | 1.354166667em = Footer height 269 | 24.679166666em = Content height 270 | 32em = Total slide height 271 | **/ 272 | .content > .margin-top-1-8 { margin-top: 3.084895833em; } 273 | .content > .margin-top-1-7 { margin-top: 3.525595238em; } 274 | .content > .margin-top-1-6 { margin-top: 4.113194444em; } 275 | .content > .margin-top-1-5 { margin-top: 4.935833333em; } 276 | .content > .margin-top-1-4 { margin-top: 6.169791666em; } 277 | .content > .margin-top-1-3 { margin-top: 8.226388889em; } 278 | .content > .margin-top-1-2 { margin-top: 12.339583333em; } 279 | 280 | /* Since bigtext does not work with our layout.. */ 281 | .content > .large { font-size: 120%; } 282 | .content > .larger { font-size: 140%; } 283 | .content > .even-larger { font-size: 180%; } 284 | .content > .big { font-size: 150%; } 285 | .content > .bigger { font-size: 300%; } 286 | .content > .probably-too-big { font-size: 600%; } 287 | } 288 | 289 | @media print { 290 | /** 291 | Please note: 292 | 6.25em = Header height 293 | 2.7em = h1 height 294 | 2.03125em = Footer height 295 | 38.81875em = Content height 296 | 49.8em = Total slide height 297 | **/ 298 | .content > .margin-top-1-8 { margin-top: 4.85234375em; } 299 | .content > .margin-top-1-7 { margin-top: 5.545535714em; } 300 | .content > .margin-top-1-6 { margin-top: 6.469791667em; } 301 | .content > .margin-top-1-5 { margin-top: 7.76375em; } 302 | .content > .margin-top-1-4 { margin-top: 9.7046875em; } 303 | .content > .margin-top-1-3 { margin-top: 12.939583333em; } 304 | .content > .margin-top-1-2 { margin-top: 19.409375em; } 305 | 306 | /* Since bigtext does not work with our layout.. */ 307 | .content > .large { font-size: 180%; } 308 | .content > .larger { font-size: 210%; } 309 | .content > .even-larger { font-size: 270%; } 310 | .content > .big { font-size: 225%; } 311 | .content > .bigger { font-size: 450%; } 312 | .content > .probably-too-big { font-size: 900%; } 313 | } 314 | 315 | /************************************************* 316 | Legacy styles 317 | ************************************************/ 318 | 319 | @media screen { 320 | /* Global */ 321 | 322 | .slide, #preso { 323 | height: 768px; 324 | width: 1024px; 325 | } 326 | 327 | a, a:visited { 328 | color: #2d2e52; 329 | text-decoration: none; 330 | } 331 | 332 | .content h2 { 333 | font-size: 24px; 334 | margin-left: 1em; 335 | text-align: left; 336 | } 337 | 338 | .content h3 { 339 | font-size: 20px; 340 | margin-left: 1em; 341 | text-align: left; 342 | } 343 | 344 | .content h4 { 345 | font-size: 16px; 346 | margin-left: 1em; 347 | text-align: left; 348 | } 349 | 350 | .content > p, 351 | .content > form > p { 352 | text-align: left; 353 | } 354 | 355 | .content p > img { 356 | max-width: 100%; 357 | } 358 | 359 | .content > ul, 360 | .content > ol { 361 | margin-left: 0; 362 | } 363 | 364 | /* Slide Styles */ 365 | 366 | .bullets > ul { 367 | font-size: 1.5em; 368 | list-style: disc; 369 | } 370 | .smbullets > ul { 371 | list-style: disc; 372 | } 373 | .bullets > ul > li, 374 | .smbullets > ul > li { 375 | text-align: left; 376 | } 377 | .bullets > ul > li > p, 378 | .smbullets > ul > li > p { 379 | margin: 0; 380 | } 381 | 382 | ul ol, ol ul, ul ul, ol ol { 383 | padding-left: 1em; 384 | } 385 | 386 | /* Legacy styles start - For backward compliance with slides created using showoff v0.9.11.1 */ 387 | .slide.small > .content.small > p, 388 | .slide.small > .content.small > ul, 389 | .slide.small > .content.small > pre, 390 | .slide.small > .content.small > table { 391 | font-size: 2em; 392 | } 393 | 394 | .slide.small > .content.smbullets.small > ul > li { 395 | margin: 0; 396 | } 397 | /* Legacy styles end */ 398 | 399 | .center p { 400 | text-align: center; 401 | } 402 | .center > img { 403 | display: block; 404 | height: 90%; 405 | margin-top: 160px; 406 | margin-left: auto; 407 | margin-right: auto; 408 | width: 90%; 409 | } 410 | 411 | .break { 412 | visibility: collapse; 413 | } 414 | 415 | .supplemental.content > p { 416 | font-size: 2em; 417 | } 418 | 419 | /* Custom Slide Styles */ 420 | 421 | .lrbullets > ul > li:nth-of-type(odd) { 422 | float: left; 423 | width: 50%; 424 | } 425 | .lrbullets > ul > li:nth-of-type(even) { 426 | } 427 | 428 | .limg > img, 429 | .limg > p > img { 430 | float: left; 431 | width: 400px; 432 | height: 50%; 433 | } 434 | .rimg > img, 435 | .rimg > p > img { 436 | float: right; 437 | width: 50%; 438 | height: 50%; 439 | } 440 | 441 | .lbullets > ul { 442 | float: left; 443 | width: 50%; 444 | } 445 | .lbullets > ul > li { 446 | float: left; 447 | width: 50%; 448 | } 449 | .rbullets > ul { 450 | float: right; 451 | width: 50%; 452 | } 453 | .rbullets > ul > li { 454 | float: right; 455 | width: 50%; 456 | } 457 | 458 | /* Legacy styles start - Print specific styles which are not hidden anymore? */ 459 | .pagebreak { 460 | display: none; 461 | } 462 | /* Legacy styles end */ 463 | 464 | /* Custom Layout */ 465 | 466 | img#staff { 467 | float: right; 468 | margin-right: 100px; 469 | width: 240px; 470 | height: 240px; 471 | } 472 | } 473 | 474 | @page { 475 | margin: 0; 476 | margin-top: 1em; 477 | margin-left: 2em; 478 | margin-right: 1em; 479 | margin-bottom: 1em; 480 | } 481 | 482 | @media print { 483 | code { 484 | font-size: 12px; 485 | } 486 | 487 | li, td { 488 | font-size: 14px; 489 | } 490 | 491 | .slide, #preso { 492 | font: normal 1.0em "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 493 | height: 100%; 494 | margin: 0; 495 | margin-top: 0em; 496 | margin-left: 0em; 497 | margin-right: 0em; 498 | margin-bottom: 0em; 499 | width: 99%; 500 | } 501 | 502 | a, a:visited { 503 | color: #2d2e52; 504 | text-decoration: none; 505 | } 506 | 507 | .content { 508 | padding-top: 5px; 509 | } 510 | 511 | .content h2 { 512 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 513 | font-size: 24px; 514 | text-align: left; 515 | margin-left: 0.5em; 516 | margin-right: 3em; 517 | } 518 | 519 | .content h3 { 520 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 521 | font-size: 20px; 522 | text-align: left; 523 | margin-left: 0.5em; 524 | margin-right: 3em; 525 | } 526 | 527 | .content h4 { 528 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 529 | font-size: 16px; 530 | text-align: left; 531 | margin-left: 0.5em; 532 | margin-right: 3em; 533 | } 534 | 535 | .content > p { 536 | font-size: 16px; 537 | text-align: left; 538 | } 539 | 540 | .content > ul, 541 | .content > ol { 542 | margin-left: 0; 543 | } 544 | 545 | /* Slide Styles */ 546 | 547 | .bullets > ul { 548 | list-style: disc; 549 | padding-left: 40px; 550 | } 551 | .smbullets > ul { 552 | list-style: disc; 553 | padding-left: 10px; 554 | } 555 | .bullets > ul > li, 556 | .smbullets > ul > li { 557 | text-align: left; 558 | } 559 | .bullets > ul > li > p, 560 | .smbullets > ul > li > p { 561 | margin: 0; 562 | } 563 | 564 | ul ol, ol ul, ul ul, ol ol { 565 | padding-left: 1em; 566 | } 567 | 568 | .content > pre, .handouts > pre, .content > form > pre { 569 | font-size: 120%; 570 | margin: 0; 571 | } 572 | .content > pre > code, .handouts > pre > code, .content > form > pre > code { 573 | overflow: visible; 574 | } 575 | 576 | .center p { 577 | text-align: center; 578 | } 579 | 580 | .center > img { 581 | display: block; 582 | height: 90%; 583 | margin-left: auto; 584 | margin-right: auto; 585 | width: 90%; 586 | } 587 | 588 | .content table tr td { 589 | text-align: left; 590 | } 591 | 592 | .annotations { 593 | display: none; 594 | } 595 | 596 | .pagebreak { 597 | margin: 1em; 598 | } 599 | 600 | .handouts { 601 | display: block !important; 602 | border: none; 603 | } 604 | .handouts h1, h2, h3, h4 { 605 | margin: 0; 606 | margin-top: 1em; 607 | margin-left: 0.5em; 608 | margin-right: 3em; 609 | margin-bottom: 1em; 610 | text-align: left; 611 | } 612 | .handouts hr { 613 | margin: 2em 0; 614 | } 615 | .handouts p { 616 | margin: 0 3em 1em 2em; 617 | text-align: left; 618 | word-wrap: break-word; 619 | } 620 | 621 | .handouts > pre, .handouts > form > pre { 622 | word-wrap: break-word; 623 | } 624 | 625 | .handouts > ul { 626 | list-style: disc; 627 | padding-left: 40px; 628 | } 629 | 630 | .supplemental { 631 | right: 0.5em; 632 | } 633 | 634 | .supplemental.content > p { 635 | font-size: 14px; 636 | } 637 | 638 | .supplemental .content > pre > code { 639 | word-wrap: break-word; 640 | } 641 | 642 | .supplemental h1 { 643 | margin: 0; 644 | color: black; 645 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 646 | font-size: 22px; 647 | text-align: left; 648 | } 649 | 650 | .supplemental h2 { 651 | color: black; 652 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 653 | font-size: 20px; 654 | text-align: left; 655 | } 656 | 657 | .supplemental h3 { 658 | color: black; 659 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 660 | font-size: 18px; 661 | text-align: left; 662 | } 663 | 664 | .supplemental h4 { 665 | color: black; 666 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 667 | font-size: 16px; 668 | text-align: left; 669 | } 670 | 671 | div#toc a { 672 | font-size: 14px; 673 | margin-left: 2em; 674 | } 675 | 676 | /* Custom Slide Styles */ 677 | 678 | .lrbullets > ul > li:nth-of-type(odd) { 679 | float: left; 680 | width: 50%; 681 | } 682 | .lrbullets > ul > li:nth-of-type(even) { 683 | } 684 | 685 | /* Custom Layout */ 686 | 687 | .content.small table { 688 | font: normal 1.5em "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 689 | } 690 | } 691 | -------------------------------------------------------------------------------- /global/layouts/osmc.css: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | Corrections for strange CSS rules by showoff 3 | ************************************************/ 4 | 5 | .code { 6 | white-space: unset; 7 | } 8 | .content.code p { 9 | font-family: monospace; 10 | white-space: pre; 11 | } 12 | 13 | .content.center { 14 | position: unset; 15 | top: unset; 16 | -webkit-transform: unset; 17 | -ms-transform: unset; 18 | transform: unset; 19 | } 20 | 21 | @media screen { 22 | /* The following assumes we'd get 24px (1.5em) by default: 24 / (16 x 0.8 x 0.8) */ 23 | .slide.small .content.small .net-header, 24 | .slide.small .content.small .net-footer { 25 | font-size: 234.375%; 26 | } 27 | 28 | /* The following assumes we'd get 24px (1.5em) by default: 24 / (16 x 0.7 x 0.7) */ 29 | .slide.smaller .content.smaller .net-header, 30 | .slide.smaller .content.smaller .net-footer { 31 | font-size: 306.122449%; 32 | } 33 | 34 | /* The following assumes the same as above, but is for non-container elements */ 35 | .slide.small .content.small .net-header + h1:not(.section-title) { 36 | font-size: 3.515625em; 37 | } 38 | .slide.smaller .content.smaller .net-header + h1:not(.section-title) { 39 | font-size: 4.591836735em; 40 | } 41 | } 42 | 43 | @media print { 44 | /* The following assumes we'd get 16px (1em) by default: 16 / (16 x 0.8) */ 45 | .content.small .net-header, 46 | .content.small .net-footer { 47 | font-size: 125%; 48 | } 49 | 50 | /* The following assumes we'd get 16px (1em) by default: 16 / (16 x 0.7) */ 51 | .content.smaller .net-header, 52 | .content.smaller .net-footer { 53 | font-size: 142.8571429%; 54 | } 55 | 56 | /* The following assumes the same as above, but is for non-container elements */ 57 | .content.small .net-header + h1:not(.section-title) { 58 | font-size: 1.875em; 59 | } 60 | .content.smaller .net-header + h1:not(.section-title) { 61 | font-size: 2.142857144em; 62 | } 63 | } 64 | 65 | /************************************************* 66 | Layout 67 | 68 | !!!!!!!!!!!!!!!!!!!! 69 | Please pay attention that all layout styles do not 70 | depend on any raw pixel sizes. Hence when adjusting 71 | anything, please use percent or em as size unit. 72 | And adjust dependent elements, paddings, margins 73 | accordingly. Thank you! 74 | !!!!!!!!!!!!!!!!!!!! 75 | 76 | ************************************************/ 77 | 78 | .net-header img { 79 | margin-right: 1.5em; 80 | } 81 | 82 | .content .net-header + h1:not(.section-title) { 83 | line-height: 100%; 84 | font-size: 1.5em; 85 | padding: .1em .25em; 86 | border-bottom: none; 87 | } 88 | 89 | .content.subsection .net-header + h1:not(.section-title), 90 | .content.subsectionnonum .net-header + h1:not(.section-title) { 91 | display: inline-block; 92 | margin-top: 3em; 93 | font-size: 2em; 94 | } 95 | 96 | .center .net-header + h1 { 97 | text-align: left; 98 | } 99 | 100 | @media screen { 101 | .slide:not(.small):not(.smaller) { 102 | font-size: 1.5em; /* Already done by showoff, but in case they'll change it in the future.. */ 103 | } 104 | 105 | .net-header { 106 | height: 4.104166667em; 107 | padding-bottom: .0625em; 108 | } 109 | 110 | .subsection .net-header, 111 | .subsectionnonum .net-header, 112 | #pre_osmc_title_00_title1 .net-header, 113 | #global_pre_osmc_title_00_title1 .net-header { 114 | border-bottom: .0625em solid black; 115 | padding-bottom: 0; 116 | } 117 | 118 | .net-header img { 119 | /* Solves that the image overlays the header's border. 120 | #preso's transformation still produces artifacts, though.. */ 121 | margin-top: -.0625em; 122 | /* Yep, applied on every slide. Otherwise we'll get flickering when switching slides */ 123 | } 124 | 125 | .content .net-header + h1:not(.section-title) { 126 | margin: 0; 127 | color: white; 128 | background: #a011f0; 129 | } 130 | 131 | .net-footer { 132 | position: absolute; 133 | bottom: 0; 134 | width: 100%; 135 | color: white; 136 | background: #a011f0; 137 | } 138 | 139 | .net-footer * { 140 | font-size: 62.5%; 141 | } 142 | 143 | .net-footer :first-child { 144 | display: inline-block; 145 | margin: .5em 1em; 146 | } 147 | 148 | .net-footer :last-child { 149 | float: right; 150 | margin: .5em 1em; 151 | } 152 | } 153 | 154 | @media print { 155 | .slide:not(.small):not(.smaller) { 156 | font-size: 1em; /* Already done by showoff, but in case they'll change it in the future.. */ 157 | } 158 | 159 | .net-header { 160 | height: 4em; 161 | border-bottom: .0625em solid black; 162 | } 163 | 164 | .net-header img { 165 | height: 80%; /* The negative margin workaround does not work with wkhtmltopdf.. */ 166 | width: 6em; 167 | } 168 | 169 | #pre_osmc_title_00_title1 .net-header, 170 | #global_pre_osmc_title_00_title1 .net-header { 171 | display: none; 172 | } 173 | 174 | .content:not(.subsection):not(.subsectionnonum) .net-header + h1:not(.section-title) { 175 | margin: .3em 0; 176 | } 177 | 178 | .subsection .net-header + h1:not(.section-title), 179 | .subsectionnonum .net-header + h1:not(.section-title) { 180 | width: 13.6em; /* Without this explicit slide max-width wkhtmltopdf is unable to produce proper line breaks */ 181 | color: white; 182 | background: #a011f0; 183 | } 184 | 185 | .net-footer { 186 | display: none; 187 | } 188 | } 189 | 190 | /************************************************* 191 | Global styles 192 | ************************************************/ 193 | 194 | @media screen { 195 | .title-name { 196 | overflow: auto; 197 | } 198 | 199 | .title-name p { 200 | float: right; 201 | margin: 1em 0; 202 | padding: .25em; 203 | font-size: 2.5em; 204 | color: white; 205 | background: black; 206 | } 207 | 208 | .title-subtitle { 209 | overflow: auto; 210 | } 211 | 212 | .title-subtitle p { 213 | float: right; 214 | margin: 1em 0; 215 | padding: .25em; 216 | font-size: 1.5em; 217 | color: black; 218 | background: #a011f0; 219 | } 220 | 221 | .title-author p { 222 | font-size: 1.35em; 223 | } 224 | } 225 | 226 | @media print { 227 | .title-logo { 228 | margin: 1em; 229 | } 230 | 231 | .title-logo img { 232 | margin: 0 auto; 233 | } 234 | 235 | .title-cover { 236 | margin: 0.5em; 237 | margin-top: 4em; 238 | padding: 1em; 239 | height: 26em; 240 | color: white; 241 | background: #a011f0; 242 | } 243 | 244 | .title-name { 245 | font-size: 2em; 246 | } 247 | 248 | .title-release { 249 | margin-top: 2em; 250 | } 251 | 252 | .title-footer { 253 | margin-top: 23.5em; 254 | text-align: right; 255 | font-weight: bold; 256 | } 257 | } 258 | 259 | /************************************************* 260 | Slide styles 261 | ************************************************/ 262 | 263 | @media screen { 264 | /** 265 | Please note: 266 | 4.166666667em = Header height 267 | 1.8em = h1 height 268 | 1.354166667em = Footer height 269 | 24.679166666em = Content height 270 | 32em = Total slide height 271 | **/ 272 | .content > .margin-top-1-8 { margin-top: 3.084895833em; } 273 | .content > .margin-top-1-7 { margin-top: 3.525595238em; } 274 | .content > .margin-top-1-6 { margin-top: 4.113194444em; } 275 | .content > .margin-top-1-5 { margin-top: 4.935833333em; } 276 | .content > .margin-top-1-4 { margin-top: 6.169791666em; } 277 | .content > .margin-top-1-3 { margin-top: 8.226388889em; } 278 | .content > .margin-top-1-2 { margin-top: 12.339583333em; } 279 | 280 | /* Since bigtext does not work with our layout.. */ 281 | .content > .large { font-size: 120%; } 282 | .content > .larger { font-size: 140%; } 283 | .content > .even-larger { font-size: 180%; } 284 | .content > .big { font-size: 150%; } 285 | .content > .bigger { font-size: 300%; } 286 | .content > .probably-too-big { font-size: 600%; } 287 | } 288 | 289 | @media print { 290 | /** 291 | Please note: 292 | 6.25em = Header height 293 | 2.7em = h1 height 294 | 2.03125em = Footer height 295 | 38.81875em = Content height 296 | 49.8em = Total slide height 297 | **/ 298 | .content > .margin-top-1-8 { margin-top: 4.85234375em; } 299 | .content > .margin-top-1-7 { margin-top: 5.545535714em; } 300 | .content > .margin-top-1-6 { margin-top: 6.469791667em; } 301 | .content > .margin-top-1-5 { margin-top: 7.76375em; } 302 | .content > .margin-top-1-4 { margin-top: 9.7046875em; } 303 | .content > .margin-top-1-3 { margin-top: 12.939583333em; } 304 | .content > .margin-top-1-2 { margin-top: 19.409375em; } 305 | 306 | /* Since bigtext does not work with our layout.. */ 307 | .content > .large { font-size: 180%; } 308 | .content > .larger { font-size: 210%; } 309 | .content > .even-larger { font-size: 270%; } 310 | .content > .big { font-size: 225%; } 311 | .content > .bigger { font-size: 450%; } 312 | .content > .probably-too-big { font-size: 900%; } 313 | } 314 | 315 | /************************************************* 316 | Legacy styles 317 | ************************************************/ 318 | 319 | @media screen { 320 | /* Global */ 321 | 322 | .slide, #preso { 323 | height: 768px; 324 | width: 1024px; 325 | } 326 | 327 | a, a:visited { 328 | color: #a011f0; 329 | text-decoration: none; 330 | } 331 | 332 | .content h2 { 333 | font-size: 24px; 334 | margin-left: 1em; 335 | text-align: left; 336 | } 337 | 338 | .content h3 { 339 | font-size: 20px; 340 | margin-left: 1em; 341 | text-align: left; 342 | } 343 | 344 | .content h4 { 345 | font-size: 16px; 346 | margin-left: 1em; 347 | text-align: left; 348 | } 349 | 350 | .content > p, 351 | .content > form > p { 352 | text-align: left; 353 | } 354 | 355 | .content p > img { 356 | max-width: 100%; 357 | } 358 | 359 | .content > ul, 360 | .content > ol { 361 | margin-left: 0; 362 | } 363 | 364 | /* Slide Styles */ 365 | 366 | .bullets > ul { 367 | font-size: 1.5em; 368 | list-style: disc; 369 | } 370 | .smbullets > ul { 371 | list-style: disc; 372 | } 373 | .bullets > ul > li, 374 | .smbullets > ul > li { 375 | text-align: left; 376 | } 377 | .bullets > ul > li > p, 378 | .smbullets > ul > li > p { 379 | margin: 0; 380 | } 381 | 382 | ul ol, ol ul, ul ul, ol ol { 383 | padding-left: 1em; 384 | } 385 | 386 | /* Legacy styles start - For backward compliance with slides created using showoff v0.9.11.1 */ 387 | .slide.small > .content.small > p, 388 | .slide.small > .content.small > ul, 389 | .slide.small > .content.small > pre, 390 | .slide.small > .content.small > table { 391 | font-size: 2em; 392 | } 393 | 394 | .slide.small > .content.smbullets.small > ul > li { 395 | margin: 0; 396 | } 397 | /* Legacy styles end */ 398 | 399 | .center p { 400 | text-align: center; 401 | } 402 | .center > img { 403 | display: block; 404 | height: 90%; 405 | margin-top: 160px; 406 | margin-left: auto; 407 | margin-right: auto; 408 | width: 90%; 409 | } 410 | 411 | .break { 412 | visibility: collapse; 413 | } 414 | 415 | .supplemental.content > p { 416 | font-size: 2em; 417 | } 418 | 419 | /* Custom Slide Styles */ 420 | 421 | .lrbullets > ul > li:nth-of-type(odd) { 422 | float: left; 423 | width: 50%; 424 | } 425 | .lrbullets > ul > li:nth-of-type(even) { 426 | } 427 | 428 | .limg > img, 429 | .limg > p > img { 430 | float: left; 431 | width: 400px; 432 | height: 50%; 433 | } 434 | .rimg > img, 435 | .rimg > p > img { 436 | float: right; 437 | width: 50%; 438 | height: 50%; 439 | } 440 | 441 | .lbullets > ul { 442 | float: left; 443 | width: 50%; 444 | } 445 | .lbullets > ul > li { 446 | float: left; 447 | width: 50%; 448 | } 449 | .rbullets > ul { 450 | float: right; 451 | width: 50%; 452 | } 453 | .rbullets > ul > li { 454 | float: right; 455 | width: 50%; 456 | } 457 | 458 | /* Legacy styles start - Print specific styles which are not hidden anymore? */ 459 | .pagebreak { 460 | display: none; 461 | } 462 | /* Legacy styles end */ 463 | 464 | /* Custom Layout */ 465 | 466 | img#staff { 467 | float: right; 468 | margin-right: 100px; 469 | width: 240px; 470 | height: 240px; 471 | } 472 | } 473 | 474 | @page { 475 | margin: 0; 476 | margin-top: 1em; 477 | margin-left: 2em; 478 | margin-right: 1em; 479 | margin-bottom: 1em; 480 | } 481 | 482 | @media print { 483 | code { 484 | font-size: 12px; 485 | } 486 | 487 | li, td { 488 | font-size: 14px; 489 | } 490 | 491 | .slide, #preso { 492 | font: normal 1.0em "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 493 | height: 100%; 494 | margin: 0; 495 | margin-top: 0em; 496 | margin-left: 0em; 497 | margin-right: 0em; 498 | margin-bottom: 0em; 499 | width: 99%; 500 | } 501 | 502 | a, a:visited { 503 | color: #a011f0; 504 | text-decoration: none; 505 | } 506 | 507 | .content { 508 | padding-top: 5px; 509 | } 510 | 511 | .content h2 { 512 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 513 | font-size: 24px; 514 | text-align: left; 515 | margin-left: 0.5em; 516 | margin-right: 3em; 517 | } 518 | 519 | .content h3 { 520 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 521 | font-size: 20px; 522 | text-align: left; 523 | margin-left: 0.5em; 524 | margin-right: 3em; 525 | } 526 | 527 | .content h4 { 528 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 529 | font-size: 16px; 530 | text-align: left; 531 | margin-left: 0.5em; 532 | margin-right: 3em; 533 | } 534 | 535 | .content > p { 536 | font-size: 16px; 537 | text-align: left; 538 | } 539 | 540 | .content > ul, 541 | .content > ol { 542 | margin-left: 0; 543 | } 544 | 545 | /* Slide Styles */ 546 | 547 | .bullets > ul { 548 | list-style: disc; 549 | padding-left: 40px; 550 | } 551 | .smbullets > ul { 552 | list-style: disc; 553 | padding-left: 10px; 554 | } 555 | .bullets > ul > li, 556 | .smbullets > ul > li { 557 | text-align: left; 558 | } 559 | .bullets > ul > li > p, 560 | .smbullets > ul > li > p { 561 | margin: 0; 562 | } 563 | 564 | ul ol, ol ul, ul ul, ol ol { 565 | padding-left: 1em; 566 | } 567 | 568 | .content > pre, .handouts > pre, .content > form > pre { 569 | font-size: 120%; 570 | margin: 0; 571 | } 572 | .content > pre > code, .handouts > pre > code, .content > form > pre > code { 573 | overflow: visible; 574 | } 575 | 576 | .center p { 577 | text-align: center; 578 | } 579 | 580 | .center > img { 581 | display: block; 582 | height: 90%; 583 | margin-left: auto; 584 | margin-right: auto; 585 | width: 90%; 586 | } 587 | 588 | .content table tr td { 589 | text-align: left; 590 | } 591 | 592 | .annotations { 593 | display: none; 594 | } 595 | 596 | .pagebreak { 597 | margin: 1em; 598 | } 599 | 600 | .handouts { 601 | display: block !important; 602 | border: none; 603 | } 604 | .handouts h1, h2, h3, h4 { 605 | margin: 0; 606 | margin-top: 1em; 607 | margin-left: 0.5em; 608 | margin-right: 3em; 609 | margin-bottom: 1em; 610 | text-align: left; 611 | } 612 | .handouts hr { 613 | margin: 2em 0; 614 | } 615 | .handouts p { 616 | margin: 0 3em 1em 2em; 617 | text-align: left; 618 | word-wrap: break-word; 619 | } 620 | 621 | .handouts > pre, .handouts > form > pre { 622 | word-wrap: break-word; 623 | } 624 | 625 | .handouts > ul { 626 | list-style: disc; 627 | padding-left: 40px; 628 | } 629 | 630 | .supplemental { 631 | right: 0.5em; 632 | } 633 | 634 | .supplemental.content > p { 635 | font-size: 14px; 636 | } 637 | 638 | .supplemental .content > pre > code { 639 | word-wrap: break-word; 640 | } 641 | 642 | .supplemental h1 { 643 | margin: 0; 644 | color: black; 645 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 646 | font-size: 22px; 647 | text-align: left; 648 | } 649 | 650 | .supplemental h2 { 651 | color: black; 652 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 653 | font-size: 20px; 654 | text-align: left; 655 | } 656 | 657 | .supplemental h3 { 658 | color: black; 659 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 660 | font-size: 18px; 661 | text-align: left; 662 | } 663 | 664 | .supplemental h4 { 665 | color: black; 666 | font-family: "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 667 | font-size: 16px; 668 | text-align: left; 669 | } 670 | 671 | div#toc a { 672 | font-size: 14px; 673 | margin-left: 2em; 674 | } 675 | 676 | /* Custom Slide Styles */ 677 | 678 | .lrbullets > ul > li:nth-of-type(odd) { 679 | float: left; 680 | width: 50%; 681 | } 682 | .lrbullets > ul > li:nth-of-type(even) { 683 | } 684 | 685 | /* Custom Layout */ 686 | 687 | .content.small table { 688 | font: normal 1.5em "Open Sans", "Lucida Sans Unicode", "Lucida Grande", "sans-serif"; 689 | } 690 | } 691 | --------------------------------------------------------------------------------