Schlagwort-Archive: Git

Meine tägliche Portion Git – Ambiguous Refname

Kürzlich habe ich aus versehen einen Branch namens “Head” angelegt. Im Anschluss bekam ich immer folgende Warning von Git:

warning: refname ‚HEAD‘ is ambiguous.image

Über “git show-ref” habe ich mir alle Referenzen anzeigen lassen. Folgerichtig war dieser dort auch aufgelistet. Head ist allerdings ein reservierter Name, der immer dem Pointer des aktuell verwendeten Branches entspricht. In diesem Artikel habe ich bereits dazu gebloggt.

Das Problem hat übrigens jemand bereits hier beschrieben. Um das Ganze abzukürzen. Wenn ihr den Branch über “git branch -d head” löscht, ist alles wieder in Butter.

Advertisements

Meine tägliche Portion Git

Heute habe ich auf Grund einer Unachtsamkeit einen falschen Merge getätigt. Die Folge war, dass mein Stand nach dem Rebase fehlte. Konkret kann euch dies passieren, wenn ihr beispielsweise an einer Klasse entwickelt, die Änderungen eincheckt und euch dann das aktuelle Repository über einen Pull zieht. Hat nun ein anderer Entwickler ebenfalls etwas an dieser Datei geändert, so schlägt das Mergen fehl und ihr seid in eurem Branch abgezweigt. In der Regel löst man dies, indem man manuell mergt. Danach führt man über “git rebase –continue” das Zusammenführen des Remote Repository und eures lokalen Repository zu Ende. Stell ihr nun fest, dass ihr falsch gemergt habt, könnt ihr nicht ohne weiteres eure Datei wiederherstellen.

In dem Falle ruft ihr “git reflog” auf. In dem Falle seht ihr alle je getätigten Commits.

image

Nun könnt ihr über “git reset –hard SHA” auf den commit zurück, den ihr vor dem Rebasing hattet. SHA entspricht dabei dem SHA eures Commits. Danach könnt ihr erneut pullen und korrekt mergen.

Meine tägliche Portion Git

Here are some Git Aliases of mine. Just insert them in the "[alias]” section into your global .gitconfig, usually placed in your home directory.

   1: review = log -1 --patch

   2: unstage = reset head

   3: aa = add --all

   4: au = add --update

   5: s = status

   6: p = pull

   7: l = log --oneline -10

   8: k = !gitk --all & --all &

   9: aua = !git add --update && git commit --amend --reuse-message=HEAD

  10: aaa = !git add --all && git commit --amend --reuse-message=HEAD

  11: amend = commit --amend --reuse-message=HEAD

  12: aac = !sh -c 'git add --all && git commit -m \"$1\"' -

  13: aucp = !sh -c 'git add --update && git commit -m \"$1\" && git push' -

  14: aacp = !sh -c 'git add --all && git commit -m \"$1\" && git push' -

From now on, you can type in your git bash

git aacp “commit message”

in order to add all, commit and push your respository.

Meine tägliche Portion Git

Wer eine Änderung gepusht hat und diese rückgängig machen will, sollte wie folgt vorgehen:

  • Gleich alle Entwickler informieren, dass sie nicht mehr pullen sollen (idealerweise hat noch niemand den neuen Stand gepullt!)
  • Über den Befehl “git reset —hard head~1” (geht eine Revision zurück) oder über “git reset —hard  fa0f23d” (wobei fa0f23d dem SHA des Commits entspricht, auf den man zurück will), könnt ihr zunächst lokal den gewünschten Stand wiederherstellen. Über git log könnt ihr auch die Historie anschauen.
  • Danach setzt ihr mit “git push -f origin master” das öffentliche Repository zurück

Anmerkung: Das funktioniert z.B. nicht, wenn der entsprechende Developer nicht die benötigten Rechte hat oder Git so eingestellt ist, dass es “git push -f” nicht zulässt. Wie ihr dieses Problem löst und einen alternativen Weg findet ihr hier (Eintrag 2 anschauen!).

Meine tägliche Portion Git

Wer eigene Merge Tools in Git verwenden will, der muss ein paar Kleinigkeiten beachten:

1. %userprofile%\.gitconfig anpassen: Neuer Abschnitt für das Mergetool der eigenen Wahl anlegen

[mergetool "P4"]
    cmd = /Pfad/p4merge-merge.sh \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
    trustExitCode = true

Gegebenenfalls auch unter [merge] dieses als Standard definieren:

[merge]
    tool = P4
    log = true

 

2. Shell-Skript schreiben und dort ablegen, worauf ihr in der .gitconfig verwiesen habt

#!/bin/sh
script_dir=/Pfad

local="$($script_dir/cygpath –mixed –absolute "$2")"
base="$($script_dir/cygpath –mixed –absolute "$1")"
baseUnixFormat="$($script_dir/cygpath –unix –absolute "$1")"
remote="$($script_dir/cygpath –mixed –absolute "$3")"
result="$($script_dir/cygpath –mixed –absolute "$4")"
tool="/Pfad/P4Merge/p4merge.exe"

