Entwicklung/Git: Unterschied zwischen den Versionen

Zur Navigation springen Zur Suche springen
Clones mit SSH
Keine Bearbeitungszusammenfassung
(Clones mit SSH)
(2 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 14: Zeile 14:
Git-Download
Git-Download


... für Windows: http://code.google.com/p/msysgit/downloads/list?q=full+installer+official+git<br>
* ... für Windows: https://git-scm.com/download/win
... für Mac: http://code.google.com/p/git-osx-installer/
* ... für Mac: https://git-scm.com/download/mac
 
Installation per Installationsprogramm und Standardeinstellungen. Zur Installation in der Entwickler-VM siehe [[Entwicklung/Entwicklersystem|Entwicklersystem]].
Installation per Installationsprogramm und Standardeinstellungen. Zur Installation in der Entwickler-VM siehe [[Entwicklung/Entwicklersystem|Entwicklersystem]].


Zeile 28: Zeile 29:


Die Entwickler können in beliebigen Topologien organisiert werden und gleichen den Inhalt ihrer Repositories wechselseitig miteinander ab. Opencaching.de verwendet eine Art Sternstruktur, mit einem Haupt-Repository unter der Adresse  
Die Entwickler können in beliebigen Topologien organisiert werden und gleichen den Inhalt ihrer Repositories wechselseitig miteinander ab. Opencaching.de verwendet eine Art Sternstruktur, mit einem Haupt-Repository unter der Adresse  
* http://github.com/OpencachingDeutschland/oc-server3
* https://github.com/OpencachingDeutschland/oc-server3
   
   
Auf dieses Repo haben nur der Code Maintainer und seine Vertreter Schreibzugriff; alle anderen können nur lesen. Um auch Daten hochladen zu können, besitzt jeder Entwickler bei Github.com eine eigene Kopie - einen "Fork" - des Haupt-Repositories, z.B.  
Auf dieses Repo haben nur der Code Maintainer und seine Vertreter Schreibzugriff; alle anderen können nur lesen. Um auch Daten hochladen zu können, besitzt jeder Entwickler bei GitHub.com eine eigene Kopie - einen "Fork" - des Haupt-Repositories, z.B.  
* http://github.com/flopp/oc-server3
* https://github.com/flopp/oc-server3
   
   
Dein erster Schritt als Opencaching-Entwickler ist das Anlegen deines Forks. Dazu legst du dir auf [http://github.com Github] einen kostenlosen Account an, gehst auf http://github.com/OpencachingDeutschland/oc-server3 und klickst oben rechts auf "Fork".
Dein erster Schritt als Opencaching-Entwickler ist das Anlegen deines Forks. Dazu legst du dir auf [https://github.com GitHub] einen kostenlosen Account an, gehst auf https://github.com/OpencachingDeutschland/oc-server3 und klickst oben rechts auf "Fork".


Der zweite Schritt ist, dir eine lokale Kopie - einen "Klon" - deines Forks anzulegen. Wie du das im OC.de-Entwicklersystem machst, ist im Artikel [[Entwicklung/Entwicklersystem|Entwicklersystem]] beschrieben. Hier machen wir es einfach mal testweise - du kannst so viele Klone anlegen wie du möchtest, den Github-Repositories ist das egal:
Der zweite Schritt ist, dir eine lokale Kopie - einen "Klon" - deines Forks anzulegen. Wie du das im OC.de-Entwicklersystem machst, ist im Artikel [[Entwicklung/Entwicklersystem|Entwicklersystem]] beschrieben. Hier machen wir es einfach mal testweise - du kannst so viele Klone anlegen wie du möchtest, den GitHub-Repositories ist das egal:
  git clone git://github.com/&lt;DeinBenutzername&gt;/oc-server3
  git clone git@github.com:&lt;DeinBenutzername&gt;/oc-server3


Nun wird bei dir ein Verzeichnis <code>oc-server3/.git</code> angelegt, das zunächst eine 1:1-Kopie deines Github-Forks ist (der zunächst eine 1:1-Kopie des Opencaching-Deutschland-Repos ist), und von dort der komplette aktuelle OC.de-Code in Unterverzeichnisse von <code>oc-server3</code> ausgecheckt. In <code>oc-server3</code> befinden sich also sowohl deine Arbeitsdaten als auch der lokale Repository-Klon. <code>oc-server3/.git/config</code> ist die Konfigurationsdatei des lokalen Repositories, die du aber nur selten von Hand bearbeiten wirst.
Nun wird bei dir ein Verzeichnis <code>oc-server3/.git</code> angelegt, das zunächst eine 1:1-Kopie deines GitHub-Forks ist (der zunächst eine 1:1-Kopie des Opencaching-Deutschland-Repos ist), und von dort der komplette aktuelle OC.de-Code in Unterverzeichnisse von <code>oc-server3</code> ausgecheckt. In <code>oc-server3</code> befinden sich also sowohl deine Arbeitsdaten als auch der lokale Repository-Klon. <code>oc-server3/.git/config</code> ist die Konfigurationsdatei des lokalen Repositories, die du aber nur selten von Hand bearbeiten wirst.


Dein Github-Fork heißt in deinem lokalen Repository ''origin''; über diesen Name kannst du mit verschiedenen Git-Kommandos darauf zugreifen. Um die Konfiguration abzuschließen, muss zusätzlich noch der ''upstream'' definiert werden - das Repository, aus dem du neue Daten abrufst. Dies ist nicht dein eigener Fork, sondern du beziehst die Daten direkt von OpencachingDeutschland:
Dein GitHub-Fork heißt in deinem lokalen Repository ''origin''; über diesen Name kannst du mit verschiedenen Git-Kommandos darauf zugreifen. Um die Konfiguration abzuschließen, muss zusätzlich noch der ''upstream'' definiert werden - das Repository, aus dem du neue Daten abrufst. Dies ist nicht dein eigener Fork, sondern du beziehst die Daten direkt von OpencachingDeutschland. Navigiere dazu ins Verzeichnis <code>oc-server3</code> und führe dann folgenden Befehl aus:
  git remote add upstream http://github.com/OpencachingDeutschland/oc-server3
 
  git remote add upstream git@github.com:OpencachingDeutschland/oc-server3


Mit <code>git remote -v</code> kannst du dir nun alle "remote"-Repositories anzeigen lassen, die in deinem Klon eingestellt sind.
Mit <code>git remote -v</code> kannst du dir nun alle "remote"-Repositories anzeigen lassen, die in deinem Klon eingestellt sind.
Zeile 58: Zeile 60:
   
   
Nach dem ersten Auschecken ist der ''development''-Branch aktiv. Dieser enthält den aktuellen Entwicklungsstand. Welcher Branch aktiv ist, siehst du mit
Nach dem ersten Auschecken ist der ''development''-Branch aktiv. Dieser enthält den aktuellen Entwicklungsstand. Welcher Branch aktiv ist, siehst du mit
  <code>git branch</code>
  git branch
Unser Standard-Workflow sieht vor, dass '''nie im development gearbeitet wird'''. Stattdessen musst du dir - ausgehend von ''development'' - für jede Aufgabe einen Arbeitsbranch anlegen:
Unser Standard-Workflow sieht vor, dass '''nie im development gearbeitet wird'''. Stattdessen musst du dir - ausgehend von ''development'' - für jede Aufgabe einen Arbeitsbranch anlegen:
  <code>git checkout -b 1234-new-feature development</code>
  git checkout -b 1234-new-feature development
Die vorangestellte Nummer ist eine Ticketnummer aus der Todo-Liste. Wenn es keine passende gibt, lässt du sie weg. Verwende nach Möglichkeit englische Namen und Kommentare, denn das OC-Projekt ist international vernetzt. Nun kannst du mit <code>git branch</code> sehen, dass es in deinem lokalen Repo zwei Branches gibt, und der neu angelegte ist aktiv. Mit dem Kommando <code>git checkout Branchname</code> kannst du zwischen den Branches hin- und herwechseln; dabei wird jeweils der Code in den Arbeitsdaten entsprechend ausgetauscht.
Die vorangestellte Nummer ist eine Ticketnummer aus der Todo-Liste. Wenn es keine passende gibt, lässt du sie weg. Verwende nach Möglichkeit englische Namen und Kommentare, denn das OC-Projekt ist international vernetzt. Nun kannst du mit <code>git branch</code> sehen, dass es in deinem lokalen Repo zwei Branches gibt, und der neu angelegte ist aktiv. Mit dem Kommando <code>git checkout Branchname</code> kannst du zwischen den Branches hin- und herwechseln; dabei wird jeweils der Code in den Arbeitsdaten entsprechend ausgetauscht.


Zeile 71: Zeile 73:


Wenn du die Änderungen vorgenommen hast, zeigt dir
Wenn du die Änderungen vorgenommen hast, zeigt dir
  <code>git status</code>
  git status
in roter Farbe an, welche Dateien geändert oder hinzugefügt wurden, und
in roter Farbe an, welche Dateien geändert oder hinzugefügt wurden, und
  <code>git diff</code>
  git diff
die Änderungen im Einzelnen. Falls dein Editor bzw. deine Eintwicklungsumgebung irgendwelche zusätzlichen Dateien angelegt hat, kannst du diese in <code>.git/info/exclude</code> eintragen, damit sie nicht ins Repository gelangen.
die Änderungen im Einzelnen. Falls dein Editor bzw. deine Entwicklungsumgebung irgendwelche zusätzlichen Dateien angelegt hat, kannst du diese in <code>.git/info/exclude</code> eintragen, damit sie nicht ins Repository gelangen.


Als nächstes musst du Git mitteilen, dass die Daten zum aktiven Branch hinzugefügt werden sollen; dies geschieht mit
Als nächstes musst du Git mitteilen, dass die Daten zum aktiven Branch hinzugefügt werden sollen; dies geschieht mit
  <code>git add .</code>
  git add .
für alle geänderten und neuen Dateien im aktuellen Verzeichnisbaum (falls du Branches gewechselt hast vergewissere dich evtl. mit <code>git branch</code>, dass du im richtigen bist!) Wahlweise kannst du einzelne Dateien per (Pfad+)Dateiname hinzufügen oder Wildcards verwenden. Dateien löschen kann man mit
für alle geänderten und neuen Dateien im aktuellen Verzeichnisbaum (falls du Branches gewechselt hast vergewissere dich evtl. mit <code>git branch</code>, dass du im richtigen bist!) Wahlweise kannst du einzelne Dateien per (Pfad+)Dateiname hinzufügen oder Wildcards verwenden. Dateien löschen kann man mit
  <code>git rm Dateiname</code>
  git rm Dateiname
Nun zeigt <code>git status</code> in grüner Farbe alle vorbereiteten Änderungen an, und mit
Nun zeigt <code>git status</code> in grüner Farbe alle vorbereiteten Änderungen an, und mit
  <code>git commit</code>
  git commit
checkst du sie in dein lokales Repository ein. Es öffent sich ein vi-Editor, in dem du einen Kommentar eingeben musst. Schreibe eine aussagekräftige, möglichst englische Zusammenfassung in die erste Zeile, und evtl. zusätzliche Erläuterungen in die weiteren Zeilen. Wenn es nur ein einzeiliger Kommentar sein soll, kannst du dir den Editor auch sparen und den Kommentar direkt angeben mit
checkst du sie in dein lokales Repository ein. Es öffent sich ein vi-Editor, in dem du einen Kommentar eingeben musst. Schreibe eine aussagekräftige, möglichst englische Zusammenfassung in die erste Zeile, und evtl. zusätzliche Erläuterungen in die weiteren Zeilen. Wenn es nur ein einzeiliger Kommentar sein soll, kannst du dir den Editor auch sparen und den Kommentar direkt angeben mit
  <code>git commit -m "Kommentar"</code>
  git commit -m "Kommentar"
Wenn keine neuen Dateien hinzugefügt, sondern nur vorhandene geändert werden sollen, kannst du auch das <code>add</code> mit einbauen, also alle geänderten Daten mit nur einem Befehl einchecken:
Wenn keine neuen Dateien hinzugefügt, sondern nur vorhandene geändert werden sollen, kannst du auch das <code>add</code> mit einbauen, also alle geänderten Daten mit nur einem Befehl einchecken:
  <code>git commit -am "Kommentar"</code>
  git commit -am "Kommentar"
Mit
Mit
  <code>git log</code>
  git log
siehst du nun, dass ein neuer ''commit'' in die Versionsgeschichte des aktiven Branches eingefügt wurde. Wahlweise kannst du auch mit <code>git log --stat</code> nochmals alle geänderten Dateien anzeigen lassen.
siehst du nun, dass ein neuer ''commit'' in die Versionsgeschichte des aktiven Branches eingefügt wurde. Wahlweise kannst du auch mit <code>git log --stat</code> nochmals alle geänderten Dateien anzeigen lassen.


Um den Commit mit einem Ticket in der [[Entwicklung/Todo-Liste|Redmine-Todo-Liste]] zu verknüpfen, kannst du im Kommentar das Stichwort "updates #nnn" einfügen, mit #nnn = Redmine-Ticketnummer. Der Commit erscheint dann innerhalb des Tickets, sobald er geprüft und in den ''development''-Branch übernommen wurde.
Um den Commit mit einem Ticket in der [[Entwicklung/Todo-Liste|Redmine-Todo-Liste]] zu verknüpfen, kannst du im Kommentar das Stichwort "updates #nnn" einfügen, mit #nnn = Redmine-Ticketnummer. Der Commit erscheint dann innerhalb des Tickets, sobald er geprüft und in den ''development''-Branch übernommen wurde.


==== Exkurs: commits ====
==== Exkurs: Commits ====
   
   
Commits sind das Hauptelement der Arbeit mit Git. Jeder Branch ist eine bestimmte Abfolge von Commits. Verschiedene Branches unterscheiden sich dadurch, welche Commits sie enthalten. Ein Commit ist ein Patch, der eine oder mehrere Dateien verändert, hinzufügt und/oder löscht. Jeder Commit hat einen eindeutigen Hashcode, der im Log angezeigt wird. Über diesen Code lassen sich Commits einzeln herauspicken, rückgängig machen, als Diff anzeigen etc. Dabei genügt die Angabe der ersten paar Zeichen, sofern sie eindeutig sind; üblich als Kurzform sind die ersten 7-10 Zeichen.
Commits sind das Hauptelement der Arbeit mit Git. Jeder Branch ist eine bestimmte Abfolge von Commits. Verschiedene Branches unterscheiden sich dadurch, welche Commits sie enthalten. Ein Commit ist ein Patch, der eine oder mehrere Dateien verändert, hinzufügt und/oder löscht. Jeder Commit hat einen eindeutigen Hashcode, der im Log angezeigt wird. Über diesen Code lassen sich Commits einzeln herauspicken, rückgängig machen, als Diff anzeigen etc. Dabei genügt die Angabe der ersten paar Zeichen, sofern sie eindeutig sind; üblich als Kurzform sind die ersten 7-10 Zeichen.


Der letzte (neueste) Commit des aktiven Branches hat auch den Name HEAD, der vorletzte HEAD~1, der drittletzte HEAD~2 etc. Mit
Der letzte (neueste) Commit des aktiven Branches hat auch den Name HEAD, der vorletzte HEAD~1, der drittletzte HEAD~2 etc. Mit
  <code>git diff HEAD~1</code>
  git diff HEAD~1
kannst du dir z.B. alle Änderungen zwischen aktuellem und vorletztem Codestand anzeigen lassen - also genau das, was du mit deinem letzten <code>commit</code> eingecheckt hast.
kannst du dir z.B. alle Änderungen zwischen aktuellem und vorletztem Codestand anzeigen lassen - also genau das, was du mit deinem letzten <code>commit</code> eingecheckt hast.


Zeile 133: Zeile 135:
==== Zusammenfassung des OC-Git-Standard-Workflow ====
==== Zusammenfassung des OC-Git-Standard-Workflow ====
   
   
Neuen Branch für eine neue Aufgabe anlegen:
* Neuen Branch für eine neue Aufgabe anlegen
 
*# <code>git checkout development</code>
1. <code>git checkout development</code><br/>
*# <code>git pull upstream</code>
2. <code>git pull upstream</code><br/>
*# <code>git checkout -b 1234-new-feature</code>
3. <code>git checkout -b 1234-new-feature</code>
*: ... oder die Arbeit an einem bereits bestehenden Branch mit <code>git checkout 1234-new-feature</code> fortsetzen
... oder die Arbeit an einem bereits bestehenden Branch mit <code>git checkout 1234-new-feature</code> fortsetzen
* Programmierzyklen
 
*# Code schreiben
Programmierzyklen:
*# mit <code>git status</code> / <code>git diff</code> lokale Änderungen kontrollieren
 
*# Änderung mit <code>git add</code> / <code>git commit</code> ins lokale Repo einchecken
4. Code schreiben<br />
*# mit <code>git pull --rebase upstream development</code> auf aktuellen OC-Code aufsetzen
5. mit <code>git status</code> / <code>git diff</code> lokale Änderungen kontrollieren<br />
*# weiter bei 1, wenn der Code noch nicht fertig ist
6. Änderung mit <code>git add</code> / <code>git commit</code> ins lokale Repo einchecken<br />
* Hochladen
7. mit <code>git pull --rebase upstream development</code> auf aktuellen OC-Code aufsetzen<br />
*# <code>git push origin 1234-neues-Feature</code>
8. weiter bei 4, wenn der Code noch nicht fertig ist
*# ''Branch 1234-neues-Feature'' auf GitHub aufrufen und Pull Request starten
 
* Nicht mehr benötigte Branches löschen
Hochladen:
*# lokal: <code>git checkout development</code> / <code>git branch -d 1234-neues-Feature</code>
 
*# auf dem Fork: <code>git push origin :1234-neues-Feature</code>
9. <code>git push origin 1234-neues-Feature</code><br />
10. ''Branch 1234-neues-Feature'' im Github aufrufen und Pull Request starten
 
Nicht mehr benötigte Branches löschen:
 
11. lokal: <code>git checkout development</code> / <code>git branch -d 1234-neues-Feature</code><br />
12. auf dem Fork: <code>git push origin :1234-neues-Feature</code>


==== Commits zusammenfassen ====
==== Commits zusammenfassen ====
Zeile 191: Zeile 186:
* <code>git revert commit-ID</code>
* <code>git revert commit-ID</code>
* <code>git push</code>
* <code>git push</code>
* evt. Pull-Request auf dem Github, wenn es bereits im Upstream angekommen war
* evt. Pull-Request auf dem GitHub, wenn es bereits im Upstream angekommen war
   
   
Den Kommentar des letzten, noch nicht "gepushten" Commit korrigieren:  
Den Kommentar des letzten, noch nicht "gepushten" Commit korrigieren:  
Zeile 199: Zeile 194:
   
   
Wenn du z.B. den Branch ''1234-new-feature'' von Entwickler ''heinz'' testen möchtest, kannst du ihn in einen Testbranch bei dir herunterladen. Zunächst musst du ''heinz''' Fork einmalig als weitere Upstream definieren:
Wenn du z.B. den Branch ''1234-new-feature'' von Entwickler ''heinz'' testen möchtest, kannst du ihn in einen Testbranch bei dir herunterladen. Zunächst musst du ''heinz''' Fork einmalig als weitere Upstream definieren:
  git remote add heinz http://github.com/heinz/oc-server3
  git remote add heinz git@github.com:heinz/oc-server3
Dann legst du bei dir einen Testbranch an, am besten auf Basis aktuellster Daten ...
Dann legst du bei dir einen Testbranch an, am besten auf Basis aktuellster Daten ...
  git checkout development
  git checkout development
Zeile 228: Zeile 223:


== Noch ein paar Gimmicks ==
== Noch ein paar Gimmicks ==
<code>git diff Branchname</code>
zeigt alle Unterschiede zwischen dem aktuellen Branch und einem anderen an.
<code>git cherry-pick Commit-ID</code>
übernimmt einen bestimmten Commit (von wo auch immer) in den aktiven Branch.
<code>git diff --name-only --diff-filter=U</code>
zeigt eine Liste aller konfliktbehafteten Dateien nach einem Merge an
<code>git gc</code>
führt eine [http://de.wikipedia.org/wiki/Garbage_Collection Garbage Collection] durch und gibt Platz im lokalen Repository frei. Per <code>git reset --hard</code> oder <code>git branch -d</code> gelöschte Commits werden damit endgültig weggeworfen (vorher sind sie via <code>git reflog</code> noch wiederherstellbar).
<code>git grep Suchbegriff</code>
durchsucht den Code des aktuellen Verzeichnisbaums; für zahlreiche Optionen siehe Git-Doku.
<code>git help Kommando</code>


zeigt die Doku für ein Git-Kommando an.
* <code>git diff Branchname</code> zeigt alle Unterschiede zwischen dem aktuellen Branch und einem anderen an.
* <code>git cherry-pick Commit-ID</code> übernimmt einen bestimmten Commit (von wo auch immer) in den aktiven Branch.
* <code>git diff --name-only --diff-filter=U</code> zeigt eine Liste aller konfliktbehafteten Dateien nach einem Merge an
* <code>git gc</code>  führt eine [http://de.wikipedia.org/wiki/Garbage_Collection Garbage Collection] durch und gibt Platz im lokalen Repository frei. Per <code>git reset --hard</code> oder <code>git branch -d</code> gelöschte Commits werden damit endgültig weggeworfen (vorher sind sie via <code>git reflog</code> noch wiederherstellbar).
* <code>git grep Suchbegriff</code> durchsucht den Code des aktuellen Verzeichnisbaums; für zahlreiche Optionen siehe Git-Doku.
* <code>git help Kommando</code> zeigt die Doku für ein Git-Kommando an.


== Forenbeiträge zu Git ==
== Forenbeiträge zu Git ==

Navigationsmenü