Git ist eines der Versionsverwaltungssysteme. Was ist ein Versionsverwaltungssystem?
Es ist ein System mit Funktionen wie. Hier ist "Geschichte ändern"
Bezieht sich auf eine Reihe von Informationen, die in chronologischer Reihenfolge aufgezeichnet wurden.
Neben Git gibt es noch andere Versionsverwaltungssysteme wie CVS und Subversion, aber Git verfügt über die folgenden Funktionen.
Schauen wir uns zunächst an, wie Git als Content Vault funktioniert. Erstellen Sie zunächst ein leeres Git-Repository
% mkdir repo1
% cd repo1
% git init
Initialized empty Git repository in repo1/.git/
Erstellen Sie eine Datei mit dem Namen readme.txt, speichern Sie den Inhalt im Repository, überschreiben Sie die Datei mit anderen Inhalten und speichern Sie sie im Repository.
% echo aaa > readme.txt
% git hash-object -w readme.txt
72943a16fb2c8f38f9dde202b7a70ccc19c52f34
% echo bbb > readme.txt
% git hash-object -w readme.txt
f761ec192d9f0dca3329044b96ebdb12839dbff6
% rm -f readme.txt
Der Inhalt der gespeicherten Datei kann mithilfe der Zeichenfolge abgerufen werden, die angezeigt wird, wenn der Befehl hash-object als Schlüssel ausgeführt wird.
% git cat-file -p 72943a16fb2c8f38f9dde202b7a70ccc19c52f34 > readme.txt
% cat readme.txt
aaa
% git cat-file -p f761ec192d9f0dca3329044b96ebdb12839dbff6 > readme.txt
% cat readme.txt
bbb
Was ist zu beachten
Das ist. Wenn der unvollendete Teil möglich wird, ist es möglich, den Änderungsverlauf beizubehalten, aber bevor ich ihn betrachte, ist "etwas, das ich nicht verstehe" der SHA1-Hashwert des Dateiinhalts (+ α). Stellen wir sicher, dass es das gibt.
hash-object.py
import hashlib
import sys
if len(sys.argv) != 2:
print("usage: %s file" % sys.argv[0])
sys.exit(-1)
try:
f = open(sys.argv[1])
except Exception:
print("open %s failed" % sys.argv[1])
sys.exit(-1)
data = f.read()
sha1 = hashlib.sha1("blob %d" % len(data) + "\0" + data).hexdigest()
print(sha1)
Dieses Python-Programm
Berechnet den SHA1-Hashwert der Verkettung und gibt seine hexadezimale Darstellung aus. Wenn ich es tatsächlich für die beiden oben genannten Inhalte verwende,
% echo aaa | python hash-object.py /dev/stdin
72943a16fb2c8f38f9dde202b7a70ccc19c52f34
% echo bbb | python hash-object.py /dev/stdin
f761ec192d9f0dca3329044b96ebdb12839dbff6
Und Sie können sehen, dass das Berechnungsergebnis mit dem Schlüssel übereinstimmt, der zum früheren Speichern des Inhalts verwendet wurde (der Inhalt wird unter Verwendung des SHA1-Hashwerts des Dateiinhalts + α als Schlüssel gespeichert). Das Speicherziel im Inhaltsrepository ist übrigens
% find .git/objects -type f
.git/objects/72/943a16fb2c8f38f9dde202b7a70ccc19c52f34
.git/objects/f7/61ec192d9f0dca3329044b96ebdb12839dbff6
Der SHA1-Hashwert ist die Verkettung von Verzeichnisname und Dateiname. Wenn Sie den SHA1-Wert dieser Dateien selbst verwenden
% sha1sum `find .git/objects -type f`
cf6e4f80cfae36e20ae7eb1a90919ca48f59514b .git/objects/72/943a16fb2c8f38f9dde202b7a70ccc19c52f34
cdb05607e2e073287a81a908564d9d901ccdd687 .git/objects/f7/61ec192d9f0dca3329044b96ebdb12839dbff6
Und der Wert ist anders. Dies liegt beispielsweise daran, dass der Inhalt komprimiert und gespeichert wird.
decompress_sha1.py
import hashlib
import sys
import zlib
if len(sys.argv) != 2:
print("usage: %s git_object_file" % sys.argv[0])
sys.exit(-1)
path = sys.argv[1]
try:
f = open(path)
except Exception:
print("open %s failed" % path)
sys.exit(-1)
data = zlib.decompress(f.read())
sha1 = hashlib.sha1(data).hexdigest()
print("%s: %s" % (path, sha1))
Wenn Sie den Hash-Wert nach dem Dekomprimieren mit dem Programm berechnen
% for i in `find .git/objects -type f`; do python ../decompress_sha1.py $i; done
.git/objects/72/943a16fb2c8f38f9dde202b7a70ccc19c52f34: 72943a16fb2c8f38f9dde202b7a70ccc19c52f34
.git/objects/f7/61ec192d9f0dca3329044b96ebdb12839dbff6: f761ec192d9f0dca3329044b96ebdb12839dbff6
Sie können sehen, dass sie richtig übereinstimmen (da die Hash-Werte übereinstimmen, wird erwartet, dass auch der Inhalt übereinstimmt).
Ich habe gesehen, wie man den Inhalt einer Datei unter .git / objects / speichert. Git speichert auch Dateinamen und Commit-Protokollnachrichteninformationen in einer Datei unter .git / objects / wird als Git-Objekt bezeichnet.
Zum Zeitpunkt der Erstellung des Repositorys werden keine Objekte gespeichert.
% mkdir repo2
% cd repo2
% git init
Initialized empty Git repository in repo2/.git/
% ls .git
HEAD config hooks/ objects/
branches/ description info/ refs/
% find .git/objects -type f
Fügen wir dem Staging-Bereich mit git add eine Datei hinzu.
% echo aaa > readme.txt
% git add readme.txt
% find .git/objects -type f
.git/objects/72/943a16fb2c8f38f9dde202b7a70ccc19c52f34
% ls .git
HEAD config hooks/ info/ refs/
branches/ description index objects/
Ein Objekt wurde hinzugefügt und eine Datei namens Index wurde erstellt. Sie können den Inhalt des Git-Objekts mit der Git-Cat-Datei überprüfen.
% git cat-file -t 729
fatal: Not a valid object name 729
% git cat-file -t 7294
blob
% git cat-file -s 7294
4
% wc -c readme.txt
4 readme.txt
% git cat-file -p 7294
aaa
% cat readme.txt
aaa
Als eine Möglichkeit, Cat-File zu verwenden
-t
überprüfen, handelt es sich um ein Blob-Objekt, das den Inhalt der Datei speichert, wie wir im vorherigen Abschnitt gesehen haben.Als nächstes schreiben wir die im Index enthaltenen Informationen als Objekt aus.
% git write-tree
580c73c39691399d09ad01152ad0a691ce80bccf
% find .git/objects -type f
.git/objects/58/0c73c39691399d09ad01152ad0a691ce80bccf
.git/objects/72/943a16fb2c8f38f9dde202b7a70ccc19c52f34
% git cat-file -t 580c
tree
% git cat-file -p 580c
100644 blob 72943a16fb2c8f38f9dde202b7a70ccc19c52f34 readme.txt
In diesem Moment,
Ich verstehe das.
Erstellen Sie als Nächstes ein Verzeichnis und eine Datei darunter und versuchen Sie git add.
% mkdir tmp
% echo bbb > tmp/bbb.txt
% git add tmp/bbb.txt
% find .git/objects -type f
.git/objects/58/0c73c39691399d09ad01152ad0a691ce80bccf
.git/objects/72/943a16fb2c8f38f9dde202b7a70ccc19c52f34
.git/objects/f7/61ec192d9f0dca3329044b96ebdb12839dbff6
% git cat-file -t f761
blob
% git cat-file -p f761
bbb
Das neu hinzugefügte Objekt ist ein Blob-Objekt, das den Inhalt von bbb.txt enthält. Wenn Sie in diesem Zustand erneut einen Index als Objekt schreiben
% git write-tree
6434b2415497a42647800c7e828038a2fb6fbbaf
% find .git/objects -type f
.git/objects/58/0c73c39691399d09ad01152ad0a691ce80bccf
.git/objects/5c/40d98927de9cdb27df5b3a7bd4f7ee95dbfc85
.git/objects/64/34b2415497a42647800c7e828038a2fb6fbbaf
.git/objects/72/943a16fb2c8f38f9dde202b7a70ccc19c52f34
.git/objects/f7/61ec192d9f0dca3329044b96ebdb12839dbff6
% git cat-file -t 6434
tree
% git cat-file -p 6434
100644 blob 72943a16fb2c8f38f9dde202b7a70ccc19c52f34 readme.txt
040000 tree 5c40d98927de9cdb27df5b3a7bd4f7ee95dbfc85 tmp
% git cat-file -t 5c40
tree
% git cat-file -p 5c40
100644 blob f761ec192d9f0dca3329044b96ebdb12839dbff6 bbb.txt
Hier,
580c
, das wir zuvor gesehen haben, bleibt intakt.580c
oder 6434
) können Sie den Dateisatz zu einem bestimmten Zeitpunkt identifizieren.Sie können sehen, dass.
Ich habe einen Parser für Baum geschrieben, weil es eine große Sache war.
parse_tree.py
import hashlib
import sys
import zlib
if len(sys.argv) != 2:
print("usage: %s git_object_file" % sys.argv[0])
sys.exit(-1)
try:
f = open(sys.argv[1])
except Exception:
print("open %s failed" % sys.argv[1])
sys.exit(-1)
data = zlib.decompress(f.read())
sha1 = hashlib.sha1(data).hexdigest()
eoh = data.find("\0")
if eoh < 0:
print("no end of header")
sys.exit(-1)
header = data[:eoh]
t, n = header.split(" ")
if len(data) - eoh - 1 != int(n):
print("size mismatch %d,%d" % (len(data) - eoh - 1, int(n)))
sys.exit(-1)
if t != "tree":
print("not tree: %s" % t)
sys.exit(-1)
dsize = hashlib.sha1().digest_size
ptr = eoh + 1
while ptr < len(data):
eorh = data.find("\0", ptr)
if eorh < 0:
print("no end of reference header")
sys.exit(-1)
mode, name = data[ptr:eorh].split(" ")
sha1_ = "".join(map(lambda x: "%02x" % ord(x), data[eorh+1:eorh+1+dsize]))
print("%s (%6s) %s" % (sha1_, mode, name))
ptr = eorh + 1 + dsize
% python parse_tree.py .git/objects/64/34b2415497a42647800c7e828038a2fb6fbbaf
72943a16fb2c8f38f9dde202b7a70ccc19c52f34 (100644) readme.txt
5c40d98927de9cdb27df5b3a7bd4f7ee95dbfc85 ( 40000) tmp
Die Datenstruktur des Baumobjekts besteht aus zlib-komprimierten Daten (ähnlich wie bei Blob).
Der Inhaltsteil ist
Es ist eine Wiederholung von.
Nachdem wir zwei Arten von Objekten gesehen haben, Blob und Tree, schauen wir uns am Ende das Commit-Objekt an. Erstellen wir ein Commit, das auf das Baumobjekt "580c" verweist.
% git commit-tree -m "initial commit" 580c
7a5c786478f17fd96b385c725c95d10fa74e4576
% ls .git/objects/7a/5c786478f17fd96b385c725c95d10fa74e4576
.git/objects/7a/5c786478f17fd96b385c725c95d10fa74e4576
% git cat-file -t 7a5c
commit
% git cat-file -p 7a5c
tree 580c73c39691399d09ad01152ad0a691ce80bccf
author Yoichi Nakayama <[email protected]> 1447772602 +0900
committer Yoichi Nakayama <[email protected]> 1447772602 +0900
initial commit
Als nächstes erstellen wir ein Commit, das auf das Baumobjekt "6434" verweist, wobei das Commit-Objekt "7a5c" das übergeordnete Objekt ist.
% git commit-tree -p 7a5c -m "second commit" 6434
88470d975c1875e2e03a46877c13dde9ed2fd1ea
% ls .git/objects/88/470d975c1875e2e03a46877c13dde9ed2fd1ea
.git/objects/88/470d975c1875e2e03a46877c13dde9ed2fd1ea
% git cat-file -t 8847
commit
% git cat-file -p 8847
tree 6434b2415497a42647800c7e828038a2fb6fbbaf
parent 7a5c786478f17fd96b385c725c95d10fa74e4576
author Yoichi Nakayama <[email protected]> 1447772754 +0900
committer Yoichi Nakayama <[email protected]> 1447772754 +0900
second commit
Wenn Sie den Hashwert dieses Festschreibungsobjekts in den von HEAD referenzierten Master eingeben, Sie können den Verlauf mit Git-Protokoll anzeigen.
% cat .git/HEAD
ref: refs/heads/master
% echo 88470d975c1875e2e03a46877c13dde9ed2fd1ea > .git/refs/heads/master
% git log
commit 88470d975c1875e2e03a46877c13dde9ed2fd1ea
Author: Yoichi Nakayama <[email protected]>
Date: Wed Nov 18 00:05:54 2015 +0900
second commit
commit 7a5c786478f17fd96b385c725c95d10fa74e4576
Author: Yoichi Nakayama <[email protected]>
Date: Wed Nov 18 00:03:22 2015 +0900
initial commit
Sie können jetzt den Verlauf anzeigen, den Sie normalerweise nach dem Festschreiben von Git sehen. Sie können git diff auch den Hash-Wert des Ziel-Commit-Objekts geben, um den Unterschied zu sehen.
% git diff 7a5c 8847
diff --git a/tmp/bbb.txt b/tmp/bbb.txt
new file mode 100644
index 0000000..f761ec1
--- /dev/null
+++ b/tmp/bbb.txt
@@ -0,0 +1 @@
+bbb
Die Datenstruktur des Festschreibungsobjekts ist dieselbe wie die des Blob-Objekts, außer dass es mit "Festschreiben" als Inhalt beginnt.
Beinhaltet.
Recommended Posts