Why you should use git

—and how it can be used


By Christopher Körber

This tutorial follows the guide available on atlassian.com


Press "?" for navigation clues

What is git?

A sophisticated save button

By far, the most widely used modern version control system in the world today

  • A modern Version Control System (VCS)
    Think of it as an sophisticated save button which saves the whole history of files
  • A Distributed Version Control System (DVCS)
    Every copy of the "source directory" is a complete repository containing the full history (different to, e.g., SVN)
  • Secure, system-independent, well maintained and fast freeware
    It focusses on the contents of files and compares differences and transmits encoded and compressed information

You should use git if...

...you want to reconstruct changes

Image taken from openclipart.org

Git guarantees accurate code reproducibility at any stage

...you are tired of folders containing importantPaper_v27.tex

"Classical version control" "Git version control" (single file)
  • DM_2H3He_draft_final_J.tex
  • DM_2H3He_draft_old.tex
  • DM_2H3He_draft_v2.tex
  • DM_2H3He_draft_v3.tex
  • DM_2H3He_draft_v4.tex
  • DM_2H3He_draft_v5.tex
  • DM_2H3He_draft_v6.tex
  • DM_2H3He_draft_v7.tex
  • DM_2H3He_draft_v8.tex
  • DM_2H3He_draft_v9.tex
  • DM_2H3He_draft_v10.tex
  • DM_2H3He_draft_v11.tex
  • DM_2H3He_draft_v12.tex
  • DM_2H3He_draft_v13.tex
  • DM_2H3He_draft_v14.tex
  • DM_2H3He_draft_v15.tex
[2017-09-01 08:16] CK: slightly modified Toms addition
[2017-08-31 15:15] TL: Added an extra line in the...
[2017-08-31 07:17] TL: Moved paper to EPL format, where...
[2017-06-29 12:08] CK: Added A. Rokash to acknowledgements and...
[2017-06-29 11:08] TL: Modified caption to figure ...
[2017-06-29 11:04] TL: updated data for pure repulsive...
[2017-06-27 10:09] CK: Prepared the upload: Fixed...
[2017-06-26 22:48] TL: Added acknowledgements section...
[2017-06-26 13:58] CK: Added proceedings folder
[2017-06-21 18:32] CK: Finalized presentation
[2017-06-21 12:05] CK: Included further backup slides
[2017-06-20 17:57] CK: top and tui in gitignore
[2017-06-20 17:56] CK: Arxiv folder
[2017-06-20 17:56] CK: Coefficient check nb
[2017-06-20 16:25] CK: Adjusted figure caption
[2017-06-20 16:13] EB: Remove promise of c_j coefficients.
[2017-06-20 15:58] CK: Changed lambda numbers in paper

Git keeps file structures clean and easy to review

...want to collaborate with others

\begin{align}
-    N&=1        & P_1[\phi] &= \exp\left(-\sum_{i\in\{0,1\}}\phi_i^2\right)   \\
+    N&=1        & P_1[\phi] &= \exp\left(-\sum_i\phi_i^2\right)   \\
     N&=\infty   & P_\infty[\phi] &= \begin{cases}
-        1 & |\phi_i| < 1 \, \forall i\in\{0,1\} \\
+        1 & |\phi_i| < 1  \\
         0 & \text{otherwise}
         \end{cases}.
 \end{align}
@@ -354,18 +354,19 @@ The case $N=1$ corresponds to the gaussian distribution of the original Hubbard-...
 As our trial wavefunction for multifermion systems $|\Psi_T\rangle$ we pick a direct product state...
 The direct product structure allows us to write the functional $\K$ in \eqref{eqn:Z} as
 \begin{equation}
-    \K[\tau,\phi,c_j,\Psi_T]=\left(K^{-1}[\tau;\phi,c_j]\right)^\alpha
+    \K[\tau,\phi,c_j,\Psi_T]=\left(K^{-1}[\tau,\phi,c_j]\right)^\alpha
 \end{equation}
Difftools for git

Git makes it easy to visualize modifications

...want a reliable backup system


You can use remote machines to synchronise data

