Zum Inhalt

Git

Git ist das Quellcodeverwaltungssystem, welches wir einsetzen.

Installation

Installiere Git mit dem Paketmanager deines Vertrauens.

Konfiguration

Damit Commits in BitBucket und JIRA dem richtigen Benutzer zugewiesen werden können müssen Name und E-Mailadresse angegeben werden.

git config --global user.name 'FIRSTNAME LASTNAME'
git config --global user.email EMAIL@EXAMPLE.NET

Des weiteren sollten nützliche Standardwerte gesetzt werden.

git config --global fetch.prune true
git config --global pull.ff only
git config --global push.default simple
git config --global push.followTags true
git config --global rebase.autoStash true
git config --global rerere.enabled true
git config --global url.https://github.com.insteadOf git://github.com

Schließlich sollte noch SSH konfiguriert, ein Schlüsselpaar erzeugt werden und der öffentliche Schlüssel bei den Hostingdiensten hochgeladen werden.

Mehrere Identitäten

Sollte man mehrere Identitäten/E-Mailadressen auf seinem Rechner eingerichtet haben sollte man sicherstellen, dass die Commits mit der korrekten Adresse gemacht werden. Ansonsten kann es sein, dass man bestimmte Benachrichtigungen an die falsche Adresse gehen und daher leicht übersehen werden.

Zuerst sollte die globale Konfiguration entfernt werden, um Git zu zwingen diese davon unabhängig für jedes einzelne Repositorium zu bestimmen:

git config --global --unset core.sshCommand
git config --global --unset user.email
git config --global --unset user.name

Ausser muss man Git instruieren den diese Daten auch nicht zu erraten:

git config --global user.useConfigOnly true

Nun kann man pro Git-Repositorium verschiedene Benutzerdaten angeben, die dann für die dortigen Commits und SSH-Verbindungen benutzt werden:

cd /path/to/project/1
git config --local user.name 'FIRSTNAME LASTNAME'
git config --local user.email NAME1@DOMAIN1
git config --local core.sshCommand = ssh -i /PATH/TO/PRIVATE/KEY/2
cd /path/to/project/2
git config --local user.name 'FIRSTNAME LASTNAME'
git config --local user.email NAME2@DOMAIN2
git config --local core.sshCommand = ssh -i /PATH/TO/PRIVATE/KEY/2

PuTTY

Will man Git unter Windows mit PuTTY und Pageant nutzen, so muss man Git instruieren nicht seinen eigenen SSH-Client, sondern den von PuTTY zu nutzen, indem man folgenden PowerShell-Befehl ausführt:

setx GIT_SSH "$env:ProgramFiles\PuTTY\plink.exe"

Danach dieser Befehl wird erst nachdem Neustart des jeweiligen Progamms (IDE oder Terminal) wirksam.

Beim Herstellen einer Verbindung zu einem bisher unbekannten Host muss dessen SSH-Fingerabdruck akzeptiert werden. Leider zeigt plink.exe keinen Dialog dafür an. Man sollte sich also zuvor mit putty.exe zu diesem Host verbinden und den Fingerabdruck akzeptieren. Folgende Hosts kann man am besten vorab abklappern:

GitFlow

GitFlow ist ein Branch-Workflow für Git. Verschiedene Arten von Arbeiten werden auf verschiedenen Branches erledigt. Es wird wie folgt unterschieden:

  • bugfix: Entwicklung von Fehlerbehebungen
  • feature: Entwicklung neuer Funktionalitäten
  • hotfix: Veröffentlichung von Fehlerbehebungen
  • release: Veröffentlichung neuer Funktionalitäten
  • support: wird von B5C nicht genutzt

Installation

Siehe hier.

Initialisierung

GitFlow muss für jedes Git-Repositorium einmal initialisiert werden. B5C verwendet die Standardeinstellungen. Daher führe man zu initialisierung folgenden Befehl aus:

git flow init --defaults

Nutzung

Bevor man einen Arbeitsschritt beginnt sollte man wie folgt sicherstellen, dass die Branches master und develop aktuell sind:

git checkout master
git pull
git checkout develop
git pull

Bugfixes zum Entwickeln von Fehlerbehebungen

Bugfix-Branches werden zur Entwicklung (aber nicht Ausrollen) von Fehlerbehebungen genutzt. Ein Bugfix-Branch zweigt vom Develop-Branch ab und wird auch wieder in diesen gemerged.

