ここからの続きです
GitHubでリポジトリ作ったときの例のアレ
GitホスティングサービスといえばGitHubですよね。
GitHubにリポジトリを作ると、リポジトリの初期化を行うシェルが例示されますが、
いっつもコピペしてガッってやってるだけで、いまいち理解していません。
これを機に、それをひとつずつ追っていきたいと思います。
mac上でポチポチやってます。
まずはGithub上に新しいリポジトリを作ってみましょう
GitHubさんにお世話になります。
アカウントがなければ作って、Repositories -> new から適当にリポジトリを作りましょう。
今回はsandbox
というリポジトリを作りました。privateでもpublicでもどちらでもかまいません。
たったいま作られたリポジトリにアクセスしてみると、例のご指示が。
コメントはじぶんの脳内補完です。
### ファイルを作って
$ echo "# sandbox" >> README.md
### ローカルにGitリポジトリを作って
$ git init
### ファイルをステージングして
$ git add README.md
### ステージングした内容をコミットして
$ git commit -m "first commit"
### mainブランチを作ってそこに移動して
$ git branch -M main
### originというリモート追跡ブランチをURLを紐付けたうえで作成して
$ git remote add origin git@github.com:atchy/sandbox.git
### プッシュする
$ git push -u origin main
いっこずつ見ていきましょう
1. README.mdを作成する
適当なディレクトリを作成&移動してから、言われるがまま、したがいましょう。
$ mkdir ~/sandbox && cd ~/sandbox
$ echo "# sandbox" >> README.md
2. git init
する
パラメータを指定せずにgit init
すると、空のリポジトリを作成します。
$ git init
Initialized empty Git repository in /Users/atchy/sandbox/.git/
ローカルにGitリポジトリが作成されました!
作成したての構成はこうなっています。
$ ls -Al
total 8
drwxr-xr-x 9 atchy staff 288 2 7 07:47 .git
-rw-r--r-- 1 atchy staff 10 2 7 07:42 README.md
.git
ディレクトリができていますね!
つまり、Gitリポジトリの実体は、.git
ディレクトリであるということが言えます。
ただこの時点では、ローカルにGitリポジトリが作られただけで、GitHub上のリポジトリとは(まだ)何の関係もありません。
.git
ディレクトリの中をのぞいてみましょう。
$ ls -Al .git
total 24
-rw-r--r-- 1 atchy staff 23 2 7 07:42 HEAD
-rw-r--r-- 1 atchy staff 137 2 7 07:42 config
-rw-r--r-- 1 atchy staff 73 2 7 07:42 description
drwxr-xr-x 14 atchy staff 448 2 7 07:42 hooks
drwxr-xr-x 3 atchy staff 96 2 7 07:42 info
drwxr-xr-x 4 atchy staff 128 2 7 07:42 objects
drwxr-xr-x 4 atchy staff 128 2 7 07:42 refs
.git/objects
にはGitオブジェクトが配置されています。
いいかげんgitのことをちゃんと知りたいあなたへ(Gitオブジェクト編)をご参照ください。
.git/config
ファイルにはリポジトリの情報が記録されています。
のぞいてみましょう。
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
core
というセクションだけ書き込まているようです。
Gitリポジトリの重要な要素にHEAD
があります。
Pro Gitによると、HEAD
とは現在作業中のブランチに対するシンボリック参照とのこと。
HEAD
はファイルなので、中身ををのぞいてみます。
$ cat .git/HEAD
ref: refs/heads/master
HEAD
、つまり現在作業中のブランチは、refs/heads/master
とのこと。
そ、そですか、じぶんmaster
ブランチで作業中だったですか・・・
中身をのぞいてみましょう。
$ cat .git/refs/heads/master
cat: .git/refs/heads/master: No such file or directory
あり?そんなファイルないけど・・・
git init
のマニュアルを見てみます。
$ man git-init
This command creates an empty Git repository - basically a .git directory with subdirectories
for objects, refs/heads, refs/tags,and template files.
An initial HEAD file that references the HEAD of the master branch is also created.このコマンドは、空のGitリポジトリを作成します。基本的には、objects, refs/heads, refs/tags、
およびテンプレートファイルのサブディレクトリを持つ.gitディレクトリです。
masterブランチのHEADをさす初期のHEADファイルも生成します。
ふむ。
git init
することで、.git/refs/heads/master
をさすHEAD
ファイルが作られるようです。
.git/refs
にはブランチ(を指すコミットオブジェクト)やタグを指す参照(ポインタ)が記述されたファイルが格納されていきます。
ただ、現時点ではGitオブジェクトひとつも作成していないので、当然何も登録されていない、ということです。
$ tree -a .git/refs
.git/refs
├── heads
└── tags
2 directories, 0 files
たしかに何もありませんね。
2. git add
してみる
最初似作成したREADME.md
をステージングします。
$ git add README.md
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README.md
ステージングされてますね。
.git/refs
まわりに何か変化はあったでしょうか?
$ tree -a .git/refs
.git/refs
├── heads
└── tags
2 directories, 0 files
変化なし、と。
次いきます。
3. git commit
してみる
$ git commit -m "first commit"
[master (root-commit) 1c25cf6] first commit
1 file changed, 1 insertion(+)
create mode 100644 README.md
commitできました。
.git/refs
まわりを確認してみます。
$ tree -a .git/refs
.git/refs
├── heads
│ └── master
└── tags
2 directories, 1 file
お!
.git/refs/heads/master
ができてます!
つまり、
-
git commit
することによりコミットオブジェクトが作られた -
git init
したときにHEAD
、つまり作業中のブランチはmaster
ブランチを指すようになっていた - 作業中の
master
ブランチでコミットしたから、.git/refs/heads/master
が作られた
中身は
$ cat .git/refs/heads/master
34f185d743f99494056929d23e4101d0ec9ba885
$ git cat-file -p 34f185d743f99494056929d23e4101d0ec9ba885
tree 7ea9d65bc6c0b96b08b44bebce84563812dabac1
author atchy <atchy@example.com> 1612655598 +0900
committer atchy <atchy@example.com> 1612655598 +0900
first commit
たしかにさっきのコミットにより作成されたコミットオブジェクトを指しているようです。
4. git branch
してみる
引き続き、指示にしたがいます。
$ git branch -M main
何も起きてないようにも見えますが・・・
$ tree -a .git/refs
.git/refs
├── heads
│ └── main
└── tags
2 directories, 1 file
さっきまではmaster
という名前だったのがmain
になっています。
マニュアルによると、
man git-branch
With a -m or -M option, will be renamed to .
If had a corresponding reflog, it is renamed tomatch ,
and a reflog entry is created to remember the branch renaming.
If exists, -M must be used to force the rename to happen.
どうやら、
- 今のブランチ(
HEAD
が指すブランチ、すなわちmaster
ブランチ)のブランチ名を変更して、 -
main
というブランチがすでにあればそれを上書きする
という挙動のようです。
つまり、master
がmain
という名前に変更された、と。
中身をのぞいてみましょう。
$ cat .git/refs/heads/main
34f185d743f99494056929d23e4101d0ec9ba885
さっきとは同じですね。
つまり、master
という名前がmain
に変わっただけ、ということですね。
今後、GitHubさんとしては、デフォルトブランチ名をmain
とするようです
5. git remote add
してみる
ここまではローカルリポジトリをコネコネしてるだけでしたが、
いよいよリモートと何やら何かをするような雰囲気です。
だってgit remote
とか言うてますから!
その前に現状を確認しておきましょう。
git remote show
反応ありません。
.git/config
の内容は、
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
git init
後と変わりないですね。
では、
$ git remote add origin git@github.com:atchy/sandbox.git
しーん。
いったいなにが起こったのでしょうか・・・
$ git remote show
origin
お!
地味ながら、変化がありましたね。
origin
というリモートが追加されたぽいです
.git/config
ファイルを見てみます
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@github.com:atchy/sandbox.git
fetch = +refs/heads/*:refs/remotes/origin/*
remote
セクションが追加されてますね!
git remote add
はリモート的な何かを追加するコマンドのようです。
順をおって見ていきましょう。
まずはgit remote
コマンドを見直してみましょう。
$ git remote add origin git@github.com:atchy/sandbox.git
という状況から類推するに、
-
origin
という名前のリモートが追加された -
url
プロパティはgit@github.com:atchy/sandbox.git
-
fetch
プロパティは+refs/heads/*:refs/remotes/origin/*
url
プロパティはなんとなく分かりますよね。
たぶん、git
というgithub.com
サーバのatchy/sandbbox
ディレクトリを指してるかと思います。
scp
コマンドと似てますね。
で、問題はfetch
プロパティの方ですが・・・
このあたりを考え出すと、もうひとつ記事が書けそうなので、別の機会にします。
とりあえず、リモートリポジトリが登録された、とだけ考えましょう。
リモートリポジトリが追加された、ということは、もうそこへpush
することができるんでしょうか?
$ git push
fatal: The current branch main has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin main
怒られましたね・・・
現在のブランチにはupstreamブランチがありません。
現在のブランチをプッシュして、upstreamをリモートとして設定するには、
git push --set-upstream origin main
を実行してね
と。
むぅぅ、upstream
とはなんぞ?
このあたりを考え出すと(ry
上流ブランチについてはまた次の機会に・・・
git remote add
によって、リモートとしてGitHub上のリポジトリが登録されましたが、
現在のブランチ(master
ブランチ)を、リモート上のどのブランチにプッシュするか、
が分からない(設定されていない)ため、現状ではプッシュが失敗します。
まあ、言われてみればそうですよね・・・
その問題を解決するために最後のステップに進みます。
6. git push
してみる
さあいよいよプッシュします!
$ git push -u origin main
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 221 bytes | 221.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:atchy/sandbox.git
* [new branch] main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.
成功したようですね。
GitHub上も表示に変化がありました(ファイルいっこしかないですがw)
コマンドの意味をみてみましょう。
まずはマニュアルを参照してみます。
$ man git-push
-u
オプションは
-u, --set-upstream
For every branch that is up to date or successfully pushed, add upstream (tracking) reference
さっき怒られたときに付いてたオプションと同じですね。
その意味は
upstream (tracking) reference
を追加する、と。
さっきはupstream
ブランチが設定されていなかったので、プッシュに失敗しましたが、
今は設定されているのでしょうか?
.git/config
をのぞくと、
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@github-atchy:atchy/sandbox.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
branch
セクションが追加されています。
さらに、.git/refs
まわりを見てみると、
$ tree -a .git/refs
.git/refs
├── heads
│ └── main
├── remotes
│ └── origin
│ └── main
└── tags
4 directories, 2 files
.git/refs/remotes/origin/main
ができてますね。
まとめると、
-
main
ブランチのリモートはorigin
とする - リモートの参照として
.git/refs/origin/main
を配置する
と。
merge
プロパティについては、いまはそっとしておきます・・・
おわりに
知れば知るほどgitの奥深さと、じぶんがぜっんぜんgitのことを
理解していなかったのかが、身に沁みてわかります。
これからも精進していきます。
次回予告
とはいえ、リモートの存在意義とか、上流ブランチとか、リモート追跡ブランチとか、
腑に落ちない点がまだまだありますので、そのあたりを紐解いていきたいでっす