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 |
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 |
29 |
30 | !SLIDE smbullets printonly
31 | # Git GUI Clients: Sourcetree
32 |
33 |
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 |
47 |
48 | !SLIDE smbullets printonly
49 | # Git GUI Clients: Gitkraken
50 |
51 |
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 |
65 |
66 | !SLIDE smbullets printonly
67 | # Git GUI Clients: GitHub Desktop
68 |
69 |
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 |
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 |
57 |
58 | * Decentral VCS
59 | * Clients mirror the *version database* from a central system and work locally
60 | * Examples: Git, Mercurial
61 |
62 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
179 |
180 |
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 |
189 |
190 |
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 |
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 |
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 |
--------------------------------------------------------------------------------