Einen Bugfix-Branch für beispielsweise das JIRA-Ticket PROJ-123 startet man wie folgt:

git flow bugfix start PROJ-123

GitFlow erzeugt einen neuen Branch namens bugfix/PROJ-123 auf dem man seine Arbeit erledigen kann. Ist man damit fertig kann man entweder den Branch veröffentlichen, damit sich andere Entwickler die Arbeit ansehen können und ihn dann mergen:

git flow bugfix publish

Alternativ kann man auch selbst den Branch mergen und hochladen:

git -c core.editor=true flow bugfix finish -m ' ' -p

Features zum Entwickeln neuer Funktionalitäten

Feature-Branches werden zur Entwicklung (aber nicht Ausrollen) von neuen Funktionen genutzt. Ein Feature-Branch zweigt vom Develop-Branch ab und wird auch wieder in diesen gemerged.

Einen Feature-Branch für beispielsweise das JIRA-Ticket PROJ-123 startet man wie folgt:

git flow feature start PROJ-123

GitFlow erzeugt einen neuen Branch namens feature/PROJ-123 auf dem man seine arbeit erledigen kann. Ist man damit fertig kann man entweder den Branch veröffentlichen, damit sich andere Entwickler die Arbeit ansehen können und ihn dann mergen:

git flow feature publish

Alternativ kann man auch selbst den Branch mergen und hochladen:

git -c core.editor=true flow bugfix finish -m ' ' -p

Hotfixes zum Veröffentlichen von Fehlerbehebungen

Hotfix-Branches werden zum Ausrollen (aber nicht Entwicklung) von Fehlerbehebungen genutzt. Ein Hotfix-Branch zweigt vom Master-Branch ab, wird auch wieder in diesen, wie auch in den Develop-Branch gemerged und mit einem Tag versehen.

Einen Hotfix-Branch wird mit einer neuen Versionsnummer erstellt. Um alle bereits veröffentlichten Versionen erhalten führt man folgenden Befehl aus:

git fetch --tags

Die bereits veröffentlichten Versionen lassen sich dann wie folgt anzeigen:

git tag -l

Um die Versionsnummer für den Hotfix zu erhalten nehme man die neueste veröffentlichte Version (z.B. 1.2.2) und erhöhe die dritte Zahl um Eins (also 1.2.3). Einen Hotfix-Branch für beispielsweise die Version 1.2.3 startet man dann wie folgt:

git flow hotfix start 1.2.3

GitFlow erzeugt einen neuen Branch namens hotfix/1.2.3 auf dem man seine arbeit erledigen kann. Ist man damit fertig kann man entweder den Branch veröffentlichen, damit sich andere Entwickler die Arbeit ansehen können und ihn dann mergen:

git flow hotfix publish

Alternativ kann man auch selbst den Branch mergen und hochladen:

git -c core.editor=true flow hotfix finish -m ' ' -p

Releases zum Veröffentlichen neuer Funktionalitäten

Release-Branches werden zum Ausrollen (aber nicht Entwicklung) von neuen Funktionen genutzt. Ein Release-Branch zweigt vom Develop-Branch ab, wird auch wieder in diesen, wie auch in den Master-Branch gemerged und mit einem Tag versehen.

Einen Release-Branch wird mit einer neuen Versionsnummer erstellt. Um alle bereits veröffentlichten Versionen erhalten führt man folgenden Befehl aus:

git fetch --tags

Die bereits veröffentlichten Versionen lassen sich dann wie folgt anzeigen:

git tag -l

Um die Versionsnummer für das Release zu erhalten nehme man die neueste veröffentlichte Version (z.B. 1.1.1) und erhöhe die zweite Zahl um Eins und setze die dritte Zahl auf Null (also 1.2.0). Einen Release-Branch für beispielsweise die Version 1.2.0 startet man dann wie folgt:

git flow release start 1.2.0

GitFlow erzeugt einen neuen Branch namens release/1.2.0 auf dem man seine arbeit erledigen kann. Ist man damit fertig kann man entweder den Branch veröffentlichen, damit sich andere Entwickler die Arbeit ansehen können und ihn dann mergen:

git flow release publish

Alternativ kann man auch selbst den Branch mergen und hochladen:

git -c core.editor=true flow release finish -m ' ' -p

Undo

Git hat keinen dedizierten Undo-Befehl. Einzelne Befehlen können jedoch mit bestimmten Aktionen rückgängig gemacht werden. Die Meisten davon sollten unmittlbar nach dem Befehl ausgeführt werden, der rückgängig gemacht werden soll. Soll ältere History – insbesondere Merges – rückgängig gemacht werden nutze git-revert(1).