if [ ! -f "$baseUnixFormat" ]
then
    base="$($script_dir/cygpath –mixed –absolute $script_dir/p4merge-empty.txt)"
fi

"$tool" "$local" "$remote" "$base" "$result"

 

Achtet genau auf die Pfade! Für Teams bietet sich an, dass man alle Tools und Skripte ins Repository mit aufnimmt. Danach erstellt man ein symbolisches Verzeichnis auf der Platte, welches bei jedem Entwickler auf den Pfad des Repository verweist. Wir haben uns z.B. darauf verständigt, dass jeder Entwickler ein Verzeichnis D:\Development\Repository haben muss. Bei mir zeigt das dann beispielsweise auf G:\heco\comwork. Bei dem Kollegen wiederum auf einen anderen Pfad. Aber da wir mit dem symbolischen Verzeichnis arbeiten, können wir alle die Skripte und Tools verwenden ohne sie anpassen zu müssen. Da die Git\.gitconfig wiederum pro Entwickler konfiguriert wird, kann trotzdem jeder das Merge Tool seiner Wahl als Standard einstellen.

Noch zwei wichtige Punkte:

  • Im Pfad muss eine p4merge-empty.txt liegen, sonst schmeißt das Skript einen Fehler. Die Dateien wird verwendet, wenn es beim Merge keine gemeinsame Basis gibt, also statt /dev/null. Damit haben die meisten Programme und Windows Probleme.
  • Ich verwende das Kommandozeilentool cygpath (Teil von cygwin), um Windows Pfade in Unix Pfade zu konvertieren. Wenn ihr dieses nicht verwendet, dann müsst ihr die Befehle abändern und alle Pfadangaben im Unix Format angeben.

Weiterführender Link zum Blogeintrag von agross.

Meine tägliche Portion Git

Gehen wir davon aus, dass wir lokal 2 Branches haben mit den Namen Branch1 und Branch2. Dann sind beide Branches unter zwei Namen zu erreichen.

image

Dem eigentlichen Alias, sprich der Branch Name, z.B. Branch1. Außerdem unter dem eindeutigen SHA. Sprich folgende Befehle sind syntaktisch gleich:

  • git checkout Branch1
  • git checkout 56789

Mit git checkout wechselt man zwischen Branches. Steht man aktuell auf Branch1, so ist dieser noch unter einem dritten Alias erreichbar: HEAD.

Wenn ich nun über git checkout Branch2 mache, so wechselt der HEAD Pointer auf Branch2, sodass Branch1 nur noch unter 2 Namen erreichbar ist, wohingegen Branch2 nun 3 Namen hat: Den SHA, Branch2 und HEAD.

Gut zu wissen: Über git reflog kann man sich die komplette Historie von HEAD anzeigen, sprich alle Änderungen die man auf jedem Branch, auf dem man jemals war, anzeigen lassen und ggf. darauf wechseln.

Lokale Branches lässt man sich über git branch anzeigen, Remote Branches über git branch –r (git branch –a listet lokale und remote Branches auf). Wichtig zu wissen: Per Default sind Branches, die man anlegt, lokal. Über git push origin branchname -u (funktioniert immer, egal wo man steht) kann man den Branch veröffentlichen. Wird ein Branch veröffentlicht, so wird er auch in die .git/config (sprich die Repository spezifische config) eingetragen! Bei lokalen ist dies nicht der Fall. Wenn ein Kollege einen Branch veröffentlicht hat, so kann man diesen sich lokal ziehen:

  • git fetch (lädt erst mal eine lokale Kopie des Origin Repository runter)
  • git checkout –b lokalername –track origin/remotename

ziehen.

Mit git checkout –b name erzeugt man übrigens einen lokalen Branch.

Git Bash Standardpfad ändern

Standardmäßig startet die Git Bash, wenn man sie startet, im Benutzerverzeichnis. Dies lässt sich ändern, wenn man dort eine Datei namens “.bashrc” anlegt (Dateierweiterungen müssen aktiviert sein!). Dort kann man dann einen cd-Befehl eintragen, z.B.:

cd /d/development/comwork

Danach startet die Bash immer in diesem Verzeichnis. Wenn das Verzeichnis nicht existiert, dann wird wieder das Benutzerverzeichnis genommen.

image

Übrigens könnt ihr hier auch Aliase eintragen, wie z.B.

alias g=’git’

So spart ihr euch täglich mehrfach das Tippen von 2 Buchstaben. Da kann einiges zusammenkommen, wenn man sehr Bash-affin arbeitet Smiley

 

Zu guter Letzt noch einen Vorschlag: Statt die .bashrc ins Benutzerverzeichnis zu legen, würde ich einen symbolischen Link einrichten. Dazu macht ihr die Windows Kommandozeile auf und tragt folgendes ein:

mklink .bashrc D:\DevelopmentSettings\.bashrc

Persönlich verwende ich das auch für ReSharper und Git Settings. So kann ich mir meine Settings über mehrere Plattformen synchronisieren.

%d Bloggern gefällt das: