Version Control with Git ch12 Remote Repositories (1/x)

Git勉強メモ

出典: 


Remote Repositories

  • clone

    • これのおかげで地理的に離れた人と協業できたりする
  • こういうときリポジトリが分かれているとうれしい:

    • 開発者が別々に作業する
    • 開発者がネットワーク上遠く離れている
    • プロジェクトが著しく分岐する

      • ブランチだと煩雑になりすぎる
  • remote

    • ファイルシステムかネットワークで別リポジトリを参照する
    • 長いGit URLのショートハンド
    • いくつでも作れる

      • 【所感】herokuのデプロイのためにoriginと別に作ったりするね
    • リモート追跡ブランチでデータ追跡する

Repository Concepts

Bare and Development Repositories

  • gitのリポジトリには2種類ある
  • development (nonbare)

    • 普段遣いのやつ
    • 11章までのは全部これ
  • bare

    • 作業ディレクトリなし
    • 「チェックアウトされたブランチ」なし
    • .git/だけあるイメージ
    • bare repository上でコミットを作ることはない
    • 協働開発内容を集約する役割
    • git cloneするときに --bareオプションをつけるとbare repositoryになる

      • 【所感】GitHub上でforkするとき、裏ではgit clone --bareしているのかな?
    • 開発用でないゆえのデフォルト挙動

      • reflogなし
      • リモート追跡ブランチなし
  • 公開リポジトリはbareであるべき

Repsitory Clones

  • clone元のrefs/heads/* が、clone先でrefs/remotes/にコピーされリモート追跡ブランチとなる
  • 原本のリポジトリにしか関係のない情報はコピーされない

    • リモート追跡ブランチ
    • コンフィグファイル
    • reflog
    • stash
  • git clone <src>[ <dst>]

    • リモート追跡ブランチは refs/remots/origin/*
    • コンフィグで変更可能
[remote "origin"]
	url = git@github.com:wand2016/subtree_practice_application.git
	fetch = +refs/heads/*:refs/remotes/origin/*

Remotes

  • originとかのこと
  • remoteといいつつ、物理的に離れている必要はまったくない
  • remoteの役目

    • 長いパスまたはURLのショートハンド
    • リモート追跡ブランチ名のプレフィックス
git ls-remote [remote]
  • 指定のremoteのrefを表示
git ls-remote
b4dcf82b6aa37a7667d87ea9e067432041de6f34	HEAD
4540d972c41fbc7785228542bc557492214f5644	refs/heads/issue2/parameterize-nginx-conf
b4dcf82b6aa37a7667d87ea9e067432041de6f34	refs/heads/master
4540d972c41fbc7785228542bc557492214f5644	refs/pull/4/head

Tracking Branches

  • ブランチの分類

    • ローカルブランチ

      • リモート追跡ブランチ

        • origin/feature/hogeとか
        • フルネームは refs/remotes/origin/feature/hoge
        • read only
      • ローカル追跡ブランチ

        • feature/hogeとか
        • ローカル開発差分とリモート追跡ブランチの差分を集約
      • トピックブランチ/開発ブランチ

        • refs/headsに入っているもののうち、ローカル追跡ブランチ以外のもの
    • リモートブランチ

      • リモートリポジトリのブランチ

Referencing Other Repositories

.git/config

[remote "origin"]
	url = git@github.com:wand2016/subtree_practice_application.git
	fetch = +refs/heads/*:refs/remotes/origin/*
  • 参照するリモートリポジトリのありか
  • refspec

Refererring to Remote Repositories

  • いろいろなプロトコルが使える

    • ファイルシステム

      • 物理/論理(NFSとか)
    • Gitネイティブプロトコル

      • 効率が良い
    • Gitネイティブプロトコル + SSHトンネリング
    • HTTP/HTTPS

      • git v1.6.6から高効率になった
      • GitHubなどが推している
    • rsync

      • 非推奨

        • 使うにしても最初のcloneだけにしとけ
        • さもないとローカルの変更が失われうる

The refspec

  • 名前が衝突しがちなので、フルネームで記述する
fetch = [+]source:destination
  • git fetch/git pushで使用
[remote "origin"]
	url = git@github.com:wand2016/sub_practice.git
	fetch = +refs/heads/*:refs/remotes/origin/*
  • remote名とリモート追跡ブランチのプレフィックスを揃える必要はないが、普通はそうする
  • ref一覧
  • ローカルのref
git show-ref
4540d972c41fbc7785228542bc557492214f5644 refs/heads/issue2/parameterize-nginx-conf
83f7e40e53b669252a8a15a16769b9859355cd11 refs/heads/master
4540d972c41fbc7785228542bc557492214f5644 refs/remotes/origin/issue2/parameterize-nginx-conf
b4dcf82b6aa37a7667d87ea9e067432041de6f34 refs/remotes/origin/master
  • リモートのref
git ls-remote origin
b4dcf82b6aa37a7667d87ea9e067432041de6f34	HEAD
4540d972c41fbc7785228542bc557492214f5644	refs/heads/issue2/parameterize-nginx-conf
b4dcf82b6aa37a7667d87ea9e067432041de6f34	refs/heads/master
4540d972c41fbc7785228542bc557492214f5644	refs/pull/4/head
b58489117ef8ed87afa1ebdb4d136c11b304f9a6	refs/pull/5/head
ecb6745401f51959f5f98707e21772116c6ab534	refs/pull/5/merge
  • git push, git pullにはremoteとrefspecを指定する
git push[ remote[ refspec]]
  • remote省略時は、originが指定されたものとして動作する
  • refspec省略時は、リモートにすでにあるトピックブランチと同名のローカルブランチがpushされる

    • 新しくpushする場合は省略不可能
  • 下記2つのコマンドは全く等価:
git push remote branch
git push remote branch:refs/heads/branch

Example Using Remote Repositories

  • 1つのリポジトリを正式なものとする

    • 技術的にはどのリポジトリも特別ではない
    • ので、運用的な話
    • 「正式な」リポジトリだけ冗長化されたストレージに置いたりする

Creating an Authoritative Repository

  • たまたま手元にあったRay.Aopでbareリポジトリを作ってみる
git clone --bare Ray.Aop Ray.Aop.git
  • .gitで終えるのは慣習・ベストプラクティス
  • 元のリポジトリ
ls -aF Ray.Aop
ls -aF Ray.Aop/.git
./     .gitignore	 .travis.yml   README.md	      demo/	  phpstan.neon	    tests/
../    .php_cs.dist	 LICENSE       annotation_loader.php  phpcs.xml*  phpunit.xml.dist
.git/  .scrutinizer.yml  README.ja.md  composer.json	      phpmd.xml   src/
./  ../  HEAD  branches/  config  description  hooks/  index  info/  logs/  objects/  packed-refs  refs/
  • bareリポジトリ
ls -aF Ray.Aop.git/
  • bareリポジトリには作業ディレクトリが存在しない
  • ので、cloneで生成したディレクトリ自体が.git/のようになる
  • 作業用のindexとlogs/もない
./  ../  HEAD  branches/  config  description  hooks/  info/  objects/	packed-refs  refs/
  • デフォルトでrefspecがない
cat Ray.Aop.git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = true
[remote "origin"]
	url = /home/wand/repos/Ray.Aop
  • 【補】書籍上は、デフォルトのremote originも生成しないことになっている

    • git v2.17.1では生成するようだ

Make Your Own Origin Remote

  • git clone --bareされたリポジトリは、「正式な」リポジトリのことを知る由もない
  • ので設定してやる必要がある
cat Ray.Aop/.git/config
  • GitHubからpullしてきたのでそのoriginが設定されている
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = https://github.com/ray-di/Ray.Aop.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "2.x"]
	remote = origin
	merge = refs/heads/2.x
  • 新たに、先程作ったRay.Aop.gitをリモートに加えたい
cd Ray.Aop
git remote
origin
git remote add origin2 /home/wand/repos/Ray.Aop.git
  • remote追加確認
git remote
origin
origin2
cat .git/config
  [core]
      repositoryformatversion = 0
      filemode = true
      bare = false
      logallrefupdates = true
  [remote "origin"]
      url = https://github.com/ray-di/Ray.Aop.git
      fetch = +refs/heads/*:refs/remotes/origin/*
  [branch "2.x"]
      remote = origin
      merge = refs/heads/2.x
+ [remote "origin2"]
+     url = /home/wand/repos/Ray.Aop.git
+     fetch = +refs/heads/*:refs/remotes/origin2/*
  • リモートのトピックブランチを取り込む
branch -a
* 2.x
  remotes/origin/1.x
  remotes/origin/2.x
  remotes/origin/HEAD -> origin/2.x
git remote update
Fetching origin
remote: Enumerating objects: 66, done.        
remote: Counting objects: 100% (66/66), done.        
remote: Compressing objects: 100% (6/6), done.        
remote: Total 103 (delta 60), reused 66 (delta 60), pack-reused 37        
Receiving objects: 100% (103/103), 15.91 KiB | 15.91 MiB/s, done.
Resolving deltas: 100% (70/70), completed with 19 local objects.
From https://github.com/ray-di/Ray.Aop
   10800bd..61d327f  2.x        -> origin/2.x
 * [new tag]         2.8.8      -> 2.8.8
Fetching origin2
From /home/wand/repos/Ray.Aop
 * [new branch]      2.x        -> origin2/2.x
git branch -a
  * 2.x
    remotes/origin/1.x
    remotes/origin/2.x
    remotes/origin/HEAD -> origin/2.x
+   remotes/origin2/2.x

英語

  • vernacular

    • お国言葉の

      • その技術特有の言葉、という意味合い
  • autonomous

    • 自立している、独立している

      • cloneを触っても原本に影響はないということ
  • amass 蓄積する
  • pertinent

    • 関連のある
  • misnomer

    • 不適切な名前