Git

A Brief Introduction into Git

Lukas Kluft and Georgiana Mania

Version control systems

  • Manage a sequence of snapshots (e.g. of folders)
  • Provide tools to handle changes
  • Provide tools for collaboration

Why version control?

  • Exchange I’ll send you my script via mail.
  • Collaboration Sample File (conflicted copy 2019-11-21)
  • Storing versions (properly) But it worked yesterday… 😭
  • Tracking I did not change anything!!11! 🤬
  • Backup I replaced the wrong my_file_2_final_final.py 😱

Git

There are many version control systems out there (e.g. Subversion, CVS, Mercurial). We will focus on Git which is the de facto standard

As easy as 1, 2, 3

git init .  # Initialize a repository
git add .  # Add the whole directory content (don't do that)
git commit -m "Initial commit"  # Commit your changes

gitGraph
   commit id: "df21a: Initial commit"

Sequence of snapshots

Commits are linked to form a sequence of snapshots:

echo "hello" > world.txt
git add world.txt
git commit -m "add world"

gitGraph
   commit id: "df21a: Initial commit"
   commit id: "315f2: add world"

The basic workflow

  • Git offers plenty of functionality that is extensively documented

  • You will only need a handful of commands in your day to day work:

    git status  # show which files have changed
    git diff my_file  # show what has changed
    git add my_file  # stage changes
    git commit  # commit your changes

Configuration

  • Each commit is attributed to an author

  • The concept or authorship is heavily used on other platforms (e.g. GitLab)

git config --global user.name "Your Name"
git config --global user.email "youremail@yourdomain.com"

Hands-on Session

  1. Configure the username and email adress in your local git client
  2. Initialize an empty Git repository
  3. Create a file and add it to the repo
  4. Change the file, inspect the differences, and commit the changes

On Levante: module load git

Branches

  • Are versions of the code identified with a name (besides the existing hash)
  • Are used to encapsulate the changes required for a feature/bugfix
  • Allow incremental development without impacting the other branches

Create a branch

Create a branch develop to work on a feature

git branch develop
git switch develop

gitGraph
   commit
   commit
   branch develop
   checkout develop
   commit
   commit

Show differences between two branches

git diff develop..main

Merge a branch

Merge the commits of develop into main

git checkout main
git merge develop

gitGraph
   commit
   commit
   branch develop
   checkout develop
   commit
   commit
   checkout main
   merge develop

Hands-on session

  1. Create a branch
  2. Commit something in the branch
  3. Merge the new branch
  4. Check the log of the main branch
  5. Delete the new branch (git branch --help)

Conflicts

Collaboration can lead to disagreements

gitGraph
   commit
   commit
   branch alice
   checkout alice
   commit
   checkout main
   branch bob
   checkout bob
   commit

Alice fixes an obvious error file.txt

-This course is lame
+This course is nice!

Bob is doing the same

-This course is lame
+This course is awesome!

Conflicts

This creates a conflict when merging both branches

gitGraph
   commit
   commit
   branch alice
   checkout alice
   commit
   checkout main
   branch bob
   checkout main
   merge alice
   checkout bob
   commit
   checkout main
   merge bob

Auto-merging file.txt
CONFLICT (content): Merge conflict in test.txt
Recorded preimage for 'file.txt'
Automatic merge failed; fix conflicts and then commit the result.

Solving conflicts

Solving conflicts requires your decision

file.txt
<<<<<<< HEAD
This course is nice!
=======
This course is awesome!
>>>>>>> bob

Solving conflicts

Solving conflicts requires your decision

file.txt
This course is awesome!

After resolving the conflict, you have to commit your changes

git add file.txt
git commit

Hands-on session

  1. Create file.txt in two different branches with different content
  2. Merge both branches into main (CONFLICT)
  3. Resolve the conflict and commit your changes

Best practices

Commits should deal with only one task; one logical unit

  • Ensure regular commits to track progress effectively
  • Commit each fix or task independently for clarity and easier management
  • Commit self-consistent (i.e. working) states

Best practices

Write meaningful commit messages

  1. Use the imperative mood in the subject line (what is done)
  2. Limit the subject line to 50 characters
  3. Use the body to elaborate why changes have been performed

ice: Fix freeing uninitialized pointers

Automatically cleaned up pointers need to be initialized before exiting
their scope.  In this case, they need to be initialized to NULL before
any return statement.

Fixes: 90f821d72e11 ("ice: avoid unnecessary devm_ usage")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>

Example from kernel.org

Remotes

  • Adding a remote repository

    git remote add origin <PATH_TO_REPO>
  • List the available remotes

    git remote -v
  • Push your local references to the remote repo

    git push origin feature-branch
  • Pull remote changes to your local repo

    git pull

Merge request on GitLab DKRZ

Hands-on session

  1. Upload your public SSH key to the DKRZ GitLab
  2. Push your repository to GitLab
  3. Create a branch and add a new file
  4. Create a merge request (add author, reviewer, …)
  5. Approve and merge it to main

https://gitlab.dkrz.de/generic-software-skills/students2024/<YOUR_USERNAME>.git

Take home messages

  • You should use git frequently!
  • Industry is using it as de facto standard
  • Use branches to organize your work

Shotgun buffet

Rebase vs merge

Instead of merging branches, one can also rebase

%%{init: {'gitGraph': {'showCommitLabel': false}} }%%
gitGraph
   commit
   commit
   branch develop
   checkout develop
   commit
   commit
   checkout main
   commit

%%{init: {'gitGraph': {'showCommitLabel': false}} }%%
gitGraph
   commit
   commit
   commit
   branch develop
   checkout develop
   commit
   commit

Rebasing retains a linear history
by changing the commit history (!!!)

Forks

  • A fork is a copy of a repository on server side

  • Used to work on public repositories without granting ownership

  • Standard names for locally defined remotes:

    origin    https://github.com/lkluft/numpy (fetch)
    origin    https://github.com/lkluft/numpy (push)
    upstream  https://github.com/numpy/numpy (fetch)
    upstream  https://github.com/numpy/numpy (push)

Tools for graphical merge

VSCode, meld

Further reading