Session 1: Alice starts with a private repository
Why is Alice using a version control system:
- It is easy to manage a few files. But for 100 files and more, she needs tool support.
- She finds web up- and download clumsy. If the file is on the web, then it is not there where she needs it for work: on her local file system
- For files used in collaboration, she wants to know who made the change, when, and for what purpose.
Why is Alice using Git:
- Git development was initiated by Linus Torvalds, the developer of the Linux kernel. That indicates quality.
- For about two years (or more) Open Source Software (OSS) developers seem to prefer Git and GitHub.
- She works for the ESA wonderland. The ESA Thematic Exploitation Platform (TEP) Reference Architecture and Standards recommend Git (see OSS Best Practices).
- She has a friend who has partners and clients who did not choose a common standard. He had to learn them all: ClearCase, CVS, Subversion, Git, etc.
- She knows EODC. They
push
collaboration andpull
standards from GitLab.
Alice configures her Git client: config --global|--list
Set user's global options (on Linux):
git config --global user.name "Alice from Wonderland"
git config --global user.email alice@wonderland.net
git config --global color.ui true
git config --global core.safecrlf warn
git config --global core.autocrlf input
On Windows, set core.autocrlf
to true
.
Check user's global options with: git config --global --list
Alice turns a directory into a Git repository: init, add, commit
It's just init
, add
and commit
, but to get standardization of line endings (LF), and to exclude generated files, she does a little bit more:
cd <dir> # for example `cci_sm_demo_src`
git init
git status
git add .gitattributes
git add .gitignore
git add .
git status
git commit
git checkout HEAD -- . # remove CRLF from working directory, if any
git status
git log
Here is a procedure for automatically fixing all line endings after changing core.autocrlf
option or .gitattributes
file:
git status # check status
git add . -u # Save current files, so that no work is lost
git commit -m "Save files before refreshing line endings."
git rm --cached -r . # remove every file from index (cache, staging area)
git reset --hard # rewrite index to pick up all new line endings
git add . # add changed files back
git commit -m "Normalize all line endings."
Alice edits files: status, diff, add, commit, log
vi <file>
git status
git diff
git add <file>
git diff --cached
git status
git commit
git status
git log
git log --oneline
git log --name-status
git log -p
Move and remove files or directories: mv, rm
git mv <old_path> <new_path>
git rm <path>
Commit options: -m, -a, --amend
git commit -m "<message>"
git commit -a # skip `git add` and commit all changes
git commit --amend # DO before pushing, DON'T after pushing
Alice knows how to discard undesired changes: reset, checkout, revert
Fix cache (aka index, staging area), then working directory:
git reset HEAD <file> # resets index, keeps changes in working directory
git checkout -- <file> # discards changes from working directory
Restore working directory after things got messed up entirely:
git reset --hard HEAD
git reset --hard <commit> # DO before pushing, DON'T after pushing
Compensate a bad commit (can be done any time):
git revert <commit>
Session 2: Bob joins Alice to work together
[bob@sidp ~]$ git config --global --list
user.name=Bob the Builder
user.email=bob@builders.com
color.ui=true
core.safecrlf=warn
core.autocrlf=input
Bob gets a copy of Alice's repository: clone, remote, branch
cd ~/repositories
git clone --origin alice ~alice/repositories/cci_cm_demo_src
git branch # view local branches
git branch -r # view remote tracking branches
git branch -a # view all branches
Bob retrieves changes made by Alice: fetch, pull
git fetch alice # updates remote tracking branches only
git pull # merge changes into active local branch
Alice integrates changes made by Bob: remote add, remote show
Alice adds a remote alias to Bob's repository:
git remote add bob ~bob/repositories/cci_cm_demo_src
git remote -v
git remote show bob
Alice can pull in Bob's changes any time as follows:
git fetch bob # update remote-tracking branches
git pull bob master # merge `bob/master` into active local branch
Session 3: Alice & Bob use a Git server
Reasons:
- Repositories by Alice and Bob may not always be available.
- Complex topology if more friends join.
- A maintained server has 24/7 availability and simple topology.
- Even with a central server, each collaborator keeps the full history and does not depend on the server (they can work off-line). The architecture is fully distributed, explaining why Git is called a Distributed Version Control System (DVCS).
Alice and Bob setup their ssh keys: ssh-keygen
Alice does this (and so does Bob):
- Get account on a Git server, for example EODC's GitLab.
- Create an ssh public+private key pair with
ssh-keygen
. - Upload public key onto Git server.
- Load private key into a local ssh agent.
Alice creates an empty repository on the Git server
Alice logs on to EODC GitLab (https://git.eodc.eu), navigates to a GitLab group of her choice, and presses the New project button.
She puts in the repository name (e.g. cci_cm_demo_src
), a brief
description, and chooses verbosity level private
.
Alice puts her repository onto the Git server: remote, push
git remote add eodc git@git.eodc.eu:cci-sm-work/cci_cm_demo_src.git
git remote show eodc
git push -u eodc master:master # semantics: <local_branch>:<remote_branch>
git branch -a
The -u (--set-upstream) flag adds an upstream (tracking) reference, which is used by argument-less "git pull" and other commands.
Bob clones from the Git server: --origin
git clone --origin eodc git@git.eodc.eu:cci-sm-work/cci_cm_demo_src.git
Remote alias origin
will be used if --origin flag is not given.
Session 4: Alice & Bob become Git experts by branching and merging
Alice & Bob define the branching policy
Here is a branching policy for a data centre:
(L3) Temporary branches for hot fixes: '<issue>_hotfix'
(L2) Permanent branch for operations system: 'ops'
(L1) Permanent branch for test system: 'tst'
(L0) Permanent branch for development: 'master'
(L-1) Temporary branches for feature implementation: '<feature>_impl'
Merging from upper to lower level is a safe action and can be done frequently. Merging from lower to upper level must be done with care and is considered a "delivery".
Alice creates the permanent branches: checkout -b, checkout, gitk, push -u
Branch master
doesn't need to be created. It is created by Git and
always there.
Create local branches (use -b flag):
git checkout -b tst # starting from HEAD
git checkout -b ops <start_point> # starting from start_point (e.g. commit)
Switch between branches:
git status # always make sure to have a clean working directory!
git checkout <branch>
Add commits to each branch, then use the graphical repository browser
for the inspection (may sometimes be more convenient than git log
and git diff
):
gitk &
Push branches to Git server (use -u flag):
git push -u <remote> <local_branch>:<remote_branch>
git push -u eodc tst:tst
git push -u eodc ops:ops
Bob gets the new remote branches: checkout -t
git fetch eodc # update remote tracking branches
git branch -a # view list of branches
git checkout -t eodc/tst # use -t to set up "upstream" configuration
git checkout -t eodc/ops
Bob delivers work on a feature branch: checkout -b, push -u, merge request
git checkout master
git checkout -b <feature>_impl
He does some work, then stages and commits it:
git add <file>...
git commit
git push -u eodc <feature>_impl:<feature>_impl
Finally, Bob submits a merge request to Alice (talk, send an email, or press GitLab's New Merge Request button).
Alice integrates Bob's changes: merge, tag, branch -d
git fetch eodc
git checkout -t eodc/<feature>_impl
Alice can and should inspect the changes made by Bob. She talks to him in case of disagreement.
Alice merges feature branch into master:
git checkout master
git merge --no-commit <feature>_impl # Don't abuse --no-commit!
git status
git diff
In case of conflicts, Alice resolves them. She also has the option to abort the merge. See the sections on conflict resolution and aborting below.
If everything OK, Alice commits and tags:
git commit
git tag -a -m "DCR-001: Feature XYZ" DCR-001-0
Alice pushes to Git server and removes obsolete feature branch:
git push eodc master
git branch -d <feature>_impl # delete local branch
git push eodc :<feature>_impl # delete remote branch
Alice notifies Bob about integration action.
Bob verifies integration: fetch --prune
git fetch eodc # fetch is additive, it doesn't delete branches
git fetch --prune eodc # prune obsolete remote tracking branches
git checkout master
git pull
gitk &
git branch -d <feature>_impl
Alice's options for conflict resolution: checkout --ours|--theirs|-m, add
When a git merge
reports about conflicts:
- Look at the diffs:
git diff
will show a three-way diff, highlighting changes from both the HEAD and MERGE_HEAD versions. - Look at the diffs from each branch:
git log --merge -p <path>
will show diffs first for the HEAD version and then the MERGE_HEAD version. - Look at the originals:
git show :1:filename
shows the common ancestor,git show :2:filename
shows the HEAD version, andgit show :3:filename
shows the MERGE_HEAD version.
Alice can use the following commands in order to resolve conflicts:
git checkout --ours -- <file>
git checkout --theirs -- <file>
git checkout -m -- <file> # gets conflicts back
vi <file> # find conflict markers and fix things
git add <file> # mark conflict as resolved.
git commit
Alice's options for aborting a failed merge: merge --abort, reset --hard, revert -m 1
If things go entirely wrong, the merge can be aborted before committing by one of the following commands:
git merge --abort # requires a newer Git version
git reset --hard HEAD
Revert the merge after committing but before pushing as follows:
git reset --hard HEAD^
Revert the merge after pushing as follows:
git revert -m 1 <commit>
Session 5: Getting help and support
- README_GIT.md in repository
cci_cm_work_doc
. - Tutorials and cheatsheets on the Internet.
- Git manual pages:
git help
- EODC User Support and Configuration Management: A job for Bob.
- Git homepage
- Git book
- GitLab