Befehl Undo-Befehl
git add $FILES git reset HEAD -- $FILES
git branch $BRANCH git branch -d $BRANCH
git checkout $TREEISH git checkout @{-1}
git checkout -b $BRANCH git checkout @{-1} && git branch -d @{-1}
git commit git reset HEAD~1
git merge $BRANCH git merge --abort || git reset --hard @{1}
git pull git merge --abort || git reset --hard @{1}
git pull --rebase git rebase --abort || git reset --hard @{1}
git rebase $BRANCH git rebase --abort || git reset --hard @{1}
git rm $FILES git checkout HEAD -- $FILES
git stash git stash pop
git tag $TAG git tag -d $TAG
rm $FILES git checkout HEAD -- $FILES
$EDITOR $FILES git checkout HEAD -- $FILES

Wenn du dir nicht sicher bist welcher Befehl zu nutzen ist schaue dir einen der folgenden Guides an:

Working with submodules

Clone repository including all submodules

git clone --recursive REPO_URL
If you forgot to use –recursive you can use git submodule update --init to init the submodules for the first time.

Checkout a certain branch on a single submodule

After you cloned the base repository with –recursive it will point to the branch you checked out. But all submodules will be in detached HEAD state and point to the last commit their commit reference has been configured to. In a production environment you can leave this as is. But when developing on a submodule, you want to change into the directory of the submodule and checkout the branch you want to work on before you start developing:

cd path/to/submodule/
git checkout <branch>

Checkout a certain branch on all submodules

If you want to checkout a certain branch on all submodules at once you can use the following command inside the base repository:

git submodule foreach git checkout <branch>

How to commit

If you changed something you can commit your changes by using the standard commit command from inside the submodule you want to commit your changes to:

cd /path/to/submodule
git commit -sam 'Your change inside the submodule'

# optionaly you can push your changes
git push

After you commited to a submodule there is a second step to take. A commit to a submodule will change the reference from the base repository to the submodule. So after doing a commit to a submodule you need to switch to the base repository and do a second commit to update the commit references. If you don’t update the commit reference in the base repo everyone else will still have the old commit references.

# Change from submodule to base repo
cd ..

# Update commit references
git commit -sam 'Update commit references'

# optonally push all commits made in the base repo or in a submodule
git push --recurse-submodules=on-demand

Update base repo and submodules to configured commits

If you want to update the base repository and all submodules to the commits that have been configured for the submodules in the base repository, you first need to update the base repository and afterwards you need to update all submodules:

git submodule init
git submodule update

git pull --rebase
git submodule update

See https://stackoverflow.com/questions/19619747/git-submodule-update-remote-vs-git-pull for details. If you checked out a submodule to a certain branch and want to update this branch, you can use git pull inside the submodule.

Update base repo and submodules to latest master

In the base repo do:

git pull --rebase
git submodule foreach git checkout master
git submodule foreach git pull
git status
git submodule status
git commit -sam 'Updated commit references to submodules'

Making changes in a submodule (summary)

We hardly recommend to read the whole documentation before reading the summary! To make changes to submodules you need to follow this steps:

  1. Clone the base repo including all submodules (git clone --recursive REPO_URL)
  2. CD into the base repo (cd ./MY_REPO)
  3. change into the submodule you want to edit (cd path/to/submodule/)
  4. checkout the branch you want to edit, this should be the same branch as the base repository branch (git checkout master)
  5. edit files
  6. commit your changes to the submodule (git commit -sam 'My changes in submodule')
  7. change to the base repository (cd ../)
  8. commit update of submodule reference to base repo (git commit -sam 'Updated commit referenced')
  9. push changes to base repository and submodule repo (git push --recurse-submodules=on-demand)

This process should result into two commits: one commit in the submodule repository and one commit in the base repository.

Adding a new submodule

For adding a new module please read

http://blog.jacius.info/git-submodule-cheat-sheet/ https://chrisjean.com/git-submodules-adding-using-removing-and-updating/

Howto Submodules

For a general howto on git submodules pleas read

  • https://www.ralfebert.de/git/submodules/
  • https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407#.aw6hbtqea

Troubleshooting

Git asks me for ssh key password very often

You can use ssh-agent to make ssh remember your password.

Häufige Anwendungsfälle

Eine Regression mittels git bisect finden

```