version control system
mainly helps with two categories of tasks:
In git a commit is a snapshot of a codebase
The evolution of a codebase is represented by a sequence / tree of commits
Sometimes the term commit also refers to the transition / change from one snapshot to the next
simple commit log with one branch (main):
* add footer (main)
* add company logo
* add sidebar
* add placeholder content
* initialize website
branches allow development to happen on different tasks in parallel
The default branch is usually called main or master
In git a branch is a pointer to a specific commit
commit log with one active feature branch:
* add sidebar (main)
| * correct typo in footer (footer)
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website
combining branches (via merge):
* merge branch 'footer' into main (main)
|\
| * correct typo in footer (footer)
| * add logo to footer
| * add footer with basic content
* | add sidebar
|/
* add placeholder content
* initialize website
combining branches (via rebase and squash):
* add footer (main)
* add sidebar
* add placeholder content
* initialize website
Install from https://git-scm.com
recommendations:
select components: uncheck Windows Explorer integration (this would add new entries in the right-click menu of the explorer)
default editor: choose Nano as a simple console based text editor
name of the initial branch: choose "main"
line ending conversions: Checkout as-is, commit as-is - and set up your development environment to use LF
default behavior of git pull: only ever fast-forward
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
git config --global pull.ff true
git init
git clone
creating a new repository in a local folder:
git init
cloning a public repository (from GitHub):
git clone https://github.com/libgit2/libgit2
creates a new folder libgit2 with the current state and all of the history
git status
git diff
git add
git restore
git commit
git status
prints information about the current state of the repository
view status of files (added / changed / deleted since last commit):
git status
view added / removed lines in files:
git diff
preparing all changed / added / removed HTML files for committing (staging files):
git add *.html
preparing all files:
git add .
unstaging previously staged files:
git restore --staged readme.txt
discarding unstaged changes:
git restore readme.txt
making a commit of everything that has changed and providing a commit message:
git add .
git commit -m "changing some HTML files"
compact version for staging and committing all changes:
git commit -a -m "changing some HTML files"
We can list files to ignore in a special text file called .gitignore
(without a filename extension):
__pycache__
node_modules
.vscode
git log
git show
git diff
git checkout
git revert
list past commits:
git log
git log --oneline
git log --oneline --graph
git log --oneline --graph --all
example output of the second command:
* e84890f (HEAD -> main, origin/main, origin/HEAD) add footer
* 9eb2f53 add company logo
* 5c41c01 add sidebar
* f4f591c add placeholder content
* d6510c2 initialize website
view changes between 19e0e64... and its parent commit:
git show 19e0
view changes between 19e0e64... and the current state:
git diff 19e0
short output:
git diff 19e0 --name-status
accessing the contents of an earlier commit (whose id is b4c906...):
git checkout . b4c9
going back to the most recent commit of the main branch:
git switch main
reverting the latest commit (via a new commit):
git revert HEAD
workflow:
To introduce a new feature / change, create a new so-called feature branch
The feature branch can individually evolve in parallel to the main branch
If the main branch evolves, its changes can be combined / merged back into the feature branch
Once the feature is complete, it can be combined / merged back into the main branch (after being reviewed by other developers)
often feature branches can be small, e.g. fix-spelling-error-in-readme
some feature branches must be big, e.g. port-to-typescript
after being combined / merged back into the main branch, feature branches are usually deleted
example: developers are working on two different tasks at the same time:
* add sidebar (sidebar)
| * add logo to footer (footer)
| * add footer with basic content
|/
* add placeholder content (main)
* initialize website
when a feature is completed it can be combined / merged back into the main branch:
* merge branches (main)
|\
* | add sidebar
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website
old feature branches are usually deleted
during development:
when the feature is ready:
git branch foo
git branch foo $commitid
git switch foo
git switch -c bar
git switch -c bar $commitid
git branch
git branch python-3-port
Switching between python-3-port and main:
git switch python-3-port
git switch main
before switching it can be useful to make sure there are no active changes
git status
git switch main
git switch -c python-3-port
create and switch to a new branch
listing all (local) branches:
git branch
strategies:
example commit history (during feature development):
* merge branches (footer)
/|
* | add company logo (main)
| * add copyright notice to footer
| * merge branch 'main' into 'footer'
|/|
* | add sidebar
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website
example commit history (when feature is complete):
* merge branches (main)
|\
* | add company logo
| * add copyright notice to footer
| * merge branch 'main' into 'footer'
|/|
* | add sidebar
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website
commands for merging changes of main into footer:
git switch footer
git merge main
if two branches changed the same line in different ways there may be a merge conflict
presentation of a merge conflict in a file:
First line
Second line
<<<<<< HEAD
Thrd line!
======
Third line
>>>>>> main
Fourth line
one branch added an exclamation mark, another one fixed a spelling error
git commit
(without extra arguments)we will usually delete a branch once it is merged:
deleting a merged branch:
git branch -d footer
deleting an unmerged branch:
git branch -D footer
create a text file with some todos:
- groceries
- taxes
x gardening
modify the todo list via separate feature branches, e.g. "long-term todos", "new-job", "new-job-sub-items", "taxes-completed", ...
Hosts for Git:
initial options:
git clone https://github.com/...
On GitHub, copy the link from the green clone or download button
On GitHub, click the + in the top right corner
Don't select "Initialize this repository with a README".
Once you have an empty repository on GitHub, follow the instructions for an existing repository displayed on GitHub
Usually you will connect a local repository to a single remote repository - the remote repository is conventionally named origin
git remote add origin https://github.com/...
Whenever we want to publish a branch the remote doesn't know about:
git push -u origin main
The above command copies the the commits in the local main branch to a newly created remote main branch.
If we want to publish commits to a known branch:
git push
Fetch and merge commits from the remote branch corresponding to the active branch:
git pull
deleting a local branch:
git branch -d python-3-port
deleting the remote branch as well:
git push origin :python-3-port
git config credential.helper cache
Git will now remember passwords for 15 minutes
In git it is possible to edit history - but it comes with dangers
example use cases:
rules:
original commit log:
* merge branch 'main' into 'footer' (footer)
/|
* | add company logo (main)
| * add copyright notice to footer
| * merge branch 'main' into 'footer'
|/|
* | add sidebar
| * add logo to footer
| * add footer with basic content
|/
* add placeholder content
* initialize website
new commit log:
* add footer (footer)
/
* add company logo (main)
* add sidebar
* add placeholder content
* initialize website
note: the main branch was not modified
editing history via rebase in git:
git rebase -i main
interactively edit the current branch from the point where it branched off of main
squashing commits:
change all except the first commands from pick to squash
creating some aliases:
git config --global alias.unstage 'restore --staged'
git config --global alias.show-tree 'log --graph --oneline --all'
git-extras provides simplified commands for common tasks
git ignore
git show-tree
git squash
git undo