Do not look for excuses

"I am not a programmer, I don't need git"

LaTeX is code as well...

"My collaborators will not use git"

15 minutes learning git can save days!

"I will never understand this..."

Routine usage only needs a few intuitive commands.

Acceptable excuse:"I am the only one using this file which will not change."

Basic Course

—About saving files, inspecting histories & collaborating

"Someone wants me to use git..."

Content of the basic course

This presentation will show you

  1. how to set up git
  2. how to "save" files and track modifications
  3. how to inspect the repository
  4. how to collaborate with others

Also, you will gain

The target group are...

...users not familiar or starting to learn git

Installing git

Git is a well known, documented and well maintained tool and used in about any development community. There is a high chance that you already have git installed. Make sure you have the most current version.

  1. Open your terminal
  2. Check if you have (the most current version of) git
    $ git --version
    • In the following context $ {command} denotes that the {command} following $ is executed in the terminal. Lines within a code box but without a trailing $ correspond to output.
    • If this prints something like git version 2.xx.y with xx >= 16, you have a relatively current version.
      If you get a command not found, you do not have git.
  3. Install (or update) git
    OS Tool command
    macOS MacPorts sudo port install git +bash_completion+credential_osxkeychain+doc
    macOS Homebrew brew install git
    Debian/Ubuntu apt-get sudo apt-get install git

    The pattern is always the same. If you are unsure, also see the git download page .

Setting up git

Since you eventually want to collaborate, you should let git know who you are.

Globally define your name

$ git config --global user.name "{My Name}"

Globally define your email

$ git config --global user.email "{my@email.address}"
  • All repository you will create or join know these information.
  • This needs to be done just once.
  • Git gives more possibilites for customization.

Initializing a repository

There are multiple ways for initializing a repository. The next slides will walk you through the basic procedure.

Creating an empty git repository

Navigate to the folder which will become the repository. In this example, it will be the directory ~/myProject.

$ git init myProject
Initialized empty Git repository in ~/myProject/.git/

This initializes the repository and only creates the folder ~/myProject/.git/ (you do not have to care about).

$ ls -a myProject/
. .. .git
  • git init {folder} can be used on non-empty folders

    It simplies places the .git/ directory into this folder

  • You can treat this folder like a regular folder
  • Git watches everything contained in this folder (also subfolders)
  • You can create storage-only or clone existing repos

Untracked files

git status

Let us start by adding an empty Readme.md file to the repo

$ cd myProject
$ touch Readme.md

Now, there is an untracked file in the repository.

$ git status
On branch master

No commits yet

Untracked files:
  (use "git add {file} .." to include in what will be committed)

  Readme.md

nothing added to commit but untracked files present (use "git add" to track)

The branch you are working on. This is not important for now

Nothing to compare against.

What git suggests to do.

Staged files

git add

To add the previously created Readme.md file, one has to execute

$ git add Readme.md

The file is now staged but not yet "saved"

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached {file}..." to unstage)

	new file:   Readme.md

File is now staged. It can now be committed or unstaged again.

It tells Git that you want to include updates to a particular file in the next commit. However, git add doesn't really affect the repository in any significant way—changes are not actually recorded until you run git commit

This is useful when you work with several files at once. See slide below for an example.


Why not directly saving a file?

Suppose you have two files, File A and File B, where File B depends on File A.

  1. You adjust File A until you are satisfied. In principle you could save File A, however File B wouldn't work anymore.
  2. Because you do not want to "save" a not entirely working snapshot of your repo,
    you only git add "File A".
    This can also serve as a reminder of what is already done.
  3. Now, you work on File B until you are happy,
    you git add "File B" and save the entirely working snapshot.

Saving files with git commit

Git's main job is to make sure you never lose a committed change.

To finally save the Readme.md file, one has to execute

$ git commit -m "Committed empty readme file."
[master (root-commit) db35944] Committed empty readme file.
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 Readme.md

Commit file with message (otherwise default editor opens).

Branch, refspec, new commit ID (db35944) and message.

Changes in file.

The file is now "saved" and the working directory is clean

$ git status
On branch master
nothing to commit, working tree clean

Now theres is nothing left to do.

One can also review all commits by running

$ git log
commit db35944b5054d24eadf49c42c0c254ce4d092040 (HEAD -> master)
Author: Christopher Koerber {my@email.address}
Date:   Wed Apr 4 18:03:54 2018 +0200

    Committed empty readme file.

The full commit ID.

Author and commit timestamp information.

The commit message.


Working with git

Usually, one works with several files at once. Lets mimic this.

  1. We create a LaTex file
    $ echo "\documentclass{minimal}\begin{document}Hello World\end{document}" > article.tex
    $ ls 
    Readme.md  article.tex

    Note that you can edit files however you want — you don't have to use bash commands.

  2. Adjust the readme file
    $ echo "Compile article.tex by running pdflatex on it" > Readme.md
  3. Check the status of the repo
    $ git status
    On branch master
    Changes not staged for commit:
      (use "git add {file}..." to update what will be committed)
      (use "git checkout -- {file}..." to discard changes in working directory)
    
    	modified:   Readme.md
    
    Untracked files:
      (use "git add {file}..." to include in what will be committed)
    
    	article.tex
    
    no changes added to commit (use "git add" and/or "git commit -a")
    

    You now have a tracked but modified file (unstaged).

    And a new, untracked file.

    You can add the modified file.

    You can reset the modified file.

    You can also add but not reset the new, untracked file.


  1. Add the untracked file
    $ git add article.tex
    $ git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD {file}..." to unstage)
    
    	new file:   article.tex
    
    Changes not staged for commit:
      (use "git add {file}..." to update what will be committed)
      (use "git checkout -- {file}..." to discard changes in working directory)
    
    	modified:   Readme.md

    The new file is now staged but not stored.

  2. Add the not staged file
    $ git add Readme.md
    $ git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD {file}..." to unstage)
    
    	modified:   Readme.md
    	new file:   article.tex
  3. Commit both at once
    $ git commit -m "Added article and adjusted readme"
    [master 44aab06] Added article and adjusted readme
     2 files changed, 2 insertions(+)
     create mode 100644 article.tex

Status of files

Status What does this mean git command
Untracked Git doesn't know anything about this file
Staged Git now tracks changes to this file and will save it on the next commit git add {untracked/unstaged}
Unstaged Git tracks this file and found a difference compared to the last recorded stage
Saved Git tracks this file, has information about the history, and will inform you about differences git commit -m "{message}"

Best practice

  • You should only commit essential files
    Do not commit product files like .o, .aux, ...
  • You should commit files which help to build the repository
    Add documentary files like a Readme or building files like a Makefile
  • Communicate and utilize a consistent "saving strategy"
    E.g., try to only commit "working" snapshots like .tex files which compile
  • If possible, try to keep the working tree clean
    Try to finish your work such that the output of git status is "nothing to commit, working tree clean"

.gitignore

Once you compile the *.tex, you obtain files you should not commit

$ pdflatex article.tex
$ git status
Untracked files:
	article.aux
	article.log
	article.pdf

Since you now know how it works, I have left out some (for now irrelevant) output lines

The solution: put them in an .gitignore file

Create a new file called .gitignore where each line is a to be ignored file name, directory name or pattern

$ echo '*.aux' >  .gitignore
$ echo '*.log' >> .gitignore
$ echo '*.pdf' >> .gitignore
$ git status
Untracked files:
	.gitignore

You should also save the .gitignore file to the repository — others should ignore the same things

$ git add .gitignore
$ git commit -m "Added .gitignore for tex products"

Inspecting

You now know how to add files and their modifications. Next you will learn how to inspect their history.

To see the repository history, use git log
It is helpful to use the --pretty flag for output styling options

$ git log --pretty="[%ci](%h) %an: %s"
[2018-04-06 15:14:02 +0200](3003795) Christopher Koerber: Added .gitignore for tex products
[2018-04-06 13:33:23 +0200](44aab06) Christopher Koerber: Added article and adjusted readme
[2018-04-04 18:03:54 +0200](db35944) Christopher Koerber: Committed empty readme file.

