Git

Die am häufigsten verwendeten Git-Kommandos

git add
git blame
git branch
git checkout
git clone
git config
git diff
git log
git mv
git pull
git push
git rm
git status
                       ┌──────┐
                       │      │
                       │   ┌──┴────────────┐             ┌───────────────┐
                       │   │               │    push     │               │
                       │   │               ├────────────►│    Remote     │
                       │   │  Comitted     │             │    (GitHub,   │
                       │   │               │             │    GitLab,    │
                       │   │               │◄────────────┤    etc.)      │
                       │   │               │    pull     │               │
                       │   └────────────┬──┘             └───────────────┘
                       │      ▲         │
                       │      │         │
                       │      │         │
                       │   commit    reset --soft HEAD^
                       │      │         │
                       │      │         │
                       │      │         ▼
                       │   ┌──┴────────────┐
                       │   │               │            ┌──────────────┐
                       │   │               │    add     │              │
                       │   │  Staged       │◄───────────┤  Untracked   │
                       │   │               │            │              │
                       │   │               │            └──────────────┘
                       │   │               │
                       │   └────────────┬──┘
                       │      ▲         │                    ───┬───
                       │      │         │                       │
                       │      │         │                       │
                       │     add     restore --staged         diff --staged
                       │      │         │                       │
                       │      │         │                       │
                       │      │         ▼                    ───┴───
                       │   ┌──┴────────────┐
┌─────────┐  stash     │   │               │
│         │◄───────────┼───┤               │
│  Stash  │            │   │  Unstaged     │
│         ├────────────┼──►│  (modified)   │
└─────────┘  stash pop │   │               │
                       │   │               │
                       │   └────────────┬──┘
                       │      ▲         │                    ───┬───
                       │      │         │                       │
                       │      │         │                       │
                       │   $EDITOR   restore                  diff
                       │      │         │                       │
                       │      │         │                       │
                       │      │         ▼                    ───┴───
                       │   ┌──┴────────────┐
                       │   │               │            ┌──────────────┐
                       │   │               │    init    │  Empty       │
                       │   │  Unstaged     │◄───────────┤  folder      │
                       │   │  (unmodified) │            │              │
                       │   │               │            └──────────────┘
                       │   │               │
                       │   └───────────────┘
                       │      ▲
                       └──────┘

Globale Git-Config setzen

Damit fängt alles an - Git global sinnvoll konfigurieren:

git config --global user.name "John Doe"
git config --global user.email "john.doe@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase true

Git Cheat Sheet

Bestehendes Repo auschecken:

git clone ssh://git@git.example.com/project/repo.git
git clone --branch 2.0.13 git@git.example.com:project/repo.git /path/to/my/dir

Git History anzeigen:

git log
git log --patch 2

# which files have changed when?
git log --name-only --date=iso

Den allerersten Commit anzeigen:

git log --format="format:%ci" --reverse | head -1

Anzahl Contributor zählen:

git log --format='%an' | sort -u | wc -l

Was muss committet werden?

git status

Wo liegen die Unterschiede?

git diff

Adden und committen:

git add $FILES
git commit -m 'my commit message describing what changed (fixed #4711)'
git push

Anzahl der Commmits zählen:

git rev-list --all --count

Aktuellen Branch anzeigen:

git branch

Neuen Branch erzeugen:

git checkout -b enh/12345/php_opcache

In bestehenden Branch wechseln:

git checkout enh/12345/php_opcache

Zwei Branches vergleichen:

git --no-pager log --oneline --graph --decorate --after="2021-10-14" master..develop

Branch umbenennen, lokal und remote:

OLD_BRANCH=master
NEW_BRANCH=main

# Switch to the local branch which you want to rename
git checkout $OLD_NAME

# Rename the local branch
git branch --move $NEW_BRANCH

# Push the $NEW_BRANCH local branch and reset the upstream branch
git push origin --set-upstream-to=$NEW_BRANCH

# Delete the $OLD_BRANCH remote branch
git push origin --delete $OLD_BRANCH

In Master committed, aber es gehört in den Branch „Develop“? Achtung: vorher alle Änderungen sichern.

git checkout develop
git cherry-pick master
git checkout master
git reset --hard origin/master
git checkout develop

Eine einzelne Datei zurücksetzen:

git checkout myfile

Alle lokalen Änderungen zurücksetzen:

git fetch --all
git reset --hard origin/master

Einen lokalen Commit vor dem endgültigen Push zurücknehmen:

# --hard: delete my changes
git reset --hard HEAD~1

# --soft: do not delete my changes, file is unstaged after that
git reset --soft HEAD~1

Einen Commit aus dem lokalen und entfernten Git-Repo löschen, aber lokal bestehen lassen:

git rm -r --cached mydir        # in SVN, "--cached" was called "--keep-local"
git commit -m 'cleaned up'
git push

Ein Git-Repo re-initialisieren, inkl. Löschen der History:

cd repo
git checkout master
git reset --hard <sha-1 of your first commit>
git commit -m 'Initial commit' --allow-empty

git remote add origin <url>
git push --force --set-upstream origin master

Switch von Passwort (https) auf SSH-Key - Parameter „url“ in .git/config ändern:

.git/config
[remote "origin"]
url = ssh://git@git.example.com/project/repo.git

Mit mehreren Usern im gleichen Git-Repo arbeiten:

groupadd repousers
useradd --create-home --groups repousers user1
useradd --create-home --groups repousers user2

# existing repo
cd /path/to/repo
git init --shared=group
# Reinitialized existing shared Git repository in /path/to/repo
chgrp -R repousers /path/to/repo
chmod -R g+rw /path/to/repo
find /path/to/repo -type d -exec chmod g+s {} +

Contributing - so geht’s

Um Code zu Open Source-Projekten beizusteuern, hat sich meist folgende Vorgehensweise etabliert:

  1. Projekt forken.

  2. Den Fork clonen: git clone git@github.com:$USERNAME/$PROJECT.git

  3. Eigenen Feature-Branch erzeugen: git checkout -b linuxfabrik/#299

  4. Coden.

  5. Änderungen committen: git commit -am 'Text describing soemthing (#299)'

  6. Änderungen in den eigenen Branch pushen: git push origin linuxfabrik/#299

  7. Im geforkten Repo einen Pull Request (PR) erstellen (auf GitHub/GitLab die Web-Ansicht für den Code-Bereich neu laden).

Tools rund um Git

  • GitHub Desktop Client, Linux Fork: https://github.com/shiftkey/desktop

  • Grafischer Client: gitg

  • TUI Client: tig

  • Git-Repos nach sensiblen Informationen durchsuchen: GitLeaks (konnte in unseren Tests allerdings keine hart-codierten Passwörter im Code finden, auch wenn sie hinterlegt waren)

  • Arbeit an Git-Repos als Video visualisieren:

    # one day = 0.1 sec
    gource --start-date '2022-01-01' --seconds-per-day 0.1 --auto-skip-seconds 1
    
    # export as gource.mp4 video
    gource \
        --auto-skip-seconds 1 \
        --date-format %Y-%m \
        --hide filenames,dirnames,usernames \
        --seconds-per-day 0.033 \
        --start-date '2021-02-21' \
        --stop-at-end \
        --output-ppm-stream - | ffmpeg -y -r 60 -f image2pipe -vcodec ppm -i - -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -crf 1 -threads 0 -bf 0 gource.mp4
    
  • Müll eingecheckt? Mit diesem kleinen Java-Tool lässt sich das Git-Repo hervorragend aufräumen: BFG Repo-Cleaner

Built on 2024-04-18