Git Pull Request enthält fremde Commits

Vielleicht ist das euch auch schon mal passiert. Mir jedenfalls passiert das immer mal wieder mal. Ich checke in ein Branch ein um zum Beispiel ein Code Review vorzunehmen. Nachdem ich fertig bin, schnappe ich mir ein Ticket und eröffne einen neuen Feature Branche. Der eine oder andere ahnt bestimmt schon, worauf ich hinaus will? Richtig – ich habe meinen neuen Feature Branch aus einem Feature Branch eröffnet. In der Regel macht man aber das so nicht. Sondern man eröffnet meistens einen neuen Branch aus dem Master heraus. Es gibt Ausnahmen, dass so zu machen. Auf die Ausnahmen werde ich aber in diesem Artikel nicht näher eingehen. In den meisten Fällen führt aber der neu eröffnete Branch aus einem anderen Branch, zu Verwirrung. Spätestens beim Pull-Request.

So war es auch bei mir mit der Verwirrung. Nachdem ich meine Arbeiten an dem neuen Ticket vollendet habe commitete ich diese Änderungen und machte dann über die Konsole meinen push mit:

git push -u origin feature/xy-99
// oder
git push --set-upstream origin feature/xy-99 

Dann erhalte ich mein PR Link um diesen zu erstellen. Beim erstellen stelle ich dann mit schrecken fest. „Kacke! Da sind ja noch die Commits meines Kollegen drin.“ Wie gehen wir vor, bevor die Klugscheißer Kollegen auf Dein Pull-Request aufmerksam werden? Es gibt mehrere Möglichkeiten die Situation zu entspannen. Folgende Notfallbehandlung kann genutzt werden.

Folgendes Ausgangsszenario: (Ihr habt bereits ein PR für feature-99 gestellt und dort findet ihr die Commits des Kollegen)

Stack: Bitbucket

(local) git branch(remote) git branch
mastermaster
developmentdevelopment
feature-1feature-1
feature-2feature-2
feature-99feature-99*
* hier sind die Commits drin vom feature-2 Branch

Ein möglicher Lösungsansatz:

Wir löschen den PR über die UI (Bitbucket). Lokal wechseln wir auf den Master.

git checkout feature-99  
git log
// *schreibe dir die ersten 4 Zahlen deines Commits auf
Git checkout master
git branch -D/-d feature-99
git checkout -b feature-99
git cherry-pick "f12d*" // *die ersten vier Zahlen deines Commits
git push -u origin feature-99 –force
// dann erstellst Du wie gewohnt den Pull-Request 

Git branch -d
Das löschen eines Branches machst Du mit git branch -d <branch-name>. Falls der Branch Jungfreudig ist und noch nicht gemerged oder gepusht wurde, wir bei dem Flag -d („kleines d“) ein Git Error kommen. Git möchte dich somit bewahren, Deine commiteten Daten zu verlieren. Falls Du dir sicher bist, dass Du das willst, kannst Du den Branch mit -D „großes D“ löschen. Falls schon gemerged oder gepusht genügt das kleine D.

Git cherry-pick
Mit git cherry-pick kannst Du andere Commits anhand ihres Selektors (Commit ID) in deinen Branch holen. Das Prizip ist einwenig wie das git stashing zu verstehen. Cherry Pick setzt dir den anderen Commit einfach in dein Branch rein. Du musst nicht einmal adden und commiten. Git Status ist clean. Ich finde git Cherry Pick abgefahren und sehr nützlich. In unserem Fall holen wir uns unsere Änderungen in den neuen Branch.

Das war ein Weg nach Rom. Mich würde interessieren wie ihr das so macht. Schreibt mir einfach in den Kommentaren und ich werde drauf eingehen.

Git Commit Message Regeln

Lange Zeit war mir das auch nicht klar, dass es Regeln für Git Commit Messages gibt. Wie sinnvoll die Regeln sind erschließt sich spätestens dann wenn man in größeren Teams arbeitet. Diese 7 Regeln möchte ich euch hier kurz erklären. Die Regel hat der Softwareentwickler Chris Beams vor einiger Zeit erstellt und auf seinem Blog veröffentlicht. https://chris.beams.io/posts/git-commit/

  • Ausgehend davon, dass gut geschriebene Commit Nachrichten der beste Weg ist, um Kollegen (aber auch sich selbst) den Kontext einer Änderung mitzuteilen. Der Code bzw. ein git diff wird dir zeigen, was sich genau geändert hat, aber eine Commit Nachricht wird dir sagen warum sich das geändert hat.
  • Trennen Sie den Betreff vom Text mit einer Leerzeile
  • Begrenzen Sie die Betreffzeile auf 50 Zeichen
  • Starten Sie Betreffzeilen immer mit einem Großbuchstaben
  • Beenden Sie die Betreffzeile nie mit einem Punkt
  • Verwenden Sie den Imperativ in der Betreffzeile und nicht die Vergangenheitsform
  • Umfassen Sie den Textkörper mit 72 Zeichen
  • Erklären Sie im Textkörper das Was und Warum, nicht das Wie

