En termes simples, quel type de système est Git ? Veuillez noter que le contenu suivant est très important. Si vous comprenez les idées et les principes de fonctionnement de base de Git, vous saurez comment l'utiliser et vous pourrez l'utiliser facilement. Lorsque vous apprenez Git, essayez de clarifier vos connaissances existantes sur d'autres systèmes de gestion de versions, tels que CVS, Subversion ou Perforce. Cela vous aidera à éviter toute confusion lors de l'utilisation de ces outils. Bien que Git soit très similaire aux autres systèmes de contrôle de version utilisés, il est très différent dans la manière dont il stocke et perçoit les informations. Comprendre ces différences aidera à éviter toute confusion lors de l'utilisation.
Git initialise le dépôt de code
Après avoir exécuté la commande git init, qu'avez-vous fait exactement ?
Après avoir exécuté la commande suivante, nous pouvons obtenir le contenu présenté dans la figure ci-dessous. À droite se trouve le référentiel de code créé pour nous par Git, qui contient le contenu requis pour la gestion des versions.
# Exécutez
$ mkdir git-demo à gauche
$ cd git-demo && git init
$ rm -rf .git/hooks/*.sample
# Exécutez à droite
$ watch -n 1 -d find .
Ici, nous pouvons jeter un œil à la structure du répertoire .git généré :
➜ arborescence .git
.git
├── HEAD
├── config
├── description
├── hooks
├── info
│ └── exclure
├── objets
│ ├── infos
│ └── pack
└── références
├── têtes
└── tags
.git/config - fichier de configuration local pour le référentiel de code actuel
-
Fichiers de configuration locaux (.git/config) et fichiers de configuration globaux (~/.gitconfig)
-
En exécutant la commande suivante, la configuration utilisateur peut être enregistrée dans le fichier de configuration de l'entrepôt de code local
-
git config user.name "démo"
-
git config user.email "[email protected]"
➜ cat .git/config
[core]
depositformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[user]
nom = démo
email = [email protected]
.git/objects - L'emplacement de stockage du code actuel du référentiel de code
-
type de goutte
-
type de validation
-
type d'arbre
# 均无内容
➜ ll .git/objects
total 0
drwxr-xr-x 2 bâton d'évasion 64B 23 novembre 20:39 info
drwxr-xr-x 2 bâton d'évasion 64B 23 novembre 20:39 pack
➜ ll .git/objects/info
➜ allez .git/objects/pack
.git/info - Informations telles que les exclusions pour le référentiel actuel
➜ cat ./.git/info/exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Les lignes qui commencent par '#' sont des commentaires.
# Pour un projet principalement en C, ce qui suit serait un bon ensemble de
# modèles d'exclusion (décommentez-les si vous souhaitez les utiliser) :
# *.[oa]
# *~
.git/hooks - le script hook par défaut pour le référentiel de code actuel
./.git/hooks/commit-msg.sample
./.git/hooks/pre-rebase.sample
./.git/hooks/pre-commit.sample
./.git/hooks/applypatch-msg.sample
./ .git/hooks/fsmonitor-watchman.sample
./.git/hooks/pre-receive.sample
./.git/hooks/prepare-commit-msg.sample
./.git/hooks/post-update.sample
./ .git/hooks/pre-merge-commit.sample
./.git/hooks/pre-applypatch.sample
./.git/hooks/pre-push.sample
./.git/hooks/update.sample
.git/HEAD - le pointeur de branche du référentiel de code actuel
➜ cat .git/HEAD
réf : refs/heads/master
.git/refs - le pointeur principal du référentiel actuel
# 均无内容
➜ ll .git/refs
total 0
drwxr-xr-x 2 bâton d'évasion 64B 23 novembre 20:39 têtes
drwxr-xr-x 2 bâton d'évasion 64B 23 novembre 20:39 tags
➜ ll .git/refs/heads
➜ allez .git/refs/tags
.git/description - informations de description du référentiel de code actuel
➜ cat .git/description
Dépôt sans nom ; modifiez ce fichier 'description' pour nommer le référentiel.
que s'est-il passé après l'ajout
Après avoir exécuté la commande git add, qu’avez-vous fait exactement ?
Après avoir exécuté la commande suivante, nous pouvons obtenir le contenu affiché dans la figure ci-dessous. Nous avons constaté qu'un nouveau fichier a été ajouté à droite, mais le contenu du répertoire Git n'a pas du tout changé. En effet, les modifications que nous effectuons maintenant sont placées par défaut dans l'espace de travail et les modifications dans l'espace de travail ne sont pas gérées par le répertoire Git.
Lorsque nous exécutons la commande git status, Git peut reconnaître qu'un nouveau fichier a été ajouté à l'espace de travail. Comment faire ? —— Voir [Comprendre les objets blob et SHA1] pour plus de détails
Lorsque nous exécutons la commande git add pour laisser Git nous aider à gérer les fichiers, nous constatons qu'un répertoire et deux fichiers ont été ajoutés à droite, à savoir le répertoire 8d, l'index et les fichiers 0e41....
# Exécuter à gauche
$ echo "hello git" > helle.txt
$ git status
$ git add hello.txt
# Exécuter à droite
$ watch -n 1 -d find .
Concentrons-nous ici sur le répertoire 8d généré et les fichiers ci-dessous. L'origine de son nom est due au fait que Git a exécuté un algorithme de hachage appelé SHA1, qui est utilisé pour transformer le contenu du fichier ou la chaîne en une telle chaîne de caractères cryptés.
# Afficher le type de fichier des objets
$ git cat-file -t 8d0e41
blob
# Afficher le contenu du fichier des objets
$ git cat-file -p 8d0e41
hello git
# Afficher la taille du fichier des objets
$ git cat-file -s 8d0e41
10
# Assembler le
blob 10\0hello git
Nous savons maintenant qu'en exécutant la commande git add pour ajouter des fichiers de l'espace de travail à la zone de stockage temporaire, Git nous aidera à générer des objets Git, qui stockent le contenu et le type de fichier du fichier et ne stockent pas le nom du fichier.
Afin de vérifier notre déclaration ci-dessus, nous pouvons ajouter le même contenu à un autre fichier, puis le soumettre pour observer les modifications dans le répertoire .git. Nous avons constaté qu'il n'y avait aucun nouveau répertoire ni fichier dans le répertoire d'objets à droite. Cela peut prouver que l'objet de type blob ne stocke que le contenu du fichier. Si le contenu des deux fichiers est cohérent, un seul objet doit être stocké.
Au fait, pourquoi l'objet ici ne stocke-t-il pas le nom du fichier ? En effet, l'algorithme de hachage SHA1 n'inclut pas le nom du fichier lors du calcul du hachage, son nom n'a donc pas d'importance. La question se pose alors : où sont stockées les informations sur le nom du fichier ? —— Voir [Comprendre les objets blob et SHA1] pour plus de détails
# Exécuter à gauche
$ echo "hello git" > tmp.txt
$ git add tmp.txt
# Exécuter à droite
$ watch -n 1 -d find .
Comprendre les objets blob et SHA1
Comprenez la relation et le calcul correspondant entre l'objet blob de Git et SHA1 !
L'algorithme de hachage transforme une entrée de n'importe quelle longueur en une sortie de longueur fixe via un algorithme de hachage. Selon l'algorithme, la longueur générée est également différente.
Algorithme de hachage :
-
MD5 - 128 bits - Non sécurisé - Somme de contrôle du fichier
-
SHA1 - 160 bits (40 bits) - Non sécurisé - Stockage Git
-
SHA256 - 256 bits - Sécurisé - Image Docker
-
SHA512 - 512 bits - sécurisé
Cependant, lorsque nous utilisons des outils pour effectuer des calculs SHA1 sur le contenu des fichiers ci-dessus, nous constatons qu'ils ne correspondent pas à ce que nous voyons dans le répertoire .git.
➜ echo "bonjour git" | shasum
d6a96ae3b442218a91512b9e1c57b9578b487a0b -
Ici, en raison de la méthode de calcul de l'outil Git, il est calculé en utilisant la méthode du type length\0 content. Ici, nous avons calculé que le contenu du fichier ne comporte que neuf chiffres, mais ici il y a dix chiffres, ce qui est dû à l'existence de sauts de ligne dans le contenu. Nous pouvons maintenant utiliser la commande git cat-file pour assembler le contenu complet du magasin d'outils Git.
➜ ls -lh hello.txt
-rw-r--r-- 1 escape staff 10B 23 novembre 21:12 hello.txt
➜ echo "blob 10\0hello git" | shasum
8d0e41234f24b6da002d962a26c2495ea16a425f -
# Assembler
blob 10\ 0hello git
Lorsque nous utilisons la commande cat pour afficher le contenu de l'objet objet, nous constatons qu'il ressemble à une chaîne de caractères tronqués. En fait, il s'agit de l'outil Git qui compresse le contenu original du fichier puis le stocke dans l'objet objet. Étrangement, nous avons constaté que le contenu compressé était en réalité plus volumineux que le contenu original !
En effet, il est compressé et stocke certaines informations liées à la compression. L'exemple ci-dessus montre un fichier plus volumineux que l'original car le contenu que nous avons créé est tout simplement trop petit. Lorsque nous voyons un fichier relativement volumineux, nous verrons que la taille du fichier compressé est beaucoup plus petite que celle du fichier original.
➜ cat .git/objects/8d/0e41234f24b6da002d962a26c2495ea16a425f
xKOR04`HWH,6A%
➜ ls -lh .git/objects/8d/0e41234f24b6da002d962a26c2495ea16a425f
-r- -r--r-- 1 bâton d'évasion 26B 23 novembre 21:36 .git/ objets/8d/0e41234f24b6da002d962a26c2495ea16a425f
➜ fichier .git/objects/8d/0e41234f24b6da002d962a26c2495ea16a425f
.git/objects/8d/0e41234f24b6da002d962 a26c2495ea16a425f : exécutable VAX COFF non supprimé - version 16694
En fait, nous pouvons également obtenir le contenu de l'objet binaire via le code Python ici.
importer
le contenu de zlib = open('0e41234f24b6da002d962a26c2495ea16a425f', 'rb').read()
zlib.decompress(content)
Parlons de l'espace de travail et de la zone de préparation
Parlons de l'espace de travail et de la zone de stockage intermédiaire, et de la façon dont les fichiers sont synchronisés entre l'espace de travail et la zone de cache.
Nous en avons également parlé dans le chapitre précédent : lorsque nous exécutons la commande git status, comment l'outil Git sait-il que nous avons un fichier qui n'est pas suivi, et où sont stockées les informations sur le nom du fichier ?
La réponse à tout cela commence par la zone de travail et la zone d'index. Selon les différents états qu'il stocke, Git divise « l'espace » de l'état correspondant en trois catégories : zone de travail, zone de stockage temporaire (aussi appelée zone d'index) et zone de version. Pour un exemple spécifique, reportez-vous à la figure ci-dessous.
Pour une compréhension plus approfondie, l'objet objet correspondant doit être généré après l'exécution de la commande git add, mais il stocke le contenu de la classe, la taille et le contenu du fichier, et ne contient pas d'informations sur le nom du fichier. Les informations relatives au nom du fichier sont incluses dans le fichier d'index généré (fichier d'index).
Lorsque nous visualisons directement le contenu du fichier d'index, nous trouvons des caractères tronqués que nous ne pouvons pas comprendre, mais grâce à la sortie de base, nous pouvons voir le nom du fichier. Pour afficher le contenu du fichier d'index, vous pouvez le visualiser via les commandes appropriées fournies par Git.
# Exécuter à gauche
$ echo "file1" > file1.txt
$ git add file1.txt
$ cat .git/index
$ git ls-files # Répertorier les informations sur la liste de fichiers de la zone de transit actuelle
$ git ls-files -s # Liste Informations détaillées sur le fichier de la zone de transit actuel
# Exécuter
$ watch -n 1 -d tree .git à droite
Lors de l'ajout de fichiers, les fichiers ou répertoires circuleront de l'espace de travail vers la zone de préparation. De plus, certaines autres opérations entraîneront certaines différences entre l'espace de travail et la zone de préparation. Cela conduira à la différence entre les deux lorsque nous exécuterons git status.
Après les opérations suivantes, le contenu de l'espace de travail et de la zone de stockage temporaire sera incohérent. Nous pouvons également vérifier la différence via des commandes. Lorsque nous utilisons la commande add pour ajouter un nouveau fichier à la zone de stockage temporaire, nous constaterons qu'il est cohérent.
# Exécuter à gauche
$ git status
$ echo "file2" > file2.txt
$ git ls-files -s
$ git status
$ git add file2.txt
$ git ls-files -s
$ git status
# Exécuter à droite
$ watch -n 1 - dtree.git
Si nous modifions un fichier ici, il est évident que notre zone de travail et la zone de stockage temporaire sont à nouveau incohérentes à ce moment-là. Lorsque nous utilisons la commande pour vérifier l'état du fichier, nous constatons qu'un fichier a été modifié, mais comment Git le sait-il ? Ahem, il est obtenu en recherchant le contenu du fichier d'index, en trouvant le nom de fichier correspondant et l'objet référencé en interne, et en le comparant avec le contenu du fichier dans l'espace de travail.
# Exécutez
$ git ls-files -s à gauche
$ echo "file.txt" > file1.txt
$ git status
# Exécutez
$ watch -n 1 -d tree .git à droite
À ce stade, si nous utilisons la commande git add pour enregistrer le contenu modifié dans la zone de stockage temporaire, nous constaterons que la valeur de référence de l'objet blob de l'objet correspondant au fichier a changé. À l'heure actuelle, on peut constater qu'il y a trois objets dans le répertoire des objets, dont file1.txt en occupe deux, mais il n'y a que deux fichiers. Affichez le contenu de l'objet blob correspondant via la commande et constatez qu'ils sont différents.
# Exécutez
$ git ls-files -s à gauche
$ git add file1.txt
$ git ls-files -s
# Exécutez
$ watch -n 1 -d tree .git à droite
Comprendre le principe de la soumission de commit
Après avoir exécuté la commande git commit, qu’avez-vous fait exactement ?
L'enregistrement de validation dans le référentiel Git enregistre un instantané de tous les fichiers de votre répertoire. C'est comme copier l'intégralité du répertoire puis le coller, mais c'est beaucoup plus élégant que de copier et coller ! Git souhaite que les enregistrements de validation soient aussi légers que possible, afin de ne pas copier aveuglément l'intégralité du répertoire à chaque fois que vous effectuez une validation. Lorsque les conditions le permettent, il comparera la version actuelle avec la version précédente dans l'entrepôt et regroupera toutes les différences sous forme d'enregistrement de validation. Git conserve également un historique des commits. C'est pourquoi la plupart des enregistrements de validation ont des nœuds parents au-dessus d'eux.
Lorsque nous utilisons la commande add pour soumettre l'espace de travail à la zone de préparation, la zone de préparation enregistre en fait un état du fichier actuel, y compris les répertoires et fichiers présents, ainsi que leur taille et leur contenu correspondants. Mais nous devons finalement le soumettre à l'entrepôt de code (local), et la commande est git commit.
Et que s'est-il passé lorsque nous avons exécuté la commande git commit ? On peut voir qu'après la soumission, deux objets d'information sont générés dans le répertoire .git et de nouveaux fichiers sont générés dans les répertoires logs et refs. Grâce aux opérations suivantes, nous pouvons visualiser le type et le contenu correspondant de sa soumission.
# Exécuter à gauche
$ git commit -m "1st commit"
$ git cat-file -t 6e4a700 # Afficher le type de l'objet de validation
$ git cat-file -p 6e4a700 # Afficher le contenu de l'objet de validation
$ git cat- file -t 64d6ef5 # Afficher le type d'objet arbre
$ git cat-file -p 64d6ef5 # Afficher le contenu de l'objet arbre
# Exécuter à droite
$ watch -n 1 -d tree .git
De cette façon, nous comprenons que lorsque nous exécutons la commande git commit, un objet commit et un objet arborescence seront générés. Le contenu de l'objet commit contient un objet arbre et les informations de soumission associées, et l'objet arbre contient l'état du fichier (nom du fichier et objet blob) dans la version que nous avons soumise cette fois, afin que nous connaissions les modifications de cette soumission.
Après avoir soumis cette fois-ci, en plus des modifications apportées au répertoire des objets, d'autres modifications ont été apportées. Par exemple, les répertoires des logs et des références ont changé. Nous vérifions le contenu du répertoire refs et constatons qu'il pointe vers l'objet de validation 6e4a70, c'est-à-dire que le dernier commit sur la branche master actuelle est ce 6e4a70.
L'objet commit 6e4a70 possède un pointeur HEAD, qui est le fichier HEAD dans le répertoire .git. Son essence est un pointeur qui pointe toujours vers la branche sur laquelle nous travaillons actuellement, c'est-à-dire que nous travaillons ici sur la branche master. Lorsque nous changeons de branche, le pointeur vers ce fichier changera également de manière aléatoire.
# Exécutez
$ cat .git/refs/heads/master à gauche
$ cat .git/HEAD
# Exécutez
$ watch -n 1 -d tree .git à droite
Approfondir la compréhension du commit commit
Après avoir exécuté la commande git commit, qu’avez-vous fait exactement ?
Lorsque nous avons modifié, ajouté et soumis à nouveau le contenu du fichier file2.txt, nous avons constaté que lorsque nous soumettions le contenu de l'objet de validation, il contenait les informations de validation du nœud parent. Pour comprendre, vous pouvez consulter l’organigramme de soumission ci-dessous.
# Exécuter à gauche
$ echo "file2.txt" > file2.txt
$ git status
$ git add file2.txt
$ git ls-files -s
$ git cat-file -p 0ac9638
$ git commit -m "2nd commit"
$ git cat -file -p bab53ff
$ git cat-file -p 2f07720
# Exécuter à droite
$ watch -n 1 -d tree .git
Dans Git, les dossiers vides ne sont pas inclus dans la plage de suivi et l'ajout de dossiers n'ajoute pas d'objets. Lorsque nous examinons le contenu de l'index, nous constatons que le nom du fichier contient un chemin relatif.
Lorsque nous soumettons via la commande commit, nous constatons que trois objets objets sont générés. Comme l'opération de validation ne génère pas d'objets blob, il s'agit d'un objet de validation et de deux objets d'arborescence. On peut constater que l'objet arborescence contient une arborescence contenant un répertoire, qui contient le contenu du fichier objet.
L'état du fichier indiqué dans la figure ci-dessous montre le concept de version dans Git. Autrement dit, l'objet commit pointe vers la racine (arborescence) de l'arborescence des répertoires de fichiers dans cette version, puis l'arborescence pointe vers l'objet blob (fichier) et l'objet arborescence (répertoire), afin qu'il puisse être répété à l'infini pour former une version complète.
# Exécuter à gauche
$ mkdir floder1
$ echo "file3" > floder1/file3.txt
$ git add floder1
$ git ls-files -s
$ git commit -m "3rd commit"
$ git cat-file -p 1711e01
$ git cat -file -p 9ab67f8
# Exécuter à droite
$ watch -n 1 -d tree .git
L'état du cycle de vie du fichier
Pour résumer, l'état du fichier dans Git et comment le changer.
Nous avons désormais une compréhension de base de la façon dont les fichiers sont suivis et synchronisés entre l'espace de travail, la zone de préparation et le référentiel de code. Dans les opérations Git, quels sont les états possibles des fichiers et comment changer d’état ? Résumons-les ici !
La signification de Branch et HEAD
Après avoir exécuté la commande git branch, qu'a-t-elle fait exactement ?
Qu'est-ce qu'une succursale exactement ? Qu’en est-il du changement de succursale ? En regardant la documentation officielle de Git, on peut comprendre qu'une branche est un pointeur vers un objet commit avec un nom (master/dev).
Lorsque nous initialisons l'entrepôt, le fournisseur nous attribuera une branche appelée master par défaut (dans la dernière version, l'entrepôt par défaut a été remplacé par main), et la branche master pointe vers le dernier commit. Pourquoi devons-nous nommer la branche ? Juste pour faciliter son utilisation et sa mémorisation, on peut simplement comprendre que la commande alias a la même signification.
Sur la base des fondements ci-dessus, nous devons réfléchir à la manière dont les succursales sont mises en œuvre et fonctionnent. Pour implémenter une branche, nous devons essentiellement résoudre deux problèmes. Le premier est de stocker le commit pointé par chaque branche. Le deuxième problème est de nous aider à identifier la branche actuelle lors du changement de branche.
Dans Git, il possède un fichier HEAD très spécial. Le fichier HEAD est un pointeur, et l'une de ses caractéristiques est qu'il pointe toujours vers le dernier objet commit de la branche actuelle. Et ce fichier HEAD résout simplement les deux problèmes que nous avons évoqués ci-dessus.
Lorsque nous passons la branche de master à dev, le fichier HEAD basculera également immédiatement, ce qui pointe vers le pointeur de dev. Le design est tellement beau, il est digne d'être un génie, une bonne tête.
# Exécutez
$ cat .git/HEAD à gauche
$ cat .git/refs/heads/master
$ git cat-file -t 1711e01
# Exécutez
$ glo = git log à droite
La logique derrière le fonctionnement de la succursale
Après avoir exécuté la commande git branch, qu'a-t-elle fait exactement ?
Ici, nous pouvons voir qu'après le changement de branche, le pointeur HEAD a changé.
# Exécuter à gauche
$ git branch
$ git branch dev
$ ll .git/refs/heads
$ cat .git/refs/heads/master
$ cat .git/refs/heads/dev
$ cat .git/HEAD
$ git checkout dev
$ cat .git/HEAD
# Exécuter
$ glo = git log à droite
Ce qu'il faut noter ici, c'est que même si nous supprimons la branche, certains objets uniques sur la branche ne seront pas supprimés. Ces objets sont en fait ce que nous appelons communément des objets poubelles. Il existe également des objets poubelles générés par nous à l'aide de la commande add à plusieurs reprises. Comment effacer et recycler ces objets poubelles ? Nous y reviendrons plus tard.
# Exécuter à gauche
$ echo "dev" > dev.txt
$ git add dev.txt
$ git commit -m "1er commit de la branche dev"
$ git checkout master
$ git branch -d dev
$ git branch -D dev
$ git cat-file -t 861832c
$ git cat-file -p 861832c
$ git cat-file -p 680f6e9
$ git cat-file -p 38f8e88
# Exécuter à droite
$ glo = git log
opérations de paiement et de validation
Parlons des opérations de checkout et de commit !
Lorsque nous exécutons la commande checkout, elle peut non seulement changer de branche, mais également basculer vers le commit spécifié, c'est-à-dire que le fichier HEAD pointera vers un certain objet de commit. Dans Git, le phénomène selon lequel le fichier HEAD ne pointe pas vers le maître est appelé HEAD détaché.
Que le fichier HEAD pointe vers un nom de branche ou vers un objet de validation, l'essence est la même, car le nom de branche pointe également vers un objet de validation.
# Exécutez
$ git checkout 6e4a700 à gauche
$ git log
# Exécutez
$ glo = git log à droite
Lorsque nous passons au commit spécifié, si nous devons continuer à modifier la soumission de code sur le commit correspondant, nous pouvons utiliser la commande switch mentionnée dans l'image ci-dessus pour créer une nouvelle branche, puis la soumettre. Cependant, nous ne jouons généralement pas et utilisons la commande checkout pour créer de nouvelles branches.
$ git checkout -b tmp
$ git journal
Même lorsque cela est possible, nous l’utilisons rarement. Vous vous souvenez de la branche de développement que nous avons créée dans le chapitre précédent ? Nous avons créé la branche et avons eu un nouveau commit, mais nous l'avons supprimé sans la fusionner dans la branche principale. Si vous utilisez la commande log pour l'afficher maintenant, vous ne pourrez plus le voir.
En fait, tu ne le vois pas ? Tout le monde doit se rappeler que toute opération dans Git, telle que la suppression de branches. Il supprime uniquement la référence du pointeur pointant vers un commit spécifique, mais le commit lui-même ne sera pas supprimé, c'est-à-dire que le commit de la branche dev est toujours là.
Alors comment trouver ce commit ? Après l'avoir trouvé, nous pouvons continuer à travailler dessus, ou rechercher les données du fichier précédent, etc.
la première méthode :
-
[Lutter n'est pas bon, faites un mauvais geste]
-
Sous le répertoire des objets, regardez-les un par un, puis basculez.
La deuxième méthode :
-
[Méthode de fonctionnement recommandée]
-
Utilisez la commande dédiée git reflog fournie par Git pour le trouver.
-
Le but de cette commande est d'enregistrer toutes nos opérations précédentes.
# Exécutez
$ git reflog à gauche
$ git checkout 9fb7a14
$ git checkout -b dev
# Exécutez
$ glo = git log à droite
Parlez de la logique d'exécution de diff
Après avoir exécuté la commande diff, comment la logique Git les compare-t-elle ?
Juste dans cette section, nous utilisons l'entrepôt de la section précédente, après avoir modifié le contenu du fichier, quel est le résultat de la commande diff ? Jetons un coup d’œil et étudions ensemble ici !
$ echo "hello" > file1.txt
$ git diff
$ git cat-file -p 42d9955
$ git cat-file -p ce01362
# Le principe des commandes suivantes est le même
$ git diff --cached
$ git diff HEAD
Comment Git ajoute un référentiel distant
Comment associer notre entrepôt local à l'entrepôt sur le serveur distant ?
Initialiser l'entrepôt
$ git init
$ git add README.md
$ git commit -m "premier commit"
Associer un entrepôt distant
Lorsque nous utilisons la commande ci-dessus pour nous associer au référentiel du serveur distant, notre répertoire .git local changera également. Si vous affichez le fichier .git/config via la commande, vous pouvez voir que le champ [remote] apparaît dans le fichier de configuration.
#Associer un entrepôt distant
$ git remote add origin [email protected]:escapelife/git-demo.git
➜ cat .git/config
[core]
depositformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = [email protected]:escapelife/git-demo.git
fetch = +refs/heads/*:refs/remotes/origine/*
Pousser la succursale locale
Lorsque nous exécutons la commande suivante, la branche principale locale est poussée vers la branche principale de l'entrepôt d'origine distant. Après cela, lorsque nous nous connectons à GitHub, nous pouvons voir les fichiers poussés et le contenu du répertoire.
Lors du transfert du contenu de la branche, le nombre d'objets poussés sera répertorié, leur contenu sera compressé, puis poussé vers notre référentiel GitHub distant, et une branche principale distante (référentiel d'origine) sera créée.
# Push la branche locale
$ git push -u origin master
Après avoir poussé, nous pouvons constater que le .git local a généré des fichiers et des répertoires. Comme indiqué ci-dessous, quatre répertoires et deux fichiers seront ajoutés, qui sont tous des informations provenant de l'entrepôt distant. Lorsque nous visualisons le contenu du fichier maître via la commande, nous constaterons qu'il s'agit également d'un objet de validation. À l’heure actuelle, cela correspond à ce que pointe notre succursale principale locale. Il est utilisé pour représenter la version actuelle de l'entrepôt distant et est utilisé pour le distinguer et le relire de la version locale.
T T TREE .git e
─ LOGS
│ & nbsp; & nbsp; ├ ─ tête
│ & nbsp; & nbsp; └
─ & nbsp;
& nbsp; │
& nbsp; & nbsp; │ ├── maître
│ │ └── tmp
│ └── télécommandes # ajouter un répertoire
│ └── origin # ajouter un répertoire
│ └── master # ajouter un fichier
└── refs
├── heads
│ &n cuillère à soupe ; ├ ── dev
│ ├── master
│ └── tmp
├── télécommandes # Nouveau répertoire
│ └─ ─ origin # Ajouter un nouveau répertoire
│ └── maître # Ajouter un nouveau fichier
└── balises
Code de stockage en entrepôt distant
Utilisez GitLab pour comprendre comment le serveur d'entrepôt distant stocke notre code !
Après avoir écrit le code, soumettez-le au serveur distant correspondant, dont la structure de stockage est exactement la même que notre adresse. Si l’on y réfléchit, il serait surprenant que ce soit différent.
Git est à l'origine une plate-forme de distribution de code sans nœud central, c'est-à-dire que chaque nœud est un nœud maître, sa structure de répertoires de stockage est donc cohérente. De cette façon, quel que soit le contenu du nœud perdu ou manquant, nous pouvons le retrouver via d'autres nœuds. Le serveur Git n'est qu'un nœud qui peut nous aider à le trouver en temps réel.