The strings in parenthesis are commit identifiers. You need them, e.g., for comparing different versions.

How have we changed the Readme file from first to second commit?

$ git diff db35944 44aab06 Readme.md
diff --git a/Readme.md b/Readme.md
index e69de29..e6da3a6 100644
--- a/Readme.md
+++ b/Readme.md
@@ -0,0 +1 @@
+Compile article.tex by running pdflatex on it

Git metadata (You will not need this information).

Changes from a/Readme.md get a "-", Changes from b/Readme.md get a "-"

Diff chunk location: in line zero, one line was added.

This line was added to a/Readme

Comparing files with git diff

The general syntax is

$ git diff {options} {commit1} {commit2} {path}

Where all objects after diff could be left out

No commit object
Compares difference of current (tracked) {path} to last commit
One commit object
Compares difference of current (tracked) {path} to {commit1}
Two commit objects
Compares difference of {path} between {commit1} and {commit2}
No path specification
Checks all files and directories

Using git checkout to walk back in time

You can also revisit old commits

$ git checkout db35944
...
HEAD is now at db35944... Committed empty readme file.

We now went back in history to the point where we only have saved the empty readme file.

$ cat Readme.md

$ ls
Readme.md  article.aux	article.log  article.pdf
  • git checkout changes the state of the whole repository folder on the harddrive.
  • The Readme file is empty
  • At this point, we have not saved article.tex — this file is gone
  • The ignored files are not tracked, therefore they are not affected by a walk in the past
  • The .gitignore file has not been created yet — therefore the product files show up

To go back to the present, execute

$ git checkout master
Previous HEAD position was db35944... Committed empty readme file.
Switched to branch 'master'

Using git checkout to revert changes

Lets say we make some unwanted changes to a file

$ echo "I'm doing something stupid" >> article.tex
$ cat article.tex 
\documentclass{minimal}\begin{document}Hell World\end{document}
I'm doing something stupid
$ git status
Changes not staged for commit:
	modified:   article.tex

Now we want to revert the changes

$ git checkout article.tex
$ cat article.tex 
\documentclass{minimal}\begin{document}Hell World\end{document}
$ git status
nothing to commit, working tree clean

We now walked back in time to the last saved snapshot (for this particular file)

Collaborating basics

This guide assumes a remote repository has already been set up.

For basic usage, you only need two things to start collaborating:

  • the location of the remote repository, e.g., a URL, folder on a remote machine, ...
  • the name of the branch to work on, e.g., master or devel, ...

You just need these infos once to initialize your local copy
ask the repo owner.

More details on how to set up remote repositories and the git branch system are given in the intermediate course.

Initializing local copies with git clone

Get a local copy of the remote repository

Create a new folder git_tutorial at the current location containing the complete repository and it's full history.

$ cd ..
$ git clone https://github.com/ckoerber/git_tutorial.git
Cloning into 'git_tutorial'...
remote: Counting objects: 13, done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 13 (delta 1), reused 9 (delta 0), pack-reused 0
Unpacking objects: 100% (13/13), done.

Go to the folder where you would like to create your local copy of the remote repo. Change that how you like.

Clone repo from this URL source. Can also be other local or remote folder.

Name of the folder containing the local copy of the repo.

Compressing, transferring and unpacking files.

Checkout the designated (development) branch

$ cd git_tutorial
$ git checkout devel
Branch 'devel' set up to track remote branch 'devel' from 'origin'.
Switched to a new branch 'devel'
  • Branches can be though of as independent lines of development.
  • The default branch is usually called master. For most linear projects, one branch is sufficient and you can ignore this step.

You can now modify, add and commit files as before

Pull update

Before update

Pull update — status before pull

After update

Pull update — status after pull

Updating local repos with git pull

Whenever a remote repository has changed, you should consider updating your local copy. There are several strategies for doing so. The most direct strategy is git pulling. Note that git warns you before it changes files irreversibly.

Update your local copy through the remote

Because you just created a copy from the remote repository, there is nothing to update.