<type>[optional scope]<description>

feat(IAD-123): Add type for something.

<type>
Die zwei gängigsten Typen wären fix und feat. Aber es gibt noch weitere:

  • fix (Nutzt du beim Bugfixing) |
  • feat(nutzt du bei code features)
  • build
  • docks
  • style
  • refactor
  • test
  • chore
  • ci

[optional scope]
Sind zusätzliche Infos wie zum Beispiel eine Ticketnummern oder ähnliches.


<description>
Hier schreibst Du eine kurze Nachricht rein. Nachrichten können sich zusammensetzen aus Betreff, Body, Fußnot. In den meisten Fällen genügt eine Betreffzeile. Im Optionalen Body schreibst Du dann ausführlich deine Änderungen rein und vor allem warum du diese gemacht hast. In der Fußnote kannst Du Tickets mit Hashtags angeben um dem Leser mehr Backgroundinformationen zu liefern.

Eine kleine Eselsbrücke für den Anfang: Du fängst den Commitsatz imaginär an: Dieser Commit möchte update readme file with new thinks.

Git – Neuen Branch verwerfen / löschen

Es kommt vor, dass man ein Feature für ein Projekt entwickeln soll und man zuerst ausprobiert was so geht. Ihr arbeitet an einem Remote Repository und entwickelt lokal. Dann schnell mal ein composer update und die composer.lock ist geändert. Ihr wollt am liebsten den ganzen Branch verwerfen und zum Step zurück wo ihr angefangen habt. Ohne Git wäre das jetzt STRESS-PANIK Deluxe. Mit Git super entspannt.

Es gibt natürlich wieder mal mehrere Lösungswege. Ich stelle hier zwei vor:

  1. Der einfachste und schnellste Weg

In seid in dem Branch wo Ihr die Änderungen gemacht habt und ihr aber nicht haben wollt. Dann folgenden Git Command abfeuern:

git reset --hard HEAD 

2. Der Lange Weg – aber derhaut auch den ganzen Branche in die Tone

Ein andere Weg wäre nun den gesamten neuen Branch zu entfernen. Wenn ihr euch noch nicht im neuem Branch bewegt könnt ihr mit git checkout neuer_branch in den branch rein. Dann mit git add. && git commit-“Änderungen sind ins leere gelaufen, daher wird dieser branch gelöscht“.

Mit:

git branch -D neuer_branch 

löscht ihr den Branch.

Fazit:

Beide Wege sind legitim. Ich nutze aber meistens den ersten Weg (git reset –hard HEAD) weil ich zu 99% den Branch weiter nutzen will.

Gitignore nachträglich ins Repository hinzufügen

Der Artikel geht davon aus, dass ihr wisst was eine Versionsverwaltungssoftware ist. Ihr solltet auch die Git Grundbefehle wie init, add, commit kennen. Was immer wieder mal, auch bei Erfahrenden Codern, vorkommt ist das kleine .gitignore Chaos. Stellt Euch vor ihr habt bereits euer Initialcommit auf euer Repository gepusht. Dann stellt ihr fest: „Mist in meinem Projekt-Root Verzeichnis liegt ja meine devnotes.txt! Mit den ssh Zugängen und meinen Arztterminen, weil ich zu faul war das mir in mein Kalender zu hacken. Nicht schon wieder! f*c*!“ Wenn ihr wüsstet, was manche Entwickler so alles in ihrer Todolisten schreiben.

Nun haben wir augenscheinlich erst mal ein Problem. Aber das ist schnell gelöst.

Schritt 1: .gitignore Datei anlegen

Falls noch nicht geschehen, legt mit touch .gitignore im Projektroot die neue Datei an. Öffnet diese und schreibt die gewünschten Dateien oder auch Verzeichnisse rein, die zukünftig nichts mehr ins Repository gepusht werden sollen. In dem fiktiven Beispiel wäre es dann devnotes.txt.

#! das gehört in eure .gitignore Datei rein
# ignore theses files
devnotes.txt
# ignore theses folders
node_modules/

Dann erst mal:

git add . && git commit -m”added gitignore”
git push origin master

Wenn ihr im Team arbeitet müsst ihr vom Repro erst mal pullen. Allerdings muss dir hier dann bewusst sein, dass nun sehr wahrscheinlich dein Team deine Einkaufsliste kennt.

Schritt 2: Lösche die zu ignorierende Datei aus dem Repository

Jetzt haben wir eine gitignore die unsere devnotes.txt nicht mehr berücksichtigt. Aber das Problem ist hier noch nicht ganz gelöst. Ihr müsst nun die devnotes.txt aus dem Repository entfernen. Das machen wir mit:

git rm --cached devnotes
git commit -m”remove devnotes from repository ;-)”
git push origin master

Ein Fallstrick hier wäre die Commit Message. Diese verrät anderen nun, dass im Repository deine devnotes.txt liegen. Vielleicht sollte eure Commit-Message in diesem Fall etwas kryptischer ausfallen als sonst.

Ansonsten wäre wir nun hiermit durch und Problem gelöst.

SeoTheater Autoren