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:
- Undoing Changes
- How to undo (almost) anything with Git
- Git pretty
- On undoing, fixing, or removing commits in git
Working with submodules
Clone repository including all submodules
git clone --recursive REPO_URL
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:
- Clone the base repo including all submodules (
git clone --recursive REPO_URL
) - CD into the base repo (
cd ./MY_REPO
) - change into the submodule you want to edit (
cd path/to/submodule/
) - checkout the branch you want to edit, this should be the same branch as the base repository branch (
git checkout master
) - edit files
- commit your changes to the submodule (
git commit -sam 'My changes in submodule'
) - change to the base repository (
cd ../
) - commit update of submodule reference to base repo (
git commit -sam 'Updated commit referenced'
) - 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
```