$ git pull
Already up to date.
$ git status
On branch devel
Your branch is up to date with 'origin/devel'.

nothing to commit, working tree clean

The current line of development is now called devel.

Informs you with what the status is compared to.

Possible scenarios

Scenario What git does What you have to do
Local status = remote status Nothing Nothing
Local status > remote status (same history) Nothing publish your commits (if you are ready)
Local status < remote status (same history) Updates your files Nothing
Local history != remote history Merges non-conflicts Manually merge conflicts (see merging)

Git will warn you before it overwrites content you have created.

Conflicts when pulling

If you and a collaborator work on the same line in the same file at the same time, you create a conflict. Without further input, git does not know what to keep.

Let's mimic the a conflict scenario by creating a local copy of the repo

$ cd ..
$ git clone git_tutorial git_tutorial_B
Cloning into 'git_tutorial_B'...
git_tutorial git_tutorial_B
$ cd git_tutorial
$ echo "Some notes" >> Readme.md
$ git add Readme.md
$ git commit -m "Updated readme"
$ cd git_tutorial_B
$ echo "Instruction B" >> Readme.md
$ git add Readme.md
$ git commit -m "New instruction"

Now imagine git_tutorial_B pulls from it's origin git_tutorial

$ git pull
error: Pulling is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm {file}'
hint: as appropriate to mark resolution and make a commit.
fatal: Exiting because of an unresolved conflict.

Push update

Before update

Push update — status before push

After update

Push update — status after push

Updating remote repos with git push

Once are ready to share your (accumulated) commits, use git push.

Modify and commit changes

$ echo "See the LICENSE for usage agreement" >> Readme.md
$ git add Readme.md
$ git commit -m "Mentioned LICENSE in Readme"
$ git status
On branch devel
Your branch is ahead of 'origin/devel' by 1 commit.
  (use "git push" to publish your local commits)

Change add and commit files.

Your status is different than origin repo status.

Next possible actions: publish to remote or continue local modifications and push multiple commits.

Update the remote

