Git Basics Workshop

Tibor Stanko

1 Intro

About me

  • Tibor Stanko, 33 years
  • since 2020 Data Engineer in Zurich Insurance, Bratislava 🇸🇰
  • before that, 6 years in academia in 🇫🇷 (PhD, postdoc)
  • I enjoy automating boring tasks using Python 🐍
  • not a Git guru, but I’ve been using Git daily for over 9 years
  • my hobbies: 👨‍👩‍👧‍👦🚲⛰️🎸🎹🍺

Contents of this workshop

2 Git & Github

What is Git?

  • version control system (VCS) or source control management (SCM)
  • in Slovak: systém riadenia verzií
  • keeps track of project development history
  • useful for teams and for individuals
  • not only about code, enables saving arbitrary files (including non-text)

Why do we need version control systems

Why do we need version control systems

What can you do with Git?

  • save versions
  • switch between versions
  • restore a previous version
  • compare versions
  • create branches
  • merge branches
  • back up files

What is Github?

  • “social network for programmers”
  • Git = version control system
  • Github = portal for maintaining repositories
  • uses Git, but is not a part of Git
  • has functionality beyond Git
    • Issues, Pull requests, Actions, …
  • similar services: Gitlab, Bitbucket, Azure DevOps, etc.

3 Basic Git Concepts

version 1version 2version 3version 4

Step 0: Working with the terminal

  • In order to understand how Git works, we will start by using Git through the terminal
  • Later on, we will also show how to use Git directly in an IDE (e.g. VS Code)
  • On Windows, I recommend Windows Terminal with PowerShell (built-in) or Nushell
  • Basic commands for navigating between directories in the terminal:
    • pwd — print the current directory
    • cd folder — change the current directory to folder
    • dir — list contents of the current directory
>> pwd                       # C:/Users/tibor.stanko
>> cd folder                 # C:/Users/tibor.stanko/folder
>> cd ..                     # C:/Users/tibor.stanko
>> cd C:/Users/janko.hrasko  # C:/Users/janko.hrasko
>> cd ~                      # C:/Users/tibor.stanko

Step 1: Installing Git

  • There are several ways to install Git on Windows, for example:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex # install scoop
scoop install git # install git
  • Instructions for macOS or Linux are on the official website in English or Czech.

Step 2: Configuring Git

  • Check if Git is installed correctly:
git --version
  • Before we start working with Git, we need to set our name and email using the git config command. Git will use these details to assign version authorship.
git config --global user.name "Tibor Stanko"
git config --global user.email "[email protected]"
  • Set the default branch to main (we will talk more about branches later)
git config --global init.defaultBranch "main"

Step 3: Creating a Git repository

  • Navigate to the directory where we want to create the repository:
cd ~/hello
  • The git init command is used to create a Git repository in the current directory:
git init
  • After running the command, Git will output:
Initialized empty Git repository in C:/Users/tibor.stanko/hello/.git/

Step 3: Creating a Git repository

  • We can check the status of the repository using git status:
git status
  • This is what an empty Git repository looks like (no files or saved versions):
On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)

Step 4: Saving a version

Saving a version involves two steps.

  1. Use git add to mark changes that should be added to the new version:
git add hello.py
  1. Use git commit to create a record of the new version:
git commit -m "Add hello.py"

Step 4: Saving a version

  • The commit message is usually a short, one-line description specified with the -m "commit message" argument.
  • If you want to write a longer description, omit the -m argument. git commit will then open a text editor where you can write the description.
  • In Git on Windows, the default editor for writing commit messages is vim, which runs directly in the terminal. If you are not familiar with using vim, you can change the editor:
git config --global core.editor notepad # Notepad
git config --global core.editor "code --wait" # VS Code

Step 4: Saving a version

Don’t slack off when writing commit messages!

Why do we save a version in two steps?

Some version control systems work by creating a new version from all the current files in the repository. This method of saving backups can be inefficient. For example, if we have implemented two independent features in the repository and we want to capture them in two separate versions. Therefore, Git introduces the concept of the staging area, which allows us to control which changes will be included in the next version.

# 1. add/stage - add file to the staging area
git add test.txt
# 2. commit - save a new version
git commit -m "added test.txt"

Step 5: Checking the status of the repository

  • We can check the current status of the repository using git status:
On branch main
nothing to commit, working tree clean
  • We can use the git log command to verify that a commit was created:
commit bf5c9b4a320012b422546fcb86f5b957104bea55 (HEAD -> main)
Author: Tibor Stanko <[email protected]>
Date:   Tue Sep 13 17:00:00 2022 +0200

    Add hello.py

Unstaging a file

  • Use git reset [file] to unstage a file while retaining changes in the working directory
git add dummy.txt
git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   dummy.txt

Unstaging a file

  • Use git reset [file] to unstage a file while retaining changes in the working directory
git reset dummy.txt
git status
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        dummy.txt

Exercises (1)

  1. Create an empty directory zoo on your computer.
  2. Turn the zoo directory into a Git repository.
  3. In the repository, create a file test.txt with any content.
  4. Add test.txt to the next version and save it.
  5. Check the new version using git log.

Tip: don’t forget to use git status while working to see the current status of the repository.

4 Branches

What is a branch?

  • Branches allow us to deviate from the main line and continue working without interfering with it

  • Branching is a strong feature of Git — switching between branches is fast, which allows for frequent creation of new branches

  • So far, we have been working on the main branch, which was automatically created by git init

  • We can see a list of branches using the git branch command:

>> git branch
* main

The default Git branch used to be master. Due to its negative connotations, this name is gradually being phased out. Therefore, when configuring Git, we changed init.defaultBranch to main.

What are branches good for?

  • Branches allow us to work efficiently in parallel on multiple parts of the project
  • For example, when we are developing a new feature (branch A) and a bug needs to be fixed immediately (branch B)
  • Thanks to Git, work on these two branches can proceed independently

rewrite/improve second bullet

Creating a branch

  • To create a new branch called french, we call:
git branch french
  • If we want to switch to the new branch:
git checkout french
  • These two operations are often done together, so there is a shortcut:
git checkout -b slovak # create branch 'slovak' and switch to it

Merging branches

  • If we want to add changes made on the slovak branch to the main main branch, we first switch to the main branch:
git checkout main
  • We use the git merge command to merge branches:
git merge slovak

Merging branches

Auto-merge

  • If possible, Git will automatically merge the changes from both branches. In that case, we will see the following output:
>> git merge slovak
Auto-merging hello.py
Merge made by the 'ort' strategy.
 hello.py | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Merging branches

Fast-forward

  • If the merged branch is a direct descendant of the target branch, Git will do a so-called fast-forward:
>> git merge comment
Updating 3a5d22e..9ad633c
Fast-forward
 hello.py | 1 +
 1 file changed, 1 insertion(+)

Merging branches

Resolving conflicts

  • If automatic merging fails, Git will report a merge conflict in the output. In this case, changes from both branches must be merged manually.
>> git merge french
Auto-merging hello.py
CONFLICT (content): Merge conflict in hello.py
Automatic merge failed; fix conflicts and then commit the result.
  • After manually merging, it is necessary to add the modified files to the new version:
git add hello.py
git commit -m "Merged branch 'french'"

Deleting a branch

  • If we no longer need a branch after merging it, we can delete it using git branch --delete, or git branch -d for short.
git branch -d comment

After deletion, the branch is removed from history and cannot be restored.

Example git log history

add mermaid diagram for this git log output

*   3a5d22e (HEAD -> main) Merge branch 'french'
|\
| * 21c7ab7 (french) Add french functionality
* |   1364948 Merge branch 'slovak'
|\ \
| * | c3159a6 (slovak) Add slovak functionality
| |/
* / 67e86d0 Fix missing exclamation mark
|/
* de1543b Add hello.py

Exercises (2)

  1. Switch to a new branch animals in your local repository.
  2. Create a new file zoo.txt in the repository with the following content:
panda
slon
lev
zirafa
  1. Save a new version that will contain zoo.txt.
  2. Merge changes made on the animals branch into the main branch and delete the animals branch.
  3. On a new tiger branch, change the lev line to tiger and save a new version.
  4. Switch to the main branch, fix the zirafa line to žirafa, and save a new version.
  5. Merge changes from the tiger branch into the main branch.

5 Remote Repositories

What is a remote repository?

  • So far, we have been working with a local Git repository that is stored on our computer

  • A remote repository is stored on the Internet — more precisely, on a web server
    e.g. github.com, corporate server, university server, …

  • There are two types of remote repositories:
    1. public repository is shared with all users who have access to the server
    2. private repository is shared only with selected users

What are remote repositories used for?

  1. Backup of code
  2. Sharing of code
  3. Synchronization of code in a team

Creating a repository on GitHub — github.com/new

Creating a repository on GitHub — github.com/new

Creating a repository on GitHub — github.com/new

Creating a repository on GitHub — github.com/new

Creating a repository on GitHub — github.com/new

Setting up a remote in the local repository

  • We use the git remote add <name> <url> command to set up a remote repository:
git remote add origin https://github.com/bbrrck/zoo.git
  • name is used by Git as the name of the remote repository at url. The name can be anything; the name origin is commonly used.
  • A local repository can have more than one remote assigned.

Sending a local copy to a remote

  • The git push <remote> <branch> command “pushes” local changes from the branch branch to the remote repository remote:
git push origin main
  • When calling git push for the first time, you need to add the -u argument:
git push -u origin main
  • -u or --set-upstream sets the default remote branch (origin/main) for the current local branch (main)

  • if the remote branch origin/main does not exist, git push will create it automatically

Example output from git push

git push -u origin main
  • Output:
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 241 bytes | 120.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/bbrrck/test-repo-01.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

Side note: logging in to GitHub

  • To allow Git to send data to GitHub, authentication is required
  • The easiest way to manage credentials: Git Credential Manager
    (it is included in Git for Windows)
  • Configuration starts automatically after the first git push is run

List of branches

  • git branch -a lists all branches, both local and remote
  • -a is short for --all
git branch -a
  • Output — * indicates the current branch:
* main
  tiger
  remotes/origin/main

Conflict: remote changes don’t exist locally

To https://github.com/bbrrck/zoo.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/bbrrck/zoo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Fetching remote changes into a local branch

  • Use the git fetch command to fetch the list of changes from the remote branch:
git fetch
  • Merge the changes that are not part of the local branch using git merge:
git merge # without arguments
  • In most cases, you can simply use the git pull command, which is a combination of git fetch and git merge:
git pull

Cloning an existing remote repository

  • You can clone an existing remote repository using git clone:
git clone <remote_url> <local_folder>
  • This command creates a copy of the repository from remote_url in the local_folder directory
  • Example:
git clone https://github.com/bbrrck/zoo.git myzoo
# or
git clone https://github.com/bbrrck/zoo.git # clones into the `zoo` directory

Exercises (3)

  1. Create a repository on Github with the name zoo.
  2. Add this remote to your local repository.
  3. Push the local main branch to the remote.
  4. On Github, add an emoji for each animal in the zoo.txt file: 🐼🐘🐯🦒.
  5. Synchronize your local repository with Github.
  6. On Github, add a new line krokodíl 🐊 to the zoo.txt file and save a new version.
  7. In your local repository, add a new line gorila 🦍 to zoo.txt and save a new version.
  8. Synchronize your local repository with Github and resolve any resulting merge conflicts.

6 Advanced Git

.gitignore

git <command> --help

# display help (documentation) for a given command -- e.g. git commit
git commit --help 
# or 
git commit -h

git diff

# show changes between two versions
git diff
git diff zoo.txt
git diff 235a0d8 5d94512 zoo.txt
git diff HEAD~1 HEAD zoo.txt

git cat-file -p

# show the contents of a Git object (commit, tree, blob)
git cat-file -p 235a0d8

git restore

# add a file to the staging area
git add zoo.txt
# remove a file from the staging area (unstage)
git restore --staged zoo.txt

git add --interactive

# interactively add changes
git add --interactive 
# or
git add -i

git log

# customize the output of git log
git log --all --oneline --graph --decorate
# or
git config --global alias.nicelog "log --all --graph --decorate --oneline"
git nicelog

git stash

# temporarily remove changes from the working directory
git stash
# restore removed changes
git stash pop

git blame

# show who made the last change in each line
git blame

git revert

# undo changes made in the last commit
git revert HEAD

The git revert command creates a new version, and does not modify the history of the repository.

git reset

# return the repository to the state after the commit with commit_id
git reset --hard <commit_id>

The git reset command modifies the history of the repository and can cause file loss.

7 Markdown Crash Course

What is Markdown?

  • Markdown is a lightweight markup language (like HTML or TeX) used to create various types of content: documents, articles, slides, web pages, …
  • Markdown is the de facto standard for documenting Git projects
  • Most Github projects have a README.md file that Github automatically renders
  • Examples of well-written README files: matiassingers/awesome-readme

Even these slides were created using Markdown! (with the help of the Quarto system)

# Markdown is Awesome

Markdown is very simple and versatile.

This is a Markdown paragraph. 
This is still the same paragraph.

## Formatting options

Bulleted list:

- *italic*
- **bold**
- ***bold and italic***
- ~~strikethrough~~
- [link](https://www.markdownguide.org/)
- `code`

Numbered list:

1. first item
2. second item
3. last item

Markdown is Awesome

Markdown is very simple and versatile.

This is a Markdown paragraph. This is still the same paragraph.

Formatting options

Bulleted list:

  • italic
  • bold
  • bold and italic
  • strikethrough
  • link
  • code

Numbered list:

  1. first item
  2. second item
  3. last item

### Code blocks

```python
def main():
    print("hello!")

if __name__ == "__main__":
    main()
```

### Images

![Queen Elizabeth II](https://upload.wikimedia.org/wikipedia/commons/1/11/Queen_Elizabeth_II_official_portrait_for_1959_tour_%28retouched%29_%28cropped%29_%283-to-4_aspect_ratio%29.jpg) 

### Blockquotes

> It’s worth remembering that it is often the small steps, not the giant leaps, that bring about the most lasting change.

Code blocks
def main():
    print("hello!")

if __name__ == "__main__":
    main()
Images

Blockquotes

It’s worth remembering that it is often the small steps, not the giant leaps, that bring about the most lasting change.

Git Glossary

en sk
branch vetva
clone naklonovanie repozitára
commit záznam
commit message popis záznamu
conflict konflikt medzi verziami
conflict resolution riešenie konfliktov
diff rozdiel medzi verziami
merge zlúčenie vetiev
en sk
pull stiahnutie vzdialených zmien
push odoslanie lokálnych zmien
repository repozitár, úložisko
remote vzdialený repozitár
snapshot snímka
staging area prípravná oblasť (tiež index)
status stav repozitára
version verzia

Git Cheatsheet

# Setup
git config --global user.name "[first last]"
git config --global user.email "[valid-email]"
git init
git clone [url]
# Stage & Snapshot
git status
git add [file]
git reset [file]
git diff
git diff --staged
git commit -m "[descriptive message]"
# Branch & Merge
git branch
git branch [branch-name]
git checkout
git merge [branch]
git log
# Share & Update
git remote add [alias] [url]
git fetch [alias]
git merge [alias]/[branch]
git push [alias]/[branch]
git pull

Thanks for your attention! 👋