Wenn ich sie richtig verstehe (und ich bin kein Experte für jeden), haben sie grundsätzlich eine andere Philosophie. Ich habe Mercurial zum ersten Mal seit 9 Monaten verwendet. Jetzt habe ich Git für 6 verwendet.
hg ist eine Versionskontrollsoftware. Das Hauptziel besteht darin, Versionen einer Software zu verfolgen.
git ist ein zeitbasiertes Dateisystem. Ziel ist es, einem Dateisystem eine weitere Dimension hinzuzufügen. Die meisten haben Dateien und Ordner, Git fügt Zeit hinzu. Dass es als VCS fantastisch funktioniert, ist ein Nebenprodukt seines Designs.
In hg gibt es eine Geschichte des gesamten Projekts, das immer gepflegt werden soll. Standardmäßig möchte hg alle Änderungen an allen Objekten durch alle Benutzer beim Drücken und Ziehen.
In git gibt es nur einen Pool von Objekten und diese Verfolgungsdateien (Zweige / Köpfe), die bestimmen, welche Gruppe dieser Objekte den Baum von Dateien in einem bestimmten Zustand darstellt. Beim Drücken oder Ziehen sendet git nur die Objekte, die für die bestimmten Zweige benötigt werden, die Sie drücken oder ziehen. Dies ist eine kleine Teilmenge aller Objekte.
Für Git gibt es kein "1 Projekt". Du könntest 50 Projekte im selben Repo haben und Git wäre das egal. Jeder kann separat im selben Repo verwaltet werden und gut leben.
Hgs Konzept von Zweigen ist Verzweigungen vom Hauptprojekt oder Verzweigungen von Zweigen usw. Git hat kein solches Konzept. Ein Zweig in Git ist nur ein Zustand des Baumes, alles ist ein Zweig in Git. Welcher Zweig offiziell, aktuell oder neu ist, hat in git keine Bedeutung.
Ich weiß nicht, ob das Sinn machte. Wenn ich Bilder zeichnen könnte, könnte hg so aussehen, wo jedes Commit ein isto
o---o---o
/
o---o---o---o---o---o---o---o
\ /
o---o---o
Ein Baum mit einer einzigen Wurzel und Ästen. Während Git das kann und die Leute es oft so benutzen, wird es nicht durchgesetzt. Ein Git-Bild könnte, wenn es so etwas gibt, leicht so aussehen
o---o---o---o---o
o---o---o---o
\
o---o
o---o---o---o
In gewisser Weise macht es nicht einmal Sinn, Zweige in Git zu zeigen.
Eine Sache, die für die Diskussion sehr verwirrend ist: Git und Mercurial haben beide einen sogenannten "Zweig", aber sie sind nicht im entferntesten dieselben Dinge. Ein Zweig in Quecksilber entsteht, wenn es Konflikte zwischen verschiedenen Repos gibt. Ein Zweig in Git ähnelt anscheinend einem Klon in HG. Aber ein Klon ist zwar nicht ähnlich, aber definitiv nicht dasselbe. Betrachten Sie mich als Versuch in git vs hg mit dem Chrom-Repo, das ziemlich groß ist.
$ time git checkout -b some-new-branch
Switched to new branch 'some-new-branch'
real 0m1.759s
user 0m1.596s
sys 0m0.144s
Und jetzt in hg mit Klon
$ time hg clone project/ some-clone/
updating to branch default
29387 files updated, 0 files merged, 0 files removed, 0 files unresolved.
real 0m58.196s
user 0m19.901s
sys 0m8.957
Beides sind heiße Läufe. Das heißt, ich habe sie zweimal ausgeführt und dies ist der zweite Lauf. hg clone ist eigentlich das gleiche wie git-new-workdir. Beide machen ein völlig neues Arbeitsverzeichnis, fast so, als hätten Sie getippt cp -r project project-clone
. Das ist nicht dasselbe wie einen neuen Zweig in Git zu machen. Es ist viel schwerer. Wenn es ein echtes Äquivalent zur Verzweigung von git in hg gibt, weiß ich nicht, was es ist.
Ich verstehe auf einer bestimmten Ebene, dass hg und git in der Lage sein könnten, ähnliche Dinge zu tun. Wenn ja, dann gibt es immer noch einen großen Unterschied im Workflow, zu dem sie Sie führen. In git besteht der typische Workflow darin, für jedes Feature einen Zweig zu erstellen.
git checkout master
git checkout -b add-2nd-joypad-support
git checkout master
git checkout -b fix-game-save-bug
git checkout master
git checkout -b add-a-star-support
Das hat gerade 3 Zweige erstellt, jeder basiert auf einem Zweig namens Master. (Ich bin mir sicher, dass es in git eine Möglichkeit gibt, diese 1 Zeile anstelle von 2 zu machen.)
Nun, um an einem zu arbeiten, mache ich es einfach
git checkout fix-game-save-bug
und anfangen zu arbeiten. Festschreiben von Dingen usw. Das Wechseln zwischen Zweigen selbst in einem Projekt, das so groß wie Chrom ist, erfolgt fast augenblicklich. Ich weiß eigentlich nicht, wie ich das in hg machen soll. Es ist nicht Teil von Tutorials, die ich gelesen habe.
Ein weiterer großer Unterschied. Gits Bühne.
Git hat diese Idee einer Bühne. Sie können sich das als versteckten Ordner vorstellen. Wenn Sie ein Commit durchführen, legen Sie nur fest, was sich auf der Bühne befindet, nicht die Änderungen in Ihrem Arbeitsbaum. Das mag seltsam klingen. Wenn Sie alle Änderungen in Ihrem Arbeitsbaum festschreiben möchten, werden alle git commit -a
geänderten Dateien zur Bühne hinzugefügt und anschließend festgeschrieben.
Was ist der Sinn der Bühne dann? Sie können Ihre Commits einfach trennen. Stellen Sie sich vor, Sie haben joypad.cpp und gamesave.cpp bearbeitet und möchten diese separat festschreiben
git add joypad.cpp // copies to stage
git commit -m "added 2nd joypad support"
git add gamesave.cpp // copies to stage
git commit -m "fixed game save bug"
Git hat sogar Befehle, um zu entscheiden, welche bestimmten Zeilen in derselben Datei Sie auf die Bühne kopieren möchten, damit Sie diese Commits auch separat aufteilen können. Warum willst du das tun? Weil andere als separate Commits nur diejenigen abrufen können, die sie möchten, oder wenn es ein Problem gab, können sie nur das Commit zurücksetzen, bei dem das Problem aufgetreten ist.