
| Git | GitHub |
|---|---|
| Software | Service |
| command line tool | GUI |
| installed locally | hosted on the web |
| VCS to mange source code history | hosting service for GIT repositories |
GitHub uses Git as central tool for its service
The history in Git is formed from the commit objects and creates a directed acyclic graph

Each developer has its own full repository
Advantage: No network connection needed for commits.
Checkins in local repository also work if production branch is broken.

Recommended sequence: commit → pull → push
git init
| Project directory | .git directory |
|---|---|
![]() |
![]() |
| contains .git directory and current checked out data | HEAD is a reference to the checked out commit |
| TFS | Git |
|---|---|
| Centralised VCS | Distributed VCS |
| branches are folders in TFS folder hierarchy | private local branches possible |
Git is recommended over TFS by Microsoft itself for new projects!
When history is not needed in Git:
git init
When history is not needed in Git: http://git-tfs.com/
git tfs clone ...
git-tfs works as two-way bridge so changes can also be pushed to TFS
git tfs checkintool
Plan your migration carefully:
cleanup before migration: e.g. large file → NuGet-Packages
for big projects multiple Git-Repositories could be created and included via Submodule/Subtree
can be local for git-repository within .git/config
can be global via global flag git config --global ...
can be accessed via git config --list
Typical settings:
git config --global core.editor "code --wait"git config --global user.name "John Doe"git config --global user.email johndoe@example.comgit config --global merge.tool kdiff3git config --global credential.helper cache.gitignore-File specifies files that Git should ignore
files already track are not affected!
each line in .gitignore specifies a pattern
Creating a new branch: git branch <branchname>
branches are very lightweight in Git: You can have many and switch very fast.
list branches:
git branch** or **git branch -v
add option to filter branches (not) merged into the branch you are currently on:
--merged
--no-merged
rename branch:
git branch --move bad-branch-name corrected-branch-name
git push --set-upstream origin corrected-branch-name
git push origin --delete bad-branch-name



Git-Flow
Github-Flow
Gitlab-Flow
Trunk-Based Development

Pros
Cons

Pros
Cons

Pros
Cons
The GitLab Flow is based on 11 rules:

Pros
Cons
Trunk-Based-Development is recommended in this book

| release method | Team | Collaboration | Workflow |
|---|---|---|---|
| all | Small | High | TBD |
| CI/CD: SaaS | Middle | Moderate | GitHub-Flow, TBD |
| fixed+periodic: iOS | Middle | Moderate | Git-Flow, GitLab-Flow |
| quality + CI/CD: platform product | Middle | Moderate | GitLab-Flow |
| quality + long maintenance: platform product | Large | Moderate | Git-Flow |
“Remote repositories are versions of your project hosted on Internet or network somewhere”
to list the current remotes you can use git remote -v
a remote can be inspected with git remote show origin
remotes can be added with git remote add pb <e.g. some github-repo-url>
to remove a remote use git remote remove <remote-name>
on a cloned repo the origin is already set
fetching from a remote: git fetch
pulling (combination of git fetch and git merge) from a remote: git pull
pushing to a remote: git push origin master
“Generate a request asking your upstream project to pull changes into their tree.”
Push: git push https://git.ko.xz/project master
vs.
Pull-Request: git request-pull v1.0 https://git.ko.xz/project master
all: git log --decorate --graph --oneline --all
by amount: git log -3
by date: git log --after="2014-7-1"
by author: git log --author="John"
by message: git log --grep="JRA-224:"
by file: git log -- foo.py bar.py
by content: git log -S"Hello, World!"
by range: git log main..feature
by merges: git log --merges git log --no-merges
git tag -a v1.9 -m "my version 1.9"git tag git tag -l "v1.8.5*"git show v1.9git tag -a v1.9 9fceb02git push origin v1.9 git push origin --tagsgit tag -d v1.9git checkout v1.9 be aware of detached HEAD!“Can simplify your Git-experience by settig custom aliases that are easier/shorter”
git config --global alias.unstage 'reset HEAD --'
→
git unstage fileA instead of git reset HEAD -- fileA
“A git submodule is a record within a host git repository that points to a specific commit in another external repository.”
git submodule add https://bitbucket.org/somerepo/awesomelibrary
Submodules do not track git refs or branches and are not automatically updated when the host repository is updated
If you need to maintain a strict version management over your external dependencies, it can make sense to use git submodules

Pros
Cons
If not specified explicitly Git will automatically choose a strategy based on the branches provided for merging
git rebase

git merge --no-ff

git merge -s ours

git merge -s octopus

git merge -s resolve

git merge -s subtree

open merge tool defined in git-config (e.g. meld):
git mergetool
open diff tool defined in git-config:
git diff Commit1sha Commit2sha
Easiest way to merge one branch into another
non destructive: does not change existing branches
a lot of merge commits if main branch changes often
no unneccessary merge commits (e.g. by squashing) → history easy readable
Readability, but less secure and trackable
Context lost → hard to see wenn upstream-changes are integrated into feature
Cherry picking can cause duplicate commits → often merges are better
Usage: git cherry-pick commitSha
Use cases for Cherry-Picking:
Team Collaboration: backend creates data-structure and frontend-dev cherry-picks it
Bug-Fixing: hotfix can be cherry-picked to main branch before it affects more users
From local repository:
git reset --soft HEADgit reset --hard HEADgit restore --staged <filename>git restore <filename>From public repository:
git revert HEAD git commit -m "reverted last commit"
add additional files to your previous commit
git commit --amend
by signing you can verify that commits are actually from a trusted source
Setup:
gpg --gen-key
gpg --list-keys
git config --global user.signingkey <signingkey>
add -s to your commit command: git commit -a -S -m 'Signed commit'
use -s instead of -a for tags: git tag -s v1.5 -m 'my signed 1.5 tag'
Switching branches without commiting unfinished work:
git stash
git stash list
git stash apply
New branch from stash:
git stash branch testchanges
Clean working dir without stashing:
git clean
get File annotations:
git blame -L 3,5 <somefilename>
git bisect (helps identifiying last good commit):
git bisect start
git bisect bad
git bisect good <good_commit>
git bisect reset
find strings/regex in your files:
git grep -n <search-text>
Git hooks are scripts that run automatically every time a particular event occurs in a Git repository. They let you customize Git’s internal behavior and trigger customizable actions at key points in the development life cycle.
Enforcing Policies: Pre-Rebase-Hook to disallow rebasing
#!/bin/sh
# Disallow all rebasing
echo "pre-rebase: Rebasing is dangerous. Don't do it."
exit 1
Other use cases:
Worth a look: Husky.NET
Very long accumulated history:
shallow clone: git clone --depth [depth] [remote-url]
clone only branch: git clone [remote url] --branch [branch_name] --single-branch [folder]
Huge binary assets that need to be tracked together with code:
Rerere: “reuse recorded resolution”
git config --global rerere.enabled true
Bundling: Useful when offline. Bundles data that would be pushed → send by mail → unbundle
git bundle create repo.bundle HEAD master
git clone repo.bundle repo
Attributes: Can be used to diff binary files by modifying .gitattributes
*.png diff=exif
git config diff.exif.textconv exiftool
GitOps is code-based infrastructure and operational procedures that rely on Git as a source control system
GitOps ensures that a cloud infrastructure is immediately reproducible based on the state of a Git repository. Pull requests modify the state of the Git repository. Once approved and merged, the pull requests will automatically reconfigure and sync the live infrastructure to the state of the repository. This live syncing pull request workflow is the core essence of GitOps
To achieve a full GitOps install, a pipeline platform is required, e.g.:
