我尝试将【Git】的“.git”文件夹交给Git进行管理
首先
2023年Git圣诞日历的第三天帖子。请多多关照。
我认为在上次和前次的帖子中,已经能够使用以下命令了。
-
- git init
-
- git add
-
- git commit
-
- git branch
-
- git checkout
- git merge
我对内部的操作感到好奇,所以这次我想观察一下执行上述命令时.git文件夹内部的变化。
完成的任务
我们将按照下面的感觉继续进行。
创建存储库(A)
⬇
在存储库(A)的.git文件夹中运行git init来创建管理.git的存储库(B)
⬇
在存储库(A)处运行Git命令以观察存储库(B)中的差异
由于我使用了两个Git仓库,所以可能会有一些转换不太明显的地方,请多包涵。
准备
-
- 「git/sample2」フォルダを用意。
- このフォルダでGitの各コマンドを打って.gitの中身を観察していきます。
初始化 Git
执行git init命令来创建存储库(A)的.git文件夹。
~/Desktop/git/sample2
$ git init
Initialized empty Git repository in フォルダ名
.gitフォルダの構成
.git
│ config
│ description
│ HEAD
│
├─hooks
│ applypatch-msg.sample
│ commit-msg.sample
│ fsmonitor-watchman.sample
│ post-update.sample
│ pre-applypatch.sample
│ pre-commit.sample
│ pre-push.sample
│ pre-rebase.sample
│ pre-receive.sample
│ prepare-commit-msg.sample
│ update.sample
│
├─info
│ exclude
│
├─objects
│ ├─info
│ └─pack
└─refs
├─heads
└─tags
在.git文件夹中使用git init命令创建一个仓库(B)。
~/Desktop/git/sample2/.git (GIT_DIR!)
$ git init
Initialized empty Git repository in フォルダ名
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
HEAD
config
description
hooks/
info/
nothing added to commit but untracked files present (use "git add" to track)
~/Desktop/git/sample2/.git (master)
$ git add .
~/Desktop/git/sample2/.git (master)
$ git commit -m"git init後"
[master (root-commit) a47036c] git init後
使用git add命令
在(A)仓库中创建一个名为“sample.txt”的文件。
~/Desktop/git/sample2 (master)
$ echo "hello world" > sample.txt
~/Desktop/git/sample2 (master)
$ ls
sample.txt
创建文件后的.git文件夹没有任何特殊变化。
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
nothing to commit, working tree clean
我尝试执行git add。
~/Desktop/git/sample2 (master)
$ git add .
在使用 git add 之后的 .git 文件夹。
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
index
objects/
nothing added to commit but untracked files present (use "git add" to track)
哦,有了变化呢。
.gitフォルダの現在の状況
C:.
│ config
│ description
│ HEAD
│ index ←←←新規
│
├─hooks
│ applypatch-msg.sample
│ commit-msg.sample
│ fsmonitor-watchman.sample
│ post-update.sample
│ pre-applypatch.sample
│ pre-commit.sample
│ pre-push.sample
│ pre-rebase.sample
│ pre-receive.sample
│ prepare-commit-msg.sample
│ update.sample
│
├─info
│ exclude
│
├─objects
│ ├─3b ←←←新規
│ │ 18e512dba79e4c8300dd08aeb37f8e728b8dad
│ │
│ ├─info
│ └─pack
└─refs
├─heads
└─tags
与.git文件夹相比,可以看出在git init后,新创建了index和objects下的3b/18e512…。由于index是一个二进制文件,很难验证差异,因此最后将在附注中进行解释。
让我们来看一看对象的内容。
~/Desktop/git/sample2 (master)
$ git cat-file -p 3b18e512dba79e4c8300dd08aeb37f8e728b8dad
hello world
在Git添加时会生成一个blob对象。
我只知道这些。
提交代码
我接下来尝试提交一次。
~/Desktop/git/sample2 (master)
$ git commit -m"first commit"
[master (root-commit) 411124e] first commit
我会尝试在.git中执行git status。
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: index
Untracked files:
(use "git add <file>..." to include in what will be committed)
COMMIT_EDITMSG
logs/
objects/02/
objects/88/
refs/
no changes added to commit (use "git add" and/or "git commit -a")
.git文件夹内容有所改变。指的是整个.git文件夹。
.git
│ COMMIT_EDITMSG ←←新規
│ config
│ description
│ HEAD
│ index ←←更新
│
├─hooks
│ applypatch-msg.sample
│ commit-msg.sample
│ fsmonitor-watchman.sample
│ post-update.sample
│ pre-applypatch.sample
│ pre-commit.sample
│ pre-push.sample
│ pre-rebase.sample
│ pre-receive.sample
│ prepare-commit-msg.sample
│ update.sample
│
├─info
│ exclude
│
├─logs ←←新規
│ │ HEAD
│ │
│ └─refs
│ └─heads
│ master
│
├─objects
│ ├─02 ←←新規
│ │ 3bd50171db535beab09fed56bd5a9281b01555
│ │
│ ├─3b
│ │ 18e512dba79e4c8300dd08aeb37f8e728b8dad
│ │
│ ├─88 ←←新規
│ │ ccc6b27fbf7beb37e2b2dadceef08ed83a5716
│ │
│ ├─info
│ └─pack
└─refs
├─heads
│ master ←←新規
│
└─tags
我们逐个来看一下。
首先,由于生成了两个对象,所以我会查看它们的内容。
~/Desktop/git/sample2 (master)
$ git cat-file -p 88ccc6b27fbf7beb37e2b2dadceef08ed83a5716
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad sample.txt
~/Desktop/git/sample2 (master)
$ git cat-file -p 023bd50171db535beab09fed56bd5a9281b01555
tree 88ccc6b27fbf7beb37e2b2dadceef08ed83a5716
author hogehoge <fugafuga> 1699592736 +0900
committer hogehoge <fugafuga> 1699592736 +0900
first commit
我们可以看到树对象和提交对象已经生成。我们还可以看到树对象具有对Blob的引用,而提交对象具有对树对象的引用。
接下来我们看一下COMMIT_EDITMSG。
$ cat COMMIT_EDITMSG
first commit
这是之前提交的提交消息吗?目前为止,我不知道更多的信息。
我们稍后再试一次提交,看看是否会有变化。
让我们接着看看refs/heads/master。
$ cat refs/heads/master
023bd50171db535beab09fed56bd5a9281b01555
这个是指在objects文件夹中新创建的提交对象的哈希值。
最后是logs/HEAD和logs/refs/master。
$ cat logs/HEAD
0000000000000000000000000000000000000000 023bd50171db535beab09fed56bd5a9281b01555 hogehoge <fugafuga> 1699592736 +0900 commit (initial): first commit
$ cat logs/refs/heads/master
0000000000000000000000000000000000000000 023bd50171db535beab09fed56bd5a9281b01555 hogehoge <fugafuga> 1699592736 +0900 commit (initial): first commit
日志就像它的名字一样,用来存储记录。每个日志都记录了HEAD从哪个提交到哪个提交移动,以及分支从哪个提交到哪个提交移动。由于这次没有对分支进行特别操作,所以看起来内容是相同的。
因为我在意COMMIT_EDITMSG的处理方式,所以让我们再次进行提交吧。随意更新”sample.txt”并重新提交。
~/Desktop/git/sample2 (master)
$ echo "hello" > sample.txt
~/Desktop/git/sample2 (master)
$ git add .
~/Desktop/git/sample2 (master)
$ git commit -m"second commit"
[master 6cf4fd0] second commit
1 file changed, 1 insertion(+), 1 deletion(-)
对于.git会怎么样呢?我试试看git status。
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: COMMIT_EDITMSG
modified: index
modified: logs/HEAD
modified: logs/refs/heads/master
modified: refs/heads/master
Untracked files:
(use "git add <file>..." to include in what will be committed)
objects/6c/
objects/ce/
objects/e3/
no changes added to commit (use "git add" and/or "git commit -a")
先来看看我们想看的COMMIT_EDITMSG文件的差异。
~/Desktop/git/sample2/.git (master)
$ git diff COMMIT_EDITMSG
diff --git a/COMMIT_EDITMSG b/COMMIT_EDITMSG
index 44e4d81..2ff0cc0 100644
--- a/COMMIT_EDITMSG
+++ b/COMMIT_EDITMSG
@@ -1 +1 @@
-first commit
+second commit
看起来好像是保存着前一个提交信息的文件。
我想你已经猜到了,我们是否也应该查看其他文件呢?
这是当前的.git文件夹的情况。
.git
│ COMMIT_EDITMSG ←←←更新
│ config
│ description
│ HEAD
│ index ←←←更新
│
├─hooks
│ applypatch-msg.sample
│ commit-msg.sample
│ fsmonitor-watchman.sample
│ post-update.sample
│ pre-applypatch.sample
│ pre-commit.sample
│ pre-push.sample
│ pre-rebase.sample
│ pre-receive.sample
│ prepare-commit-msg.sample
│ update.sample
│
├─info
│ exclude
│
├─logs
│ │ HEAD ←←←更新
│ │
│ └─refs
│ └─heads
│ master ←←←更新
│
├─objects
│ ├─02
│ │ 3bd50171db535beab09fed56bd5a9281b01555
│ │
│ ├─3b
│ │ 18e512dba79e4c8300dd08aeb37f8e728b8dad
│ │
│ ├─6c ←←←新規
│ │ f4fd07bd3d1f982045f50fae9dc070d6967f36
│ │
│ ├─88
│ │ ccc6b27fbf7beb37e2b2dadceef08ed83a5716
│ │
│ ├─ce ←←←新規
│ │ 013625030ba8dba906f756967f9e9ca394464a
│ │
│ ├─e3 ←←←新規
│ │ d14d7340059b5852f32f29574e98ff73eb3c47
│ │
│ ├─info
│ └─pack
└─refs
├─heads
│ master
│
└─tags
objectsフォルダ配下の新規作成されたファイル3つ
~/Desktop/git/sample2 (master)
$ git cat-file -p ce013625030ba8dba906f756967f9e9ca394464a
hello
~/Desktop/git/sample2 (master)
$ git cat-file -p e3d14d7340059b5852f32f29574e98ff73eb3c47
100644 blob ce013625030ba8dba906f756967f9e9ca394464a sample.txt
~/Desktop/git/sample2 (master)
$ git cat-file -p 6cf4fd07bd3d1f982045f50fae9dc070d6967f36
tree e3d14d7340059b5852f32f29574e98ff73eb3c47
parent 023bd50171db535beab09fed56bd5a9281b01555
author hogehoge <fugafuga> 1699594574 +0900
committer hogehoge <fugafuga> 1699594574 +0900
second commit
这是关于Blob、Tree和Commit对象的内容。
logsフォルダ配下の更新されたファイルの差分
~/Desktop/git/sample2/.git (master)
$ git diff logs/
diff --git a/logs/HEAD b/logs/HEAD
index 8783cde..58d6c1d 100644
--- a/logs/HEAD
+++ b/logs/HEAD
@@ -1,2 +1,2 @@
0000000000000000000000000000000000000000 023bd50171db535beab09fed56bd5a9281b01555 hogehoge <fugafuga> 1699592736 +0900 commit (initial): first commit
+023bd50171db535beab09fed56bd5a9281b01555 6cf4fd07bd3d1f982045f50fae9dc070d6967f36 hogehoge <fugafuga> 1699594574 +0900 commit: second commit
diff --git a/logs/refs/heads/master b/logs/refs/heads/master
index 8783cde..58d6c1d 100644
--- a/logs/refs/heads/master
+++ b/logs/refs/heads/master
@@ -1,2 +1,2 @@
0000000000000000000000000000000000000000 023bd50171db535beab09fed56bd5a9281b01555 hogehoge <fugafuga> 1699592736 +0900 commit (initial): first commit
+023bd50171db535beab09fed56bd5a9281b01555 6cf4fd07bd3d1f982045f50fae9dc070d6967f36 hogehoge <fugafuga> 1699594574 +0900 commit: second commit
日志是这样写的。
refs配下の更新されたファイルの差分
~/Desktop/git/sample2/.git (master)
$ git diff refs/
diff --git a/refs/heads/master b/refs/heads/master
index f1bb341..ed3d53b 100644
--- a/refs/heads/master
+++ b/refs/heads/master
@@ -1 +1 @@
-023bd50171db535beab09fed56bd5a9281b01555
+6cf4fd07bd3d1f982045f50fae9dc070d6967f36
主分支的提交已经移动了。
分支
接下来,让我们使用git branch命令创建一个分支。
我们将创建另一个分支。
~/Desktop/git/sample2 (master)
$ git branch another
.git文件夹里面发生了什么?
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
logs/refs/heads/another
refs/heads/another
nothing added to commit but untracked files present (use "git add" to track)
我们做了两个文件,请看一下。
$ cat refs/heads/another
6cf4fd07bd3d1f982045f50fae9dc070d6967f36
$ cat logs/refs/heads/another
0000000000000000000000000000000000000000 6cf4fd07bd3d1f982045f50fae9dc070d6967f36 hogehoge <fugafuga> 1699595907 +0900 branch: Created from master
参考/ブランチ/another 指向与 master 相同的提交。
我会查看日志以确认。
~/Desktop/git/sample2 (master)
$ git log --oneline
6cf4fd0 (HEAD -> master, another) second commit
023bd50 first commit
切换分支
那么,让我们尝试使用git checkout切换分支。
我将切换到另一个分支。
~/Desktop/git/sample2 (master)
$ git checkout another
Switched to branch 'another'
~/Desktop/git/sample2 (another)
现在.git会怎么样呢?
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: HEAD
modified: logs/HEAD
no changes added to commit (use "git add" and/or "git commit -a")
看到了吧,HEAD和logs/HEAD已经更新了。我试着取出它们的差异。
HEADファイル
~/Desktop/git/sample2/.git (master)
$ git diff HEAD -- HEAD
diff --git a/HEAD b/HEAD
index cb089cd..b64c555 100644
--- a/HEAD
+++ b/HEAD
@@ -1 +1 @@
-ref: refs/heads/master
+ref: refs/heads/another
刚刚创建的refs/heads/another文件已被更新以引用它。当然,这是理所当然的,因为HEAD已被更新为引用another。
再次强调一下,refs/heads/another的内容如下所示。
$ cat refs/heads/another
6cf4fd07bd3d1f982045f50fae9dc070d6967f36
从这个问题中,HEAD会持续指向另一个分支的提交6cf4fd。
logs/HEADファイル
~/Desktop/git/sample2/.git (master)
$ git diff HEAD -- logs/HEAD
diff --git a/logs/HEAD b/logs/HEAD
index 58d6c1d..9bb9ffe 100644
--- a/logs/HEAD
+++ b/logs/HEAD
@@ -1,2 +1,3 @@
0000000000000000000000000000000000000000 023bd50171db535beab09fed56bd5a9281b01555 hogehoge <fugafuga> 1699592736 +0900 commit (initial): first commit
023bd50171db535beab09fed56bd5a9281b01555 6cf4fd07bd3d1f982045f50fae9dc070d6967f36 hogehoge <fugafuga> 1699594574 +0900 commit: second commit
+6cf4fd07bd3d1f982045f50fae9dc070d6967f36 6cf4fd07bd3d1f982045f50fae9dc070d6967f36 hogehoge <fugafuga> 1699596443 +0900 checkout: moving from master to another
这是关于HEAD引用的日志对吧。是这样记录日志的方式。
将git合并
最后,我们将进行git merge,然后观察.git文件夹。
做好準備
由于准备工作很繁琐,我们将准备和观察的步骤分开了。首先,作为准备工作,我们在另一个分支上创建了一个适当的提交。
~/Desktop/git/sample2 (another)
$ echo "another" > sample.txt
~/Desktop/git/sample2 (another)
$ git add .
~/Desktop/git/sample2 (another)
$ git commit -m"third commit"
[another cbc33d4] third commit
1 file changed, 1 insertion(+), 1 deletion(-)
.git文件夹的状态。没有什么特别值得注意的地方,所以先进行提交。
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: COMMIT_EDITMSG
modified: index
modified: logs/HEAD
modified: logs/refs/heads/another
modified: refs/heads/another
Untracked files:
(use "git add <file>..." to include in what will be committed)
objects/11/
objects/9b/
objects/cb/
no changes added to commit (use "git add" and/or "git commit -a")
~/Desktop/git/sample2/.git (master)
$ git add .
~/Desktop/git/sample2/.git (master)
$ git commit -m"git commit 1回目@another"
[master d25acad] git commit 1回目@another
这次将切换到主分支master。
~/Desktop/git/sample2 (another)
$ git checkout master
Switched to branch 'master'
.git文件夹的状态。
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: HEAD
modified: index
modified: logs/HEAD
no changes added to commit (use "git add" and/or "git commit -a")
~/Desktop/git/sample2/.git (master)
$ git add .
~/Desktop/git/sample2/.git (master)
$ git commit -m"git checkout後another→master"
[master c15e8de] git checkout後another→master
3 files changed, 2 insertions(+), 1 deletion(-)
由于从另一个分支更新文件的状态回到了原始的主分支,因此,“index”也被更新了。
合并
(Maaji)
好的,我现在要將另一個分支合併到主分支上試試看。
~/Desktop/git/sample2 (master)
$ git merge --no-ff another
Merge made by the 'recursive' strategy.
sample.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
.git文件夹的状态。
(The state of the .git folder.)
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: index
modified: logs/HEAD
modified: logs/refs/heads/master
modified: refs/heads/master
Untracked files:
(use "git add <file>..." to include in what will be committed)
ORIG_HEAD
objects/bb/
no changes added to commit (use "git add" and/or "git commit -a")
让我们来看看,一个新的ORIG_HEAD和对象被生成了。
$ cat ORIG_HEAD
6cf4fd07bd3d1f982045f50fae9dc070d6967f36
我不记得这是哪个哈希值了…所以我来查看一下日志。
~/Desktop/git/sample2 (master)
$ git cat-file -p 6cf4fd07bd3d1f982045f50fae9dc070d6967f36
tree e3d14d7340059b5852f32f29574e98ff73eb3c47
parent 023bd50171db535beab09fed56bd5a9281b01555
author hogehoge <fugafuga> 1699594574 +0900
committer hogehoge <fugafuga> 1699594574 +0900
second commit
~/Desktop/git/sample2 (master)
$ git log --oneline --graph
* bb54bb5 (HEAD -> master) Merge branch 'another'
|\
| * cbc33d4 (another) third commit
|/
* 6cf4fd0 second commit
* 023bd50 first commit
ORIG_HEAD所引用的6cf4fd是主分支(master)的直前提交,所以通过git reset ORIG_HEAD –hard命令可以回到合并之前的状态。
新产生的对象是什么内容呢?
MINGW64 ~/Desktop/git/sample2 (master)
$ git cat-file -p bb54bb567fc99a85750561362e2dcd892f179434
tree 11982c20951b8249234a871fb7fce5983fe1465f
parent 6cf4fd07bd3d1f982045f50fae9dc070d6967f36
parent cbc33d4a1844fddc6f4dad5918897d00a6eaa80f
author hogehoge <fugafuga> 1699598971 +0900
committer hogehoge <fugafuga> 1699598971 +0900
Merge branch 'another'
这个合并提交是引用了两个父对象的对象,对吧。
由于浏览其他文件会感到厌烦,所以我只会查看个人感兴趣的logs目录下的文件。
~/Desktop/git/sample2/.git (master)
$ git diff logs/
diff --git a/logs/HEAD b/logs/HEAD
index c43111f..eb4e0a5 100644
--- a/logs/HEAD
+++ b/logs/HEAD
@@ -4,3 +4,4 @@
6cf4fd07bd3d1f982045f50fae9dc070d6967f36 6cf4fd07bd3d1f982045f50fae9dc070d6967f36 hogehoge <fugafuga> 1699596443 +0900 checkout: moving from master to another
6cf4fd07bd3d1f982045f50fae9dc070d6967f36 cbc33d4a1844fddc6f4dad5918897d00a6eaa80f hogehoge <fugafuga> 1699598305 +0900 commit: third commit
cbc33d4a1844fddc6f4dad5918897d00a6eaa80f 6cf4fd07bd3d1f982045f50fae9dc070d6967f36 hogehoge <fugafuga> 1699598624 +0900 checkout: moving from another to master
+6cf4fd07bd3d1f982045f50fae9dc070d6967f36 bb54bb567fc99a85750561362e2dcd892f179434 hogehoge <fugafuga> 1699598971 +0900 merge another: Merge made by the 'recursive' strategy.
diff --git a/logs/refs/heads/master b/logs/refs/heads/master
index 58d6c1d..1256f4a 100644
--- a/logs/refs/heads/master
+++ b/logs/refs/heads/master
@@ -1,2 +1,3 @@
0000000000000000000000000000000000000000 023bd50171db535beab09fed56bd5a9281b01555 hogehoge <fugafuga> 1699592736 +0900 commit (initial): first commit
023bd50171db535beab09fed56bd5a9281b01555 6cf4fd07bd3d1f982045f50fae9dc070d6967f36 hogehoge <fugafuga> 1699594574 +0900 commit: second commit
+6cf4fd07bd3d1f982045f50fae9dc070d6967f36 bb54bb567fc99a85750561362e2dcd892f179434 hogehoge <fugafuga> 1699598971 +0900 merge another: Merge made by the 'recursive' strategy.
日志不会这么写的。
竞合 hé)
如果竞争使用,会发生什么呢?
我将在主文件和另一个文件中随意进行编辑。
説明:masterブランチでファイルを編集
~/Desktop/git/sample2 (master)
$ echo "master" > sample.txt
~/Desktop/git/sample2 (master)
$ git add .
~/Desktop/git/sample2 (master)
$ git commit -m"fourth commit"
[master 61dd6f5] fourth commit
1 file changed, 1 insertion(+), 1 deletion(-)
説明:anotherブランチでファイルを編集
~/Desktop/git/sample2 (master)
$ git checkout another
Switched to branch 'another'
~/Desktop/git/sample2 (another)
$ echo "another branch" > sample.txt
~/Desktop/git/sample2 (another)
$ git add .
~/Desktop/git/sample2 (another)
$ git commit -m"fifth commit"
[another bd61df7] fifth commit
1 file changed, 1 insertion(+), 1 deletion(-)
説明:masterブランチでマージするので移動
~/Desktop/git/sample2 (another)
$ git checkout master
Switched to branch 'master'
现在的感觉就像这样。
~/Desktop/git/sample2 (master)
$ git log --graph --oneline --all
* bd61df7 (another) fifth commit
| * 61dd6f5 (HEAD -> master) fourth commit
| * bb54bb5 Merge branch 'another'
| |\
| |/
|/|
* | cbc33d4 third commit
|/
* 6cf4fd0 second commit
* 023bd50 first commit
好吧,我来合并并竞争它们。
~/Desktop/git/sample2 (master)
$ git merge --no-ff another
Auto-merging sample.txt
CONFLICT (content): Merge conflict in sample.txt
Automatic merge failed; fix conflicts and then commit the result.
竞合了。.git文件夹怎么样了呢?
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: ORIG_HEAD
modified: index
Untracked files:
(use "git add <file>..." to include in what will be committed)
MERGE_HEAD
MERGE_MODE
MERGE_MSG
objects/7a/
no changes added to commit (use "git add" and/or "git commit -a")
我们来看一下刚刚合并时生成的文件,那些在之前没有的。让我们查看MERGE_HEAD、MERGE_MODE和MERGE_MSG的内容。
$ cat MERGE_HEAD
bd61df78647648b52c932db29880eda9f0e6b72f
$ cat MERGE_MODE
no-ff
$ cat MERGE_MSG
Merge branch 'another'
# Conflicts:
# sample.txt
MERGE_HEAD指的是将要合并的分支的最新提交(在此例中是another分支的最新提交)。
由于生成了以7a开头的对象,我们来看一下它的内容。
~/Desktop/git/sample2 (master)
$ git cat-file -p 7a67e00d6b7bee74c0f0ebdd167f22400ea80f9b
<<<<<<< HEAD
master
=======
another branch
>>>>>>> another
对吧,一旦竞合,就会生成一个diff格式的对象。
下一个更新将是ORIG_HEAD。
与先前相同,指的是合并之前的提交。
~/Desktop/git/sample2/.git (master)
$ git diff ORIG_HEAD
diff --git a/ORIG_HEAD b/ORIG_HEAD
index ed3d53b..6eb6ba5 100644
--- a/ORIG_HEAD
+++ b/ORIG_HEAD
@@ -1 +1 @@
-6cf4fd07bd3d1f982045f50fae9dc070d6967f36
+61dd6f56c96d9a3edef66cce619cf2915d76205e
如果中止(abort)操作,.git文件夹会怎么样呢?
中止(abort)后的.git文件夹状态将会是以下的样子。
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: MERGE_HEAD
deleted: MERGE_MODE
deleted: MERGE_MSG
modified: index
modified: logs/HEAD
no changes added to commit (use "git add" and/or "git commit -a")
这些文件已经消失了,而且即使合并完成也可能会消失。
在模拟前面的竞争之后,现在我们将解决竞争并进行合并。
省略了竞争的模拟。↓从竞争发生到解决竞争的过程。
~/Desktop/git/sample2 (master|MERGING)
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: sample.txt
no changes added to commit (use "git add" and/or "git commit -a")
~/Desktop/git/sample2 (master|MERGING)
$ git diff
diff --cc sample.txt
index 1f7391f,5d70384..0000000
--- a/sample.txt
+++ b/sample.txt
@@@ -1,1 -1,1 +1,5 @@@
++<<<<<<< HEAD
+master
++=======
+ another branch
++>>>>>>> another
~/Desktop/git/sample2 (master|MERGING)
$ echo "master" > sample.txt
~/Desktop/git/sample2 (master|MERGING)
$ git add .
~/Desktop/git/sample2 (master|MERGING)
$ git commit
[master 8254984] Merge branch 'another'
通过解决竞合问题,我们成功进行了合并提交。
「.git」文件夹的状态是这样的。
~/Desktop/git/sample2/.git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: COMMIT_EDITMSG
deleted: MERGE_HEAD
deleted: MERGE_MODE
deleted: MERGE_MSG
modified: index
modified: logs/HEAD
modified: logs/refs/heads/master
modified: refs/heads/master
Untracked files:
(use "git add <file>..." to include in what will be committed)
objects/82/
no changes added to commit (use "git add" and/or "git commit -a")
–与abort相同,MERGE_HEAD、MERGE_MODE、MERGE_MSG均已消失。
此外,已经生成了合并提交的对象。
~/Desktop/git/sample2 (master)
$ git cat-file -p 8254984b906f193d27c2e4f55ee75991155bcedf
tree d9fd303cfe17e779b06fe84c97c970ba22253c4b
parent 61dd6f56c96d9a3edef66cce619cf2915d76205e
parent bd61df78647648b52c932db29880eda9f0e6b72f
author hogehoge <fugafuga> 1699601812 +0900
committer hogehoge <fugafuga> 1699601812 +0900
Merge branch 'another'
以上是今天关于将“.git”管理成“Git”的演示的结束。
感谢大家一直阅读到最后。
有关「index」文件的补充说明
以下是关于一直被顽固地忽视的索引文件的补充说明。
索引文件是一个二进制文件,因此我们停止了观察,但顾名思义,索引文件是用于表示索引状态的二进制文件。它与树对象类似,具有树引用、文件名和数据块的对应关系。
将索引文件的创建和更新总结如下:
git add:初回のみindex作成、その後は更新
git commit:index更新
git branch:なにもなし
git checkout:なにもなし
git merge:index更新
当执行git add命令时,索引文件会被更新,并在git commit时创建树对象。换句话说,执行git add命令时,树对象不会被创建,只会更新索引文件。在git commit时,树对象会被创建,并且会用索引的内容进行替换。通过这样做,可以确保执行git add时工作目录和索引的内容一致,在执行git commit时,工作目录、索引和存储库的内容一致。
最后
我一边输入命令一边写文章,但途中出错并修改了部分命令结果后才发表出来,所以如果有细微错误的地方请原谅。