$ git push
...
To https://github.com/ckoerber/git_tutorial.git
   3003795..73ab23c  devel -> devel
  • NEVER push to repositories in which others work (see remote repositories; that's the origin repository owners duty).
  • The general push syntax is git push {repository} {branch}.
  • Because you have cloned the repository, git already knows where to place your commits on default.
  • The admin might have to accept your updates depending on the configuration of the remote repo.
    (git will tell you if you have to do anything else)

Conflicts when pushing

If you and a collaborator work on the same line in the same file at the same time, you create a conflict. Without further input, git does not know what to keep.

Let's mimic the a conflict scenario by creating a local copy of the repo

$ cd ..
$ git clone git_tutorial git_tutorial_B
Cloning into 'git_tutorial_B'...
git_tutorial git_tutorial_B
$ cd git_tutorial
$ echo "Some notes" >> Readme.md
$ git add Readme.md
$ git commit -m "Updated readme"
$ cd git_tutorial_B
$ echo "Instruction B" >> Readme.md
$ git add Readme.md
$ git commit -m "New instruction"

Now imagine git_tutorial_B pushes to it's origin git_tutorial

$ git push
To ~/git_tutorial/
! [rejected]        devel -> devel (fetch first)
error: failed to push some refs to '~/git_tutorial/'
...

Workflow

  1. git pull to obtain updates from remote
  2. Make local modifications and commit them (see status of files)
    1. Modify files
    2. git add {file} modified files
    3. git commit -m "{message}" complete snapshots
  3. git push to publish commits on remote

Good practise

  • git pull before git push
    Git does not allow to git push if you don't have the same history. You have to pull first.
  • Frequently use git status to ensure correctness of actions
  • Try to keep git status clean
    E.g., nothing to do anywhere

Additional tools

latexdiff-vc

Visualization of changes between different commits for .tex files

$ latexdiff-vc --git --pdf -r {commit-hash} {texfile}
Example result of latexdiff-vc.

Intermediate Course

—About setting up remote repos, branching & merging

Content of the intermediate course

This course will show you

  1. how to create and use different branches
  2. how to merge branches and resolve conflicts
  3. how to set up repositories on remote machines
  4. a cheat sheat

Branching

Branches correspond to independent lines of development. You have already seen examples for different branches: the local master branch is an independent line of development based on the origin/master branch. You can also create local independent lines of development.

  1. Create a new branch
    $ git branch new-feature master
    

    The syntax is "git branch {branch-name} {start-point}"

    Branching — status after creating new feature branch
  2. Switch to new branch and add stuff
    $ git checkout new-feature
    Switched to branch 'new-feature'
    
    
    $ echo "import numpy" > newFeature.py
    $ echo "started to work on new feature" >> Readme.md
    $ git add newFeature.py Readme.md
    $ git commit -m "Added new feature"
    
    Branching — status after commit on new-feature branch
  3. Go back to old branch
    $ git checkout master
    Switched to branch 'master'
    Your branch is up to date with 'origin/master'.
    
    $ ls
    LICENSE  Readme.md  article.tex
    
    Branching — status after going back to master branch

Branching examples

The main purpose of branches
  • A common basis for collaborating and developing new features
  • Fix point to go back to old versions
If you work alone and don't need a stable fixpoint
It is sufficient to solely have a master branch
If you need a stable version or have simple collaborating projects
Create one master branch as a basis and further devel branches
For complex projects
See Gitflow Workflow for a structure containing hotfixes and release versions

Using git merge

In the best possible case, you just use git merge and git does everything for you. For example, effectively, git push & git pull make use of this command.

There are basically four different merging strategies

  1. Fast forward merge
  2. 3-Way merge
    1. without conflicts
    2. with conflicts
  3. git rebase , which "rebases" the history of your commits

Below, the first 3 scenarios are explained.

The starting point will always be the final state from the branching slide.

(newFeature.py was created and commited in the new-feature branch and the master branch is checked out.)

Fast forward merge

You have a linear path from current branch to target branch head

Branching — status after commit on new-feature branch

Merge new-feature branch into current branch

$ git merge new-feature 
Updating 841377f..5321d8f
Fast-forward
 newFeature.py | 0
 ...
Merging — fast forward merging new-feature branch into master branch

3-Way merge without conflict

You do not have a linear path from current branch to target branch head but it was worked on different parts of files.

Branching — status after commit on new-feature branch
  1. Add another new file and commit it
    $ touch logo.png
    $ git add logo.png
    $ git commit -m "Added logo"
    
    Branching — status after commit on new-feature branch
  2. Merge new-feature branch into current branch
    $ git merge new-feature -m "Merge branch 'new-feature'"
    Merge made by the 'recursive' strategy.
     Readme.md     | 1 +
     newFeature.py | 1 +
     2 files changed, 2 insertions(+)
     create mode 100644 newFeature.py
    
    Branching — status after commit on new-feature branch

    This creates a new commit

3-Way merge with conflict

Same as starting scenario as with "3-Way merge without conflict" but now the same file was modified in both branches.

  1. Modify the readme file and commit it
    $ echo "I shouldn't be doing this..." > Readme.md
    $ git add Readme.md
    $ git commit -m "Changed the readme..."
    
  2. Merge new-feature branch into current branch CONFLICT!
    $ git merge new-feature 
    Auto-merging Readme.md
    CONFLICT (content): Merge conflict in Readme.md
    Automatic merge failed; fix conflicts and then commit the result.
    

    You have to adjust the readme file.

  3. Adjust the conflicting files and commit them

    git status signalizes what needs to be done

    $ git status
    You have unmerged paths.
      (fix conflicts and run "git commit")
      (use "git merge --abort" to abort the merge)
    
    Changes to be committed:
    
    	new file:   newFeature.py
    
    Unmerged paths:
      (use "git add {file}..." to mark resolution)
    
    	both modified:   Readme.md
    

    The readme file contains now both changes. Adjust it as desired

    $ cat Readme.md 
    <<<<<<< HEAD
    I shouldn't be doing this...
    =======
    Compile article.tex by running pdflatex on it
    started to work on new feature
    >>>>>>> new-feature
    
    $ echo "Compile article.tew with pdflatex" > Readme.md
    $ echo "See the new feature file for more infos" >> Readme.md
    $ git add Readme.md
    $ git commit -m "Merged branch 'new-feature'. Reverted stupid readme changes..."
    

Similiar as before, The final commit has merged the new-feature branch into master and has created a new commit.

Branching — status after commit on new-feature branch

Remote repository options

There are several ways to set up remote repositories. The options range from private servers or publicly available domains. Here are a few options

  • Set up remote repositories over SSH connection, e.g.,
    $ git clone me@ssh.remote.com:/home/me/git_tutorial

    Where me@ssh.remote.com are the SSH login name and address of the remote machine and /home/me/git_tutorial is the path to the remote repository folder.

  • Git hosting services like GitHub, Bitbucket or GitLab and many others
    $ git clone https://github.com/ckoerber/git_tutorial.git
    • Most of these repositories are open source inspired: you can use the service for free with public repositories or as a subscription with private repositories.
    • Furthermore, the hosting services come with a graphical interface and many features for collaborating.
    • Some research instituions already have setup hosting services like GitLab@FZJ*.

Set up bare SSH repository

Here, you learn how to set up remote repositories over SSH access. Besides step 1., this is similar for hosting services.

Settle on a common repository location

Even though there exist no absolute origin repo in git, for a given project it is useful to push/pull from just one source.

Steps to set up a remote repository

  1. Create an empty bare repository at remote location

    $ ssh me@ssh.remote.com
    $ cd /home/me
    $ git init --bare git_tutorial
    $ logout
    

    Go to the path of choice. Make sure you have writing permissions.

    The flag "--bare" signalizes a repo without working directory. You can only push & pull but not add/commit.

  2. Tell your local repository the remote location

    $ git remote add myRemote me@ssh.remote.com:/home/me/git_tutorial 
    

    "myRemote" is now the git name (abbreviation) for the remote repository. You can name it however you like.

  3. Fill the remote from local repository

    $ git push --set-upstream myRemote master
    

    "myRemote" is now the git name (abbreviation) for the remote repository. You can name it however you like.

You can now clone, push & pull from the remote repo.

Git cheat sheet

See also the atlassian.com git cheat sheet.

Git setup

Command Info
git config [--global] user.name {name} Define author name to be used for all commits in current repo. One can commonly use the optional --global flag to set config options for current user. The same can be done for user.email.
git init {directory} Creates an empty Git repo in specified directory.
git clone {repo} Clones repo located at {repo} onto local machine. Original repo can be located on the local filesystem or on a remote machine via HTTP or SSH.

Git basics

Command Info
git {command} -h Show brief help page for git command. Use --help instead of -h for long description.
git add {directory/file} Stage all changes in {directory/file} for the next commit.
git commit -m "{message}" Commit the staged snapshot and use message as the commit message.
git status List which files are staged, unstaged and untracked.
git log Display the entire commit history.
git diff {file} Show unstaged changes for {file}.

Nearly all commands come with additional flags, e.g., use git commit -am "{message}" to automatically stage and commit all unstaged files. Use -h to find the flag you are looking for.

Git branches

Command Info
git branch {branch} Creates a new branch with the name {branch}. List all of the branches in your repo if {branch} is left out.
git checkout {branch} Checks out the branch {branch}.
git merge {branch} Merges {branch} into the current branch.

Git collaborating

Command Info
git remote add {name} {url} Creates a new connection to a remote repo. After adding a remote, you can use {name} as a shortcut for {url} in other commands. Prints all available remotes if {name} and {url} are left out.
git pull {remote} Merges the specified remote's copy of the current branch into the local copy.
git push {remote} {branch} Pushs the specified branch to {remote}, along with necessary commits and objects. Creates named branch in the remote repo if it doesn't exist.

Nearly all commands come with additional flags, e.g., use git push --set-upstream {remote} {branch} to define the default push remote for specified branch (after this git push without options automatically pushs the {branch} to {remote}). Use -h to find the flag you are looking for.