Kapitel 1. Einführung in Git
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
Einfach ausgedrückt, ist Git ein Content Tracker. Damit hat Git die gleichen Prinzipien wie die meisten Systeme zur Versionskontrolle. Das Besondere an Git ist jedoch, dass es ein verteiltes Versionskontrollsystem ist, das sich von der Vielzahl der heute verfügbaren Tools abhebt. Das bedeutet, dass Git schnell und skalierbar ist, über eine umfangreiche Sammlung von Befehlen verfügt, die sowohl High-Level- als auch Low-Level-Operationen ermöglichen, und für lokale Operationen optimiert ist.
In diesem Kapitel lernst du die Grundprinzipien von Git, seine Eigenschaften und die grundlegenden git
Befehle kennen und erhältst eine kurze Anleitung zum Erstellen und Hinzufügen von Änderungen zu einem Repository.
Wir empfehlen dir dringend, dir Zeit zu nehmen, um die wichtigen Konzepte zu verstehen, die hier erklärt werden. Diese Themen sind die Bausteine von Git und helfen dir, die mittleren und fortgeschrittenen Techniken für die Verwaltung eines Git-Repositorys im Rahmen deiner täglichen Arbeit zu verstehen. Diese grundlegenden Konzepte werden dir auch dabei helfen, dein Wissen zu erweitern, wenn wir das Innenleben von Git in den Kapiteln von Teil II, "Grundlagen von Git", Teil III, "Mittlere Fertigkeiten", und Teil IV, "Fortgeschrittene Fertigkeiten", aufschlüsseln.
Git Komponenten
Bevor wir in die Welt der git
Befehle eintauchen, wollen wir einen Schritt zurücktreten und uns einen Überblick über die Komponenten verschaffen, aus denen das Git-Ökosystem besteht. Abbildung 1-1 zeigt, wie die Komponenten zusammenarbeiten.
Git-GUI-Tools dienen als Frontend für die Git-Befehlszeile, und einige Tools haben Erweiterungen, die sich in gängige Git-Hosting-Plattformen integrieren lassen. Die Git-Client-Tools arbeiten meist mit der lokalen Kopie deines Repositorys.
Wenn du mit Git arbeitest, gehören zu einer typischen Einrichtung ein Git-Server und Git-Clients. Du kannst auch auf einen Server verzichten, aber das würde die Pflege und Verwaltung von Repositories beim Austausch von Revisionsänderungen in einer kollaborativen Umgebung komplizierter machen und die Konsistenz erschweren (wir werden in Kapitel 11 darauf zurückkommen). Der Git-Server und die Clients funktionieren wie folgt:
- Git-Server
-
Ein Git-Server ermöglicht dir eine einfachere Zusammenarbeit weil er die Verfügbarkeit einer zentralen und zuverlässigen Quelle der Wahrheit für die Repositories, an denen du arbeitest, gewährleistet. Ein Git-Server ist auch der Ort, an dem deine entfernten Git-Repositories gespeichert werden; wie es üblich ist, verfügt das Repository über die aktuellste und stabilste Quelle deiner Projekte. Du hast die Möglichkeit, einen eigenen Git-Server zu installieren und zu konfigurieren, oder du kannst auf den Aufwand verzichten und deine Git-Repositorys auf zuverlässigen Hosting-Seiten von Drittanbietern wie GitHub, GitLab und Bitbucket hosten lassen.
- Git Clients
-
Git-Clients interagieren mit deinen lokalen Repositories, . Du kannst mit Git-Clients über die Git-Befehlszeile oder die Git-GUI-Tools interagieren. Wenn du einen Git-Client installierst und konfigurierst, kannst du auf die entfernten Repositories zugreifen, an einer lokalen Kopie des Repositories arbeiten und Änderungen an den Git-Server übertragen. Wenn du Git noch nicht kennst, empfehlen wir dir, mit der Git-Befehlszeile zu beginnen. Mach dich mit den gängigen
git
Befehlen vertraut, die du für deine tägliche Arbeit benötigst, und gehe dann zu einem Git-GUI-Tool deiner Wahl über.
Der Grund für diesen Ansatz ist, dass Git GUI-Tools bis zu einem gewissen Grad dazu neigen, Terminologien bereitzustellen, die ein gewünschtes Ergebnis darstellen, das möglicherweise nicht Teil der Standardbefehle von Git ist. Ein Beispiel wäre ein Werkzeug mit einer Option namens sync
, hinter der sich die Verkettung von zwei oder mehr git
Befehlen verbirgt, um ein gewünschtes Ergebnis zu erzielen. Wenn du aus irgendeinem Grund den Unterbefehl sync
in die Befehlszeile eingibst, könntest du diese verwirrende Ausgabe erhalten:
$ git sync git: 'sync' is not a git command. See 'git --help'. The most similar command is svn
Hinweis
git sync
ist kein gültiger git
Unterbefehl. Um sicherzustellen, dass deine lokale Arbeitskopie des Repositorys mit den Änderungen des entfernten Git-Repositorys synchronisiert ist, musst du eine Kombination dieser Befehle ausführen: git fetch
, git merge
, git pull
, oder git push
.
Es gibt eine Fülle von Tools, die dir zur Verfügung stehen. Einige Git-GUI-Tools sind ausgefallen und über ein Plug-in-Modell erweiterbar, das dir die Möglichkeit bietet, Funktionen von beliebten Git-Hosting-Sites von Drittanbietern einzubinden und zu nutzen. So bequem es auch sein mag, Git über ein GUI-Tool zu erlernen, werden wir uns bei den Beispielen und Code-Diskussionen auf das Git-Befehlszeilen-Tool konzentrieren, da dies ein gutes Grundwissen schafft, das zu Git-Geschicklichkeit führt.
Git Merkmale
Nachdem wir nun einen Überblick über die Git-Komponenten gegeben haben,, wollen wir uns nun mit den Eigenschaften von Git beschäftigen. Wenn du diese besonderen Eigenschaften von Git verstehst, kannst du mühelos von einer zentralen Versionskontrolle zu einer verteilten Versionskontrolle wechseln. Wir bezeichnen dies als "Denken in Git":
- Git speichert Revisionsänderungen als Snapshots
-
Das erste Konzept, das du verlernen musst, ist die Art und Weise, wie Git mehrere Revisionen einer Datei speichert, an der du gerade arbeitest. Im Gegensatz zu anderen Versionskontrollsystemen zeichnet Git Änderungen nicht als eine Reihe von Änderungen auf, die auch als Deltas bezeichnet werden, sondern erstellt einen Schnappschuss der Änderungen, die zu einem bestimmten Zeitpunkt am Zustand deines Projektarchivs vorgenommen wurden. In der Git-Terminologie wird dies als Commit bezeichnet. Stell dir vor, du hältst einen Moment in der Zeit fest, wie bei einem Foto.
- Git wird für die lokale Entwicklung verbessert
-
In Git arbeitest du an einer Kopie des Repositorys auf deinem lokalen Entwicklungsrechner. Dies wird als lokales Repository oder als Klon des entfernten Repositorys auf einem Git-Server bezeichnet. Dein lokales Repository enthält die Ressourcen und die Snapshots der Revisionsänderungen, die an diesen Ressourcen vorgenommen wurden, an einem Ort. Git nennt diese Sammlungen von verknüpften Snapshots Repository Commit History oder kurz Repo History. So kannst du auch in einer unverbundenen Umgebung arbeiten, da Git keine ständige Verbindung zum Git-Server benötigt, um deine Änderungen zu kontrollieren. So kannst du auch in verteilten Teams an großen, komplexen Projekten arbeiten, ohne dass die Effizienz und Leistung der Versionskontrolle darunter leidet.
- Git ist endgültig
-
Definitiv bedeutet, dass die
git
Befehle explizit sind. Git wartet darauf, dass du Anweisungen gibst, was zu tun ist und wann es zu tun ist. Git synchronisiert zum Beispiel nicht automatisch Änderungen aus deinem lokalen Projektarchiv mit dem entfernten Projektarchiv und speichert auch nicht automatisch einen Schnappschuss einer Revision in deiner lokalen Projektarchiv-Historie. Jede Aktion erfordert einen expliziten Befehl oder eine Anweisung von dir, um Git mitzuteilen, was erforderlich ist, z. B. das Hinzufügen neuer Commits, das Korrigieren bestehender Commits, das Verschieben von Änderungen aus deinem lokalen Projektarchiv in das Remote-Repository und sogar das Abrufen neuer Änderungen aus dem Remote-Repository. Kurz gesagt, du musst deine Handlungen mit Bedacht ausführen. Dazu gehört auch, dass du Git mitteilst, welche Dateien du verfolgen willst, denn Git fügt nicht automatisch neue Dateien zur Versionskontrolle hinzu. - Git soll die nichtlineare Entwicklung unterstützen
-
Mit Git kannst du Ideen entwickeln und mit verschiedenen Implementierungen von Funktionen experimentieren, um praktikable Lösungen für dein Projekt zu finden, indem du parallel an der stabilen Hauptcodebasis deines Projekts arbeitest und dich verzweigst. Diese Methode, die als Verzweigung bezeichnet wird, ist eine weit verbreitete Praxis, die die Integrität der Hauptentwicklungslinie sicherstellt und versehentliche Änderungen verhindert, die sie zerstören könnten.
In Git gilt das Konzept der Verzweigung als leichtgewichtig und kostengünstig, weil ein Branch in Git nur ein Verweis auf den letzten Commit in einer Reihe von verknüpften Commits ist. Für jeden Zweig, den du erstellst, merkt sich Git die Reihe der Commits für diesen Zweig. Du kannst lokal zwischen den Zweigen wechseln. Git stellt dann den Zustand des Projekts auf den letzten Zeitpunkt zurück, als der Snapshot des angegebenen Zweigs erstellt wurde. Wenn du dich entscheidest, die Änderungen aus einem beliebigen Zweig in die Hauptentwicklungslinie einzubringen, kann Git diese Reihen von Commits mithilfe von Techniken zusammenführen, die wir in Kapitel 6 besprechen werden.
Tipp
Da Git viele Neuerungen bietet, solltest du bedenken, dass die Konzepte und Praktiken anderer Versionskontrollsysteme möglicherweise anders funktionieren oder in Git gar nicht anwendbar sind.
Die Git-Befehlszeile
Die Kommandozeilenschnittstelle von Git ist einfach zu bedienen. Sie ist so konzipiert, dass du die volle Kontrolle über dein Repository hast. Daher gibt es viele Möglichkeiten, das Gleiche zu tun. Indem wir uns auf die Befehle konzentrieren, die für deine tägliche Arbeit wichtig sind, können wir sie vereinfachen und tiefergehend lernen.
Für den Anfang tippen Sie einfach git version
oder git --version
auf ein, um festzustellen, ob dein Rechner bereits mit Git vorgeladen ist. Du solltest eine ähnliche Ausgabe wie die folgende sehen:
$ git --version git version 2.37.0
Wenn du Git noch nicht auf deinem Rechner installiert hast, lies bitte in Anhang B nach, wie du Git entsprechend deiner Betriebssystemplattform installieren kannst, bevor du mit dem nächsten Abschnitt fortfährst.
Nach der Installation gibst du git
ohne Argumente ein. Git listet dann seine Optionen und die gängigsten Unterbefehle auf:
$ git usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] [--super-prefix=<path>] [--config-env=<name>=<envvar>] <command> [<args>] These are common Git commands used in various situations: start a working area (see also: git help tutorial) clone Clone a repository into a new directory init Create an empty Git repository or reinitialize an existing one work on the current change (see also: git help everyday) add Add file contents to the index mv Move or rename a file, a directory, or a symlink restore Restore working tree files rm Remove files from the working tree and from the index examine the history and state (see also: git help revisions) bisect Use binary search to find the commit that introduced a bug diff Show changes between commits, commit and working tree, etc grep Print lines matching a pattern log Show commit logs show Show various types of objects status Show the working tree status grow, mark and tweak your common history branch List, create, or delete branches commit Record changes to the repository merge Join two or more development histories together rebase Reapply commits on top of another base tip reset Reset current HEAD to the specified state switch Switch branches tag Create, list, delete or verify a tag object signed with GPG collaborate (see also: git help workflows) fetch Download objects and refs from another repository pull Fetch from and integrate with another repository or a local branch push Update remote refs along with associated objects 'git help -a' and 'git help -g' list available subcommands and some((("git help command"))) concept guides. See 'git help <command>' or 'git help <concept>' to read about a specific subcommand or concept. See 'git help git' for an overview of the system.
Tipp
Eine vollständige Liste der git
Unterbefehle findest du, indem du git help --all
.
Wie du aus dem Verwendungshinweis ersehen kannst, gilt eine kleine Handvoll von Optionen für git
. Die meisten Optionen, die im Hinweis als [ARGS]
angezeigt werden, gelten für bestimmte Unterbefehle.
Die Option --version
wirkt sich zum Beispiel auf den Befehl git
aus und erzeugt eine Versionsnummer:
$ git --version git version 2.37.0
Im Gegensatz dazu ist --amend
ein Beispiel für eine Option, die spezifisch für den git
Unterbefehl commit
ist:
$ git commit --amend
Manche Aufrufe erfordern beide Formen von Optionen (hier dienen die zusätzlichen Leerzeichen in der Befehlszeile nur dazu, den Unterbefehl optisch vom Basisbefehl zu trennen und sind nicht erforderlich):
$ git --git-dir=project.git repack -d
Der Einfachheit halber ist die Dokumentation für jeden git
Unterbefehl unter git help subcommand
, git --help subcommand
, git subcommand --help
, oder verfügbar. man git-subcommand
.
Hinweis
Die vollständige Git-Dokumentation ist online.
In der Vergangenheit wurde Git als eine Suite von vielen einfachen, eigenständigen Befehlen bereitgestellt, die nach der Unix-Philosophie entwickelt wurden: kleine, interoperable Tools zu bauen. Jeder Befehl trug einen Namen mit Bindestrich, z. B. git-commit
und git-log
.
Moderne Git-Installationen unterstützenjedoch nicht mehr die Befehlsformen mit Bindestrich und verwenden stattdessen eine einzelne git
ausführbare Datei mit einem Unterbefehl.
Die Befehle git
verstehen sowohl "kurze" als auch "lange" Optionen. Der Befehl behandelt zum Beispiel die folgenden Beispiele gleichwertig: git commit
$ git commit -m "Fix a typo." $ git commit --message="Fix a typo."
Die Kurzform, -m
, verwendet einen Bindestrich, die Langform, --message
, zwei. (Dies entspricht der GNU-Erweiterung für lange Optionen.) Einige Optionen gibt es nur in einer Form.
Tipp
Du kannst eine Commit-Zusammenfassung und eine detaillierte Nachricht für die Zusammenfassung erstellen, indem du die Option -m
mehrfach verwendest:
$ git commit -m "Summary" -m "Detail of Summary"
Schließlich kannst du Optionen von einer Liste von Argumenten durch einen einfachen Doppelstrich trennen. Verwende den Doppelstrich zum Beispiel, um den Steuerteil der Befehlszeile von einer Liste von Operanden, wie Dateinamen, zu unterscheiden:
$ git diff -w main origin -- tools/Makefile
Möglicherweise musst du den doppelten Bindestrich verwenden, um Dateinamen zu trennen und explizit zu kennzeichnen, damit sie nicht mit einem anderen Teil des Befehls verwechselt werden. Wenn du zum Beispiel zufällig sowohl eine Datei als auch einen Tag mit dem Namen main.c hast, musst du bei deinen Operationen absichtlich vorgehen:
# Checkout the tag named "main.c" $ git checkout main.c # Checkout the file named "main.c" $ git checkout -- main.c
Schnelle Einführung in die Verwendung von Git
Um Git in Aktion zu sehen, kannst du ein neues Repository erstellen, einige Inhalte hinzufügen und ein paar Revisionen verfolgen. Du kannst ein Repository auf zwei Arten erstellen: Entweder du erstellst ein Repository von Grund auf neu und füllst es mit Inhalten, oder du arbeitest mit einem bestehenden Repository, indem du es von einem entfernten Git-Server klonst.
Vorbereitungen für die Arbeit mit Git
Egal, ob du ein neues Repository erstellst oder mit einem bestehenden Repository arbeitest, es gibt einige grundlegende Konfigurationen, die du nach der Installation von Git auf deinem lokalen Entwicklungsrechner vornehmen musst. Das ist so, als würdest du bei einer neuen Kamera das richtige Datum, die richtige Zeitzone und die richtige Sprache einstellen, bevor du deinen ersten Schnappschuss machst.
Git verlangt mindestens deinen Namen und deine E-Mail-Adresse, bevor du deinen ersten Commit in deinem Repository machst. Die Identität, die du angibst, wird dann zusammen mit anderen Metadaten des Snapshots als Autor der Übertragung angezeigt. Du kannst deine Identität in einer Konfigurationsdatei speichern, indem du den Befehl git config
verwendest:
$ git config user.name "Jon Loeliger" $ git config user.email "jdl@example.com"
Wenn du dich entscheidest, deine Identität nicht in eine Konfigurationsdatei aufzunehmen, musst du deine Identität für jeden git commit
Unterbefehl angeben, indem du das Argument --author
am Ende des Befehls anhängst:
$ git commit -m "log message" --author="Jon Loeliger <jdl@example.com>"
Denke daran, dass dies der harte Weg ist, der schnell mühsam werden kann.
Du kannst auch deine Identität angeben, indem du deinen Namen und deine E-Mail-Adresse in den Umgebungsvariablen GIT_AUTHOR_NAME
und GIT_AUTHOR_EMAIL
angibst. Wenn diese Variablen gesetzt sind, setzen sie alle Konfigurationseinstellungen außer Kraft. Bei Angaben, die in der Befehlszeile gemacht werden, setzt Git jedoch die in der Konfigurationsdatei und der Umgebungsvariablen angegebenen Werte außer Kraft.
Arbeiten mit einem lokalen Repository
Nachdem du deine Identität konfiguriert hast, bist du bereit, mit einem Repository zu arbeiten. Beginne damit, ein neues leeres Repository auf deinem lokalen Entwicklungsrechner anzulegen. Wir fangen ganz einfach an und arbeiten uns dann zu den Techniken für die Arbeit mit einem gemeinsamen Repository auf einem Git-Server vor.
Erstellen eines ersten Repositorys
Wir werden eine typische Situation nachstellen, indem wir ein Repository für deine persönliche Website erstellen. Nehmen wir an, du fängst bei Null an und fügst Inhalte für dein Projekt in das lokale Verzeichnis ~/my_website ein, das du in ein Git-Repository stellst.
Gib die folgenden Befehle ein, um das Verzeichnis zu erstellen und einige grundlegende Inhalte in einer Datei namens index.html abzulegen:
$ mkdir ~/my_website $ cd ~/my_website $ echo 'My awesome website!' > index.html
Um ~/my_website in ein Git-Repository zu verwandeln, führe git init
aus. Hier geben wir die Option -b
gefolgt von einem Standardzweig namens main
an:
$ git init -b main Initialized empty Git repository in ../my_website/.git/
Wenn du es vorziehst, zuerst ein leeres Git-Repository zu initialisieren und ihm dann Dateien hinzuzufügen, kannst du dies mit den folgenden Befehlen tun:
$ git init -b main ~/my_website Initialized empty Git repository in ../my_website/.git/ $ cd ~/my_website $ echo 'My awesome website!' > index.html
Tipp
Du kannst ein komplett leeres Verzeichnis oder ein bestehendes Verzeichnis voller Dateien initialisieren. In beiden Fällen ist der Prozess der Umwandlung des Verzeichnisses in ein Git-Repository derselbe.
Der Befehl git init
erstellt ein verstecktes Verzeichnis namens .git auf der Stammebene deines Projekts. Alle Revisionsinformationen sowie unterstützende Metadaten und Git-Erweiterungen werden in diesem versteckten .git-Ordner auf oberster Ebene gespeichert.
Git betrachtet ~/my_website als das Arbeitsverzeichnis. Dieses Verzeichnis enthält die aktuelle Version der Dateien für deine Website. Wenn du Änderungen an bestehenden Dateien vornimmst oder neue Dateien zu deinem Projekt hinzufügst, speichert Git diese Änderungen im versteckten Ordner .git.
Zu Lernzwecken verweisen wir auf zwei virtuelle Verzeichnisse , die wir Local History und Index nennen, um das Konzept der Initialisierung eines neuen Git-Repositorys zu veranschaulichen. Wir werden die Local History und den Index in den Kapiteln 4 bzw. 5 besprechen.
Abbildung 1-2 veranschaulicht, was wir gerade erklärt haben:
. └── my_website ├── .git/ │ └── Hidden git objects └── index.html
Die gestrichelten Linien, die den lokalen Verlauf und den Index umgeben, stellen die versteckten Verzeichnisse innerhalb des .git-Ordners dar.
Hinzufügen einer Datei zu deinem Repository
Bis zu diesem Punkt hast du nur ein neues Git-Repository erstellt. Mit anderen Worten: Dieses Git-Repository ist leer. Obwohl die Datei index.html im Verzeichnis ~/my_website existiert, ist dies für Git das Arbeitsverzeichnis, eine Art Notizblock oder Verzeichnis, in dem du häufig deine Dateien änderst.
Wenn du die Änderungen an den Dateien abgeschlossen hast und diese Änderungen im Git-Repository ablegen möchtest, musst du dies explizit mit dem git add
file
Befehl:
$ git add index.html
Warnung
Obwohl du Git mit dem Befehl git add .
alle Dateien im Verzeichnis und allen Unterverzeichnissen hinzufügen lassen kannst, wird dadurch alles in das Verzeichnis eingefügt, und wir raten dir, genau zu überlegen, was du in das Verzeichnis einfügen willst. Um solche Informationen zu vermeiden, kannst du die Datei .gitignore verwenden, die in Kapitel 5 behandelt wird.
Das Argument .
, der einzelne Punkt oder Punkt in der Unix-Sprache, ist eine Kurzform für das aktuelle Verzeichnis.
Mit dem Befehl git add
versteht Git, dass du beabsichtigst, die letzte Iteration der Änderung an index.html als Revision in das Repository aufzunehmen. Bislang hat Git die Datei jedoch nur bereitgestellt, ein Zwischenschritt, bevor ein Snapshot per Commit erstellt wird.
Git trennt die Schritte add
und commit
, um Unbeständigkeit zu vermeiden und gleichzeitig Flexibilität und Granularität bei der Erfassung von Änderungen zu bieten. Stell dir vor, wie störend, verwirrend und zeitaufwändig es wäre, das Repository jedes Mal zu aktualisieren, wenn du eine Datei hinzufügst, entfernst oder änderst. Stattdessen können mehrere provisorische und zusammenhängende Schritte, wie z. B. das Hinzufügen einer Datei, zusammengefasst werden, wodurch das Projektarchiv in einem stabilen, konsistenten Zustand bleibt. Diese Methode ermöglicht es uns auch, eine Erklärung dafür zu finden, warum wir den Code ändern. In Kapitel 4 werden wir uns mit diesem Konzept näher befassen.
Wir empfehlen dir, logische Änderungsstapel zu gruppieren, bevor du eine Übergabe machst. Dies wird als atomare Übergabe bezeichnet und hilft dir in Situationen, in denen du in späteren Kapiteln einige fortgeschrittene Git-Operationen durchführen musst.
Wenn du den Befehl git status
ausführst, siehst du diesen Zwischenzustand von index.html:
$ git status On branch main No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: index.html
Der Befehl meldet, dass die neue Datei index.html bei der nächsten Übertragung zum Repository hinzugefügt wird.
Nachdem du die Datei bereitgestellt hast, ist der nächste logische Schritt, die Datei an das Projektarchiv zu übergeben. Sobald du die Datei festschreibst, wird sie Teil des Repository-Commit-Verlaufs, den wir der Einfachheit halber als Repo-Verlauf bezeichnen. Jedes Mal, wenn du einen Commit durchführst, speichert Git verschiedene andere Metadaten mit, vor allem die Commit-Logmeldung und den Autor der Änderung.
Ein vollständig qualifizierter git commit
Befehl sollte eine knappe und aussagekräftige Logmeldung in aktiver Sprache liefern, um die Änderung zu bezeichnen, die durch den Commit eingeführt wird. Das ist sehr hilfreich, wenn du die Repo-Historie durchforsten musst, um eine bestimmte Änderung aufzuspüren, oder wenn du die Änderungen eines Commits schnell identifizieren willst, ohne dich in die Details der Änderung vertiefen zu müssen. Dieses Thema wird in den Kapiteln 4 und 8 genauer behandelt.
Übertragen wir die index.html-Datei für deine Website:
$ git commit -m "Initial contents of my_website" [main (root-commit) c149e12] initial contents of my_website 1 file changed, 1 insertion(+) create mode 100644 index.html
Hinweis
Die Daten des Autors, der die Übertragung vornimmt, werden aus der Git-Konfiguration abgerufen, die wir zuvor eingerichtet haben.
Im Codebeispiel haben wir das Argument -m
angegeben, um die Logmeldung direkt in der Befehlszeile eingeben zu können. Wenn du es vorziehst, eine detaillierte Logmeldung über eine interaktive Editor-Sitzung zu erstellen, kannst du das auch tun. Du musst Git so konfigurieren, dass dein Lieblingseditor während einer git commit
gestartet wird (lass das Argument -m
weg); wenn es nicht bereits gesetzt ist, kannst du die Umgebungsvariable $GIT_EDITOR
wie folgt setzen:
# In bash or zsh $ export GIT_EDITOR=vim # In tcsh $ setenv GIT_EDITOR emacs
Hinweis
Git beachtet den Standard-Texteditor, der in den Shell-Umgebungsvariablen VISUAL
und EDITOR
konfiguriert ist. Wenn keiner von beiden konfiguriert ist, wird der Editor vi
verwendet.
Nachdem du die Datei index.html in das Repository übertragen hast, rufe git status
auf, um den aktuellen Stand deines Repositorys zu erfahren. In unserem Beispiel sollte git status
anzeigen, dass es keine ausstehenden Änderungen gibt, die übertragen werden müssen:
$ git status On branch main nothing to commit, working tree clean
Git sagt dir auch, dass dein Arbeitsverzeichnis sauber ist. Das bedeutet, dass das Arbeitsverzeichnis keine neuen oder geänderten Dateien enthält, die sich von denen im Repository unterscheiden.
Abbildung 1-3 hilft dir, alle Schritte, die du gerade gelernt hast, zu visualisieren.
Der Unterschied zwischen git add
und git commit
ist so, als würdest du eine Gruppe von Schulkindern in einer bestimmten Reihenfolge organisieren, um das perfekte Klassenfoto zu bekommen: git add
organisiert, während git commit
den Schnappschuss macht.
Eine weitere Verpflichtung eingehen
Als Nächstes nehmen wir ein paar Änderungen an index.html vor und erstellen eine Repository-Historie innerhalb des Repositorys.
Wandle index.html in eine richtige HTML-Datei um und übertrage die Änderung in diese:
$ cd ~/my_website # edit the index.html file. $ cat index.html <html> <body> My website is awesome! </body> </html> $ git commit index.html -m 'Convert to HTML' [main 521edbe] Convert to HTML 1 file changed, 5 insertions(+), 1 deletion(-)
Wenn du bereits mit Git vertraut bist, fragst du dich vielleicht, warum wir den Schritt git add index.html
übersprungen haben, bevor wir die Datei übertragen haben. Das liegt daran, dass der zu übertragende Inhalt in Git auf mehr als eine Weise angegeben werden kann.
Gib ein git commit --help
um mehr über diese Optionen zu erfahren:
$ git commit --help NAME git-commit - Record changes to the repository SYNOPSIS git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend] [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>)] [-F <file> | -m <msg>] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]] [--] [<pathspec>...] ...
Tipp
Ausführliche Erläuterungen zu den verschiedenen Commit-Methoden findest du auch auf den Handbuchseiten von git commit --help
.
In unserem Beispiel haben wir uns entschieden, die Datei index.html mit einem zusätzlichen Argument, dem Schalter -m
, zu übertragen, der eine Nachricht liefert, die die Änderungen in der Übertragung erklärt: 'Convert to HTML'
. Abbildung 1-4 erklärt die Methode, die wir gerade besprochen haben.
Beachte, dass unsere Verwendung von git commit index.html -m 'Convert to HTML'
das Staging der Datei nicht überspringt; Git erledigt dies automatisch als Teil der Commit-Aktion.
Deine Commits ansehen
Jetzt, wo du mehr Commits in der Repository-Historie hast, kannst du sie auf verschiedene Arten untersuchen. Einige git
Befehle zeigen die Reihenfolge der einzelnen Commits an, andere zeigen die Zusammenfassung eines einzelnen Commits und wieder andere zeigen die vollständigen Details jedes Commits, den du im Repository angibst.
Der Befehl git log
liefert eine fortlaufende Historie der einzelnen Commits im Repository:
$ git log commit 521edbe1dd2ec9c6f959c504d12615a751b5218f (HEAD -> main) Author: Jon Loeliger <jdl@example.com> Date: Mon Jul 4 12:01:54 2022 +0200 Convert to HTML commit c149e12e89a9c035b9240e057b592ebfc9c88ea4 Author: Jon Loeliger <jdl@example.com> Date: Mon Jul 4 11:58:36 2022 +0200 Initial contents of my_website
In der vorangegangenen Ausgabe gibt der Befehl git log
detaillierte Protokollinformationen für jeden Commit im Repository aus. Zu diesem Zeitpunkt hast du nur zwei Commits in deiner Repository-Historie, was das Lesen der Ausgabe erleichtert. Bei Repositories mit vielen Commit-Historien hilft dir diese Standardansicht möglicherweise nicht, eine lange Liste detaillierter Commit-Informationen leicht zu durchforsten; in solchen Situationen kannst du mit dem Schalter --oneline
eine zusammengefasste Commit-ID-Nummer zusammen mit der Commit-Nachricht auflisten:
$ git log --oneline 521edbe (HEAD -> main) Convert to HTML c149e12 Initial contents of my_website
Die Commit-Log-Einträge werden in der Reihenfolge vom jüngsten zum ältesten Eintrag aufgelistet.1 (die Originaldatei). Jeder Eintrag enthält den Namen und die E-Mail-Adresse des Commit-Autors, das Datum des Commits, die Logmeldung für die Änderung und die interne Identifikationsnummer des Commits. Die Commit-ID-Nummer wird in "Inhaltsadressierbare Datenbank" erklärt. Wir werden Commits in Kapitel 4 ausführlicher besprechen.
Wenn du mehr Details zu einem bestimmten Commit sehen willst, benutze den Befehl git show
mit einer Commit-ID-Nummer:
$ git show c149e12e89a9c035b9240e057b592ebfc9c88ea4 commit c149e12e89a9c035b9240e057b592ebfc9c88ea4 Author: Jon Loeliger <jdl@example.com> Date: Mon Jul 4 11:58:36 2022 +0200 Initial contents of my_website diff --git a/index.html b/index.html new file mode 100644 index 0000000..6331c71 --- /dev/null +++ b/index.html @@ -0,0 +1 @@ +My awesome website!
Tipp
Wenn du git show
ohne eine explizite Commit-Nummer aufrufst, zeigt es einfach die Details des HEAD
Commits an, in unserem Fall den jüngsten.
Der Befehl git log
zeigt in den Commit-Logs an, wie die Änderungen für jeden Commit in die Repo-Historie aufgenommen werden. Wenn du knappe, einzeilige Zusammenfassungen für den aktuellen Entwicklungszweig sehen willst, ohne dem Befehl git log --oneline
zusätzliche Filteroptionen zu geben, kannst du alternativ den Befehl git show-branch
verwenden:
$ git show-branch --more=10 [main] Convert to HTML [main^] Initial contents of my_website
Die Phrase --more=10
zeigt bis zu 10 weitere Versionen an, aber bisher gibt es nur zwei und deshalb werden beide angezeigt. (Die Standardeinstellung würde in diesem Fall nur die jüngste Übertragung auflisten.) Der Name main
ist der Standardzweigname.
In Kapitel 3 werden wir die Verzweigungen besprechen und den Befehl git show-branch
genauer unter die Lupe nehmen.
Unterschiede bei der Übertragung anzeigen
Mit der Repo-Historie von kannst du jetzt die Unterschiede zwischen den beiden Revisionen von index.html sehen. Du musst dir die Commit-ID-Nummern merken und den Befehl git diff
ausführen:
$ git diff c149e12e89a9c035b9240e057b592ebfc9c88ea4 \ 521edbe1dd2ec9c6f959c504d12615a751b5218f diff --git a/index.html b/index.html index 6331c71..8cfcb90 100644 --- a/index.html +++ b/index.html @@ -1 +1,5 @@ -My awesome website! +<html> +<body> My website is awesome! +</body> +</html>
Die Ausgabe ähnelt der, die der Befehl git diff
erzeugt. Gemäß der Konvention ist die erste Revisionsübergabe, 9da581d910c9c4ac93557ca4859e767f5caf5169
, die frühere des Inhalts von index.html und die zweite Revisionsübergabe, ec232cddfb94e0dfd5b5855af8ded7f5eb5c90d6
, der neueste Inhalt von index.html. Daher steht vor jeder Zeile mit neuem Inhalt ein Pluszeichen (+
) nach dem Minuszeichen (–
), das für entfernten Inhalt steht.
Hinweis
Lass dich von den langen Hex-Zahlen nicht einschüchtern. Git bietet viele kürzere, einfachere Möglichkeiten, ähnliche Befehle auszuführen, sodass du große, komplizierte Commit-IDs vermeiden kannst. In der Regel reichen die ersten sieben Zeichen der Hexadezimalzahlen, wie im Beispiel git log --oneline
gezeigt, aus. Wir gehen in "Inhaltsadressierbare Datenbank" näher darauf ein .
Entfernen und Umbenennen von Dateien in deinem Projektarchiv
Nachdem du nun gelernt hast, wie man Dateien zu einem Git-Repository hinzufügt, schauen wir uns nun an, wie man eine Datei aus einem Repository entfernt. Das Entfernen einer Datei aus einem Git-Repository erfolgt analog zum Hinzufügen einer Datei, allerdings mit dem Befehl git rm
. Angenommen, du hast die Datei adverts.html im Inhalt deiner Website und möchtest sie entfernen. Das kannst du wie folgt tun:
$ cd ~/my_website $ ls index.html adverts.html $ git rm adverts.html rm 'adverts.html' $ git commit -m "Remove adverts html" [main 97ff70a] Remove adverts html 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 adverts.html
Ähnlich wie bei einer Hinzufügung sind auch beim Löschen zwei Schritte erforderlich: Drücke deine Absicht, die Datei zu entfernen, mit git rm
aus, das auch die Datei, die du entfernen willst, in Szene setzt. Realisiere die Änderung im Repository mit git commit
.
Hinweis
Genau wie bei git add
löschen wir bei git rm
nicht direkt die Datei, sondern wir ändern, was verfolgt wird: das Löschen oder Hinzufügen einer Datei.
Du kannst eine Datei indirekt umbenennen, indem du eine Kombination aus den Befehlen git rm
und git add
verwendest, oder du kannst die Datei schneller und direkt mit dem Befehl git mv
umbenennen. Hier ist ein Beispiel für Ersteres:
$ mv foo.html bar.html $ git rm foo.html rm 'foo.html' $ git add bar.html
In dieser Reihenfolge musst du zu Beginn mv foo.html bar.html
ausführen, um zu verhindern, dass git rm
die Datei foo.html dauerhaft aus dem Dateisystem löscht.
Hier siehst du den gleichen Vorgang mit git mv
:
$ git mv foo.html bar.html
In beiden Fällen müssen die abgestuften Änderungen anschließend übertragen werden:
$ git commit -m "Moved foo to bar" [main d1e37c8] Moved foo to bar 1 file changed, 0 insertions(+), 0 deletions(-) rename foo.html => bar.html (100%)
Git geht mit Dateiverschiebungen anders um als die meisten ähnlichen Systeme und verwendet einen Mechanismus, der auf der Ähnlichkeit des Inhalts zwischen zwei Dateiversionen basiert. Die Einzelheiten dazu werden in Kapitel 5 beschrieben.
Konfigurationsdateien
Die Git-Konfigurationsdateien sind alle einfache Textdateien im Stil von .ini-Dateien. In den Konfigurationsdateien werden Präferenzen und Einstellungen gespeichert, die von mehreren git
Befehlen verwendet werden. Einige der Einstellungen sind persönliche Vorlieben (z. B. soll color.pager
verwendet werden?), andere sind wichtig, damit ein Repository richtig funktioniert (z. B. core repositoryformatversion
), und wieder andere verändern das Verhalten der git
Befehle ein wenig (z. B. gc.auto
). Wie andere Tools auch, unterstützt Git eine Hierarchie von Konfigurationsdateien.
Hierarchie der Konfigurationsdateien
Abbildung 1-6 zeigt die Hierarchie der Git-Konfigurationsdateien in abnehmender Rangfolge:
- .git/config
-
Repository-spezifische Konfigurationseinstellungen mit der Option
--file
oder standardmäßig manipuliert. Du kannst auch mit der Option--local
in diese Datei schreiben. Diese Einstellungen haben den höchsten Vorrang. - ~/.gitconfig
-
Benutzerspezifische Konfigurationseinstellungen, die mit der Option
--global
bearbeitet werden. - /etc/gitconfig
-
Systemweite Konfigurationseinstellungen kannst du mit der Option
--system
ändern, wenn du die richtigen Unix-Schreibrechte für die Datei gitconfig hast. Diese Einstellungen haben den geringsten Vorrang. Je nach deiner Installation kann sich die Datei mit den Systemeinstellungen an einer anderen Stelle befinden (vielleicht in /usr/local/etc gitconfig) oder ganz fehlen.
Um zum Beispiel einen Autorennamen und eine E-Mail-Adresse zu speichern, die für alle deine Commits in allen Repositories verwendet wird, konfiguriere die Werte für user name
und user.email
in deiner Datei $HOME/.gitconfig mit git config --global
:
$ git config --global user.name "Jon Loeliger" $ git config --global user.email "jdl@example.com"
Wenn du einen repository-spezifischen Namen und eine E-Mail-Adresse festlegen musst, die eine --global
-Einstellung überschreiben würden, lass einfach das --global
-Flag weg oder benutze das --local
-Flag, um explizit zu sein:
$ git config user.name "Jon Loeliger" $ git config user.email "jdl@special-project.example.org"
Du kannst git config -l
(oder die Langform --list
) verwenden, um die Einstellungen aller Variablen aufzulisten, die sich in der gesamten Konfigurationsdatei befinden:
# Make a brand-new, empty repository $ mkdir /tmp/new $ cd /tmp/new $ git init # Set some config values $ git config --global user.name "Jon Loeliger" $ git config --global user.email "jdl@example.com" $ git config user.email "jdl@special-project.example.org" $ git config -l user.name=Jon Loeliger user.email=jdl@example.com core.repositoryformatversion=0 core.filemode=true core.bare=false core.logallrefupdates=true user.email=jdl@special-project.example.org
Tipp
Wenn du den Befehl git config -l
angibst, kannst du mit den Optionen --show-scope
und --show-origin
die verschiedenen Quellen für die Konfigurationen ausgeben! Probiere das mit git config -l --show-scope --show-origin
in deinem Terminal aus.
Da es sich bei den Konfigurationsdateien um einfache Textdateien handelt, kannst du ihren Inhalt mit cat
ansehen und sie auch mit deinem bevorzugten Texteditor bearbeiten:
# Look at just the repository-specific settings $ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [user] email = jdl@special-project.example.org
Hinweis
Der Inhalt der Konfigurationstextdatei kann sich je nach Betriebssystemleicht unterscheiden. Viele dieser Unterschiede ermöglichen unterschiedlicheEigenschaften des Dateisystems.
Wenn du eine Einstellung aus den Konfigurationsdateien entfernen musst, verwende die Option --unset
zusammen mit dem Flag correct configuration files:
$ git config --unset --global user.email
Git stellt dir viele Konfigurationsoptionen und Umgebungsvariablen zur Verfügung, die häufig für den gleichen Zweck existieren. Du kannst zum Beispiel einen Wert für den Editor festlegen, der beim Verfassen einer Commit-Logmeldung verwendet werden soll. Basierend auf der Konfiguration folgt der Aufruf diesen Schritten:
-
GIT_EDITOR
Umgebungsvariable -
core.editor
Konfigurationsoption -
VISUAL
Umgebungsvariable -
EDITOR
Umgebungsvariable -
Der Befehl
vi
Es gibt mehr als ein paar hundert Konfigurationsparameter. Wir werden dich nicht mit ihnen langweilen, sondern nach und nach auf wichtige Parameter hinweisen. Eine ausführlichere (aber immer noch unvollständige) Liste findest du auf der Handbuchseite git config
.
Tipp
Eine vollständige Liste aller git
Befehle findest du online.
Einen Alias konfigurieren
Git-Aliase ermöglichen es dir, häufige aber komplexe git
Befehle, die du häufig eingibst, durch einfache und leicht zu erinnernde Aliase zu ersetzen. Das erspart dir die Mühe, dich an lange Befehle zu erinnern oder sie abzutippen, und es erspart dir den Frust über Tippfehler:
$ git config --global alias.show-graph \ 'log --graph --abbrev-commit --pretty=oneline'
In diesem Beispiel haben wir den Alias show-graph
erstellt und ihn in jedem Repository, das wir erstellen, verfügbar gemacht. Wenn wir den Befehl git show-graph
verwenden, erhalten wir dieselbe Ausgabe, die wir erhalten haben, als wir den langen Befehl git log
mit all diesen Optionen eingegeben haben.
Zusammenfassung
Auch nach allem, was du bisher gelernt hast, wirst du sicherlich viele unbeantwortete Fragen dazu haben, wie Git funktioniert. Wie speichert Git zum Beispiel jede Version einer Datei? Was macht eigentlich einen Commit aus? Woher kommen diese komischen Commit-Nummern? Warum der Name "main"? Und ist ein "Branch" das, was ich denke, dass er ist? Das sind gute Fragen. Was wir behandelt haben, gibt dir einen Einblick in die Vorgänge, die du in deinen Projekten häufig verwenden wirst. Die Antworten auf deine Fragen werden in Teil II im Detail erklärt.
Das nächste Kapitel definiert einige Begriffe, führt in einige Git-Konzepte ein und schafft eine Grundlage für die Lektionen im Rest des Buches.
1 Streng genommen sind sie nicht chronologisch geordnet, sondern eher eine topologische Sortierung der Commits.
Get Versionskontrolle mit Git, 3. Auflage now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.