Git tutorial


Tools: Terminal


Press 'Space' to continue

Press 'n' to show/hide notes

Press 's' for speaker mode

Benjamin Dumont

Introduction

  • Distributed SCM
  • Most popular
  • Designed for merging branches

Schema

Glossary (for local work)

  • Working directory: local directory where you work
  • Index: temporary zone enumerating all changes to save
  • Commit: change save
  • HEAD: last commit

Basic commands

via Gfycat

Init workspace from remote repository

                     
git clone https://repository_url # https
...
git clone user@repository_url # ssh
                     
                  

Adding files to staging

                     
git add path/to/file1 path/to/file2
...
git add .
                     
                  

Check the local git status

                     
git status
                     
                  

Committing to local repository

                     
git commit
...
git commit -m "my commit message"
                     
                  

Identifying a commit

Identified by a sha1 (e.g.: 3241a3db7c76e29b63c0b1ea116b6db0f8619fdc)

Exercise

  • Clone repository (you should be on develop branch)
  • Create a file with your username as filename
  • Commit it
  • Write the datetime in the file
  • Commit it

Sending data to the remote repository

                     
git push origin your_branch_name
                     
                  

Getting data from the remote repository

                     
git pull origin your_branch_name
                     
                  

Exercise

Push the file previously created on the develop branch

Managing branches

Creating branch locally

                     
git checkout -b new_branch # deprecated
...
git switch -c new_branch
                     
                  

Switching branch

                     
git checkout branch2 # deprecated
...
git switch branch2
                     
                  

Merging branches

                     
git merge branch2 # will merge branch2 into the current branch
                     
                  

Merging flowchart

%%{ init: { 'theme': 'base', 'themeVariables': { 'commitLabelColor': '#ff0000', 'commitLabelFontSize': '30px' }, 'gitGraph': { 'showBranches': true, 'showCommitLabel':true, 'mainBranchName': 'develop' } } }%% gitGraph commit id: "A" commit id: "B" branch my_feature commit id: "Alpha" commit id: "Beta" checkout develop commit id: "C" merge my_feature

Show current branch history

                     
git log
...
git log --decorate --oneline --graph
                     
                  

Updating local repository information from remote

                     
git fetch
                     
                  

Conflicts

                     
<<<<<<< HEAD:index.html
contact : email.support@github.com
======
 please contact us at support@github.com
>>>>>>> iss53:index.html
                     
                  

You have to solve it manually, then commit the change

Git flow

Common branches

  • master/main: production
  • develop: most up to date branch
  • release: pre-production branch, waiting for tester approval

Personal branches

  • All other branches
  • Temporary
  • Should be deleted when merged

Flowchart

%%{ init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': { 'showBranches': true, 'showCommitLabel':false, 'mainBranchName': 'main' } } }%% gitGraph commit tag: "1.0.0" branch hotfix order: 1 branch develop order: 3 checkout develop commit branch my_feature order: 4 commit commit checkout hotfix commit checkout main merge hotfix tag:"1.0.1" checkout develop merge hotfix checkout develop merge my_feature branch release/1.1.0 order: 2 commit commit checkout main merge release/1.1.0 tag: "1.1.0" checkout develop merge release/1.1.0

Tag

  • Identifies a commit by a version (X.Y.Z)
  • MUST be on a reference branch
  • Should be on main/master

Tag flowchart

%%{ init: { 'theme': 'base', 'themeVariables': { 'commitLabelColor': '#ff0000', 'commitLabelFontSize': '30px' }, 'gitGraph': { 'showBranches': true, 'showCommitLabel':true, 'mainBranchName': 'main' } } }%% gitGraph commit id: "Initial" branch develop commit id: "A" branch my_feature commit id: "B" commit id: "C" checkout develop merge my_feature checkout main merge develop tag: "1.0.0"
                     
git tag -a 1.0.0 -m "my comment"
                     
                  

Undo (local)

Undo all changes

                     
git reset --hard HEAD
                     
                  

Remove from index

                     
git reset
...
git reset --mixed
                     
                  

Restore file from HEAD

                     
git checkout myfile.txt # deprecated
...
git restore myfile.txt
                     
                  

Rewrite history

We will see it the next section

Save changes into a temporary stack and remove them

                     
git stash # Save changes into a temporary stack and remove them
git stash pop # restore changes from stash
                     
                  

Rewrite history

Warning

Rewriting history must be done only on personal branches

Add files from index into the last commit

                     
git commit --amend
                     
                  

Shift history / Context

  1. I need to work on a new feature
  2. I create a branch "feature" from develop
  3. Someone merged some code into develop
  4. I need the new code on develop for my feature

Shift history / Actions

  • Merge action: will create a merged commit into my feature branch
  • Rebase action: will put all the new commits from develop before commits on personal branch

Rebase Flowchart

%%{ init: { 'theme': 'base', 'themeVariables': { 'commitLabelColor': '#ff0000', 'commitLabelFontSize': '30px' }, 'gitGraph': { 'showBranches': true, 'showCommitLabel':true, 'mainBranchName': 'develop' } } }%% gitGraph commit id: "A" commit id: "B" commit id: "C" branch my_feature commit id: "F" commit id: "G" checkout develop commit id: "D" commit id: "E"

%%{ init: { 'theme': 'base', 'themeVariables': { 'commitLabelColor': '#ff0000', 'commitLabelFontSize': '30px' }, 'gitGraph': { 'showBranches': true, 'showCommitLabel':true, 'mainBranchName': 'develop' } } }%% gitGraph commit id: "A" commit id: "B" commit id: "C" commit id: "D" commit id: "E" branch my_feature commit id: "F'" commit id: "G'"

Shift history / Rebase

                     
git rebase develop
                     
                  

Shift history / Rebase with conflicts

Solve conflicts, then :

                     
git add my-file-with-conflicts-resolved.txt
git rebase --continue
                     
                  

Merge vs Rebase 1/2

Merge is easier to use to deal with conflicts, since we treat all of them inside the same commit, contrary to rebase. Rebase will apply each commit, so you may need to solve conflicts for each commit.

Merge vs Rebase 2/2

Merge will create a merged commit. It makes some sense when you want to put your code into develop. It makes no sense when you want to update your personal branch from develop

Merge vs Rebase Summary

  • Merge: destination branch is a common branch
  • Rebase: destination branch is a personal branch

Interactiv Rebase 1/4

On your personal branch, you may want to:

  • Change a commit message
  • Remove a commit
  • Merge some commits into only one commit
  • Reorder commits

Interactiv Rebase 2/4

Identify the start commit from which you want to rewrite history

                     
git log
# Identify the sha1 (excluded)
                     
                  

Interactiv Rebase 3/4

                     
git rebase -i my_sha1
                     
                  

Interactiv Rebase 4/4

                     
pick b6c57be commit message 1
pick 53c836a commit message 2
pick e2130ac commit message 3

# Rebase 4d32053..e2130ac onto 4d32053 (3 commands)
#
# Commands:
# p, pick  = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
                     
                  

Push a rewritten history

%%{ init: { 'theme': 'base', 'themeVariables': { 'commitLabelColor': '#ff0000', 'commitLabelFontSize': '16px', 'commitLabelFontSize': '30px' }, 'gitGraph': { 'showBranches': true, 'showCommitLabel':true, 'mainBranchName': 'develop' } } }%% gitGraph commit id: "A" commit id: "B" commit id: "C" commit id: "D" commit id: "E" branch my_feature commit id: "F'" commit id: "G'"
                     
# If remote doen't have F and G
git push origin personal_branch
# Else, push force
git push -f origin personal_branch
                     
                  

Exercise

  1. On your personal branch, create 3 commits (change the data in the file)
  2. Push it
  3. Change the commit message of your 1rst commit, merge the 2nd and 3rd commits
  4. Push

Pull requests

Aim

  • Show your code to other developers
  • Request for reviews
  • Request for changes
  • Merge your personal branch to a reference one

Aim (advanced)

  • Run tests
  • Detect code coverage
  • Generate documentation
  • Define breaker rules for merging
  • ...

Create a pull request

Select the branches (from, to)

PR informations

Comment

Review

Merge

Exercise

  1. Update your working directory with the lastest develop
  2. Create a personal branch
  3. Wait
  4. Modify file.txt and put your name and datetime instead of its content
  5. Create a pull request
  6. Wait for approval
  7. Merge

Best practice

Commit message

Normalize your message commit (use a reference or create a new one for all developers)

Angular Reference

Avoid merge

Avoid manual merge. Use Pull Request for merging.

Forbid Push on Reference Branch

You must not be able to push directly into develop/main/master/release branch. Use a Pull request instead.

Avoid ByPassing a Pull Request

Use pull request to show your code and wait for reviewers or comments before merging.

Personal branches

Only work on your personal branches. Your personal branches must not be based on otherone personal branch.

Parallel reference branches

Avoid parallel reference branches. You should only have at a time:

  • develop
  • main/master
  • ONLY ONE release

Rewritting history

When you rewrite the history, force push as soon as possible to avoid an error telling you to pull the repository (which will lead to unexpected commits)

Other stuff

Ignore some files

You can ignore some files by using a .gitignore file in root folder or sub folders

                     
## Example
*.ipa
*.dSYM.zip
*.dSYM                     
                  

You can generate .gitignore file using gitignore.io

Graphical clients

  • SourceTree
  • GitKraken

Graphical client (terminal)

oh-my-zsh (can be installed with homebrew)

Git and IT projects

Kanban

Product Owner Tester Developer

Backlog

To do list. Must be filled with the PO/BA, Tester and developer during the example mapping to move to "In Progress" status

Lifetime: from minutes to eternity

Product Owner Tester Developer

In progress

Developer create a branch (e.g.: feature/3 where 3 is the ID of the ticket). He develops the content of the ticket and create a pull request. Merging PR will change the status to "Done"



Lifetime: from minutes to days
Developer

Done

Code is merged. Tester can test it (on pair testing or on a staging environment if code has been deployed)



Lifetime: from minutes to hours on pair testing, from hours to weeks on staging environment
Tester Developer (if pair tests)

Tested

Code is tested. The ticket is waiting for deploying a released version



Lifetime: weeks
Tester (if there is a global test phase) Developer

Delivered

Released on production or pre-production



Lifetime: eternity

Concerning Git

  • Used in the development phase (personal branches) and delivery phase (develop branch for staging, release branch for pre-delivery and master/main branch for delivery)
  • Personal branches should have the shortest lifetime possible
  • When merged, personal branches should be deleted (at least on remote)
  • For lifetime reason, tickets may have to be splitted

Github: benjdum59
Website: benjdum59.github.io
Mail: benjamin.dumont.pro@gmail.com

Go to Homepage