Gitのリモートリポジトリとローカルリポジトリとの連携方法を記載する。
GitリモートリポジトリはGCPのCloud Source Repositoriesを例に説明するが、大部分の記載はGitHubなど他リモートリポジトリでも利用可能な手順となる。
本手順の前提としては、既にGCPのCloud Source RepositoriesやGitHubなどで、空のプライベートのリモートリポジトリを作成済みの状態を想定した記載となる。
リモートリポジトリが未作成の場合は以下を参照に作成するか、GitHub等にて準備を実施する。
また、本手順はリポジトリ等Gitの構造や仕組みの詳細を踏まえた手順となる。
構造や仕組みについては以下ナレッジにまとめている。
リモートリポジトリ接続用SSH設定
プライベートのリモートリポジトリに接続するには、ssh接続が必要となる。そのためにローカル環境にて以下を設定。
- リモートリポジトリ接続用のSSH秘密鍵 (id_rsa) を任意のディレクトリに設置。
- 下記例では”~/xxxxxx/”配下に設置。
~/xxxxxx/id_rsa
秘密鍵は権限が正しくないとssh接続は不可となるため、権限を変更する。
$ sudo chmod 600 ~/xxxxxx/id_rsa
- emacsやvi等テキストエディタを利用し、ssh設定を行う。
- “~/.ssh/config”ファイルに下記を設定。ファイルがない場合は作成。
- “Host”にて任意の接続名を設定。下記では”host01″と設定。
- “Hostname”にて接続先のFQDNやIPを設定。下記はGCPのCloud Source Repositoriesの接続先である”source.developers.google.com”を設定。
- “IdentityFile”にて使用するSSH秘密鍵の場所を設定。前述の通り鍵を設置した”~/xxxxxx/id_rsa”を設定。
- “port”にてリモートリポジトリへのSSH接続用ポートを設定。下記はGCPのCloud Source Repositoriesの接続先ポートとして”2022″を設定。
$ vi ~/.ssh/config
Host host01
Hostname source.developers.google.com
IdentityFile ~/xxxxxx/id_rsa
port 2022
リモートリポジトリをローカルリポジトリへ複製
- もし、そもそもgit自体がローカル環境にインストールされていなければインストールする。
- 下記はUbuntu等でのaptを利用したコマンドとなる。CentOS等の場合はyumを利用する。
$ sudo apt-get install git
- ワークツリー (gitで管理したいファイルを配置するディレクトリ) を設置したいディレクトリに移動。
- 下記例では”git_repo”ディレクリ配下
$ cd ~/git_repo
- “git clone”コマンドにてリモートリポジトリをローカルリポジトリへ複製。
- ssh接続経由にて”git clone”コマンドを実施。
- [User]にはssh接続のユーザを記載。下記例では”user01″。
- [SSH設定のHost]には前述のssh設定で設定したHostを記載。下記例では”host01″。
- [リポジトリの絶対パス]は、GitHubやCloud Source RepositoriesのWebポータル上のリポジトリページから、SSHを利用したクローン用のコマンドや接続情報として確認できる。下記例では”/p/nagarelab-pj01/r/pj01_repo01″。
- コマンド実行後SSH接続の[パスフレーズ]入力が求められるので、入力する。
$ git clone ssh://[User]@[SSH設定のHost][リポジトリの絶対パス]
$ git clone ssh://user01@host01/p/nagarelab-pj01/r/pj01_repo01
Cloning into 'pj01_repo01'...
Enter passphrase for key '/home/xxx/xxxxxx/id_rsa': [パスフレーズ]
warning: You appear to have cloned an empty repository.
ここまでSSH設定を利用した”git clone”を記載したが、SSHの秘密鍵を下記のデフォルトの設置場所に設置することが可能であれば、前述のSSH設定をせずにコマンドのみでの”git clone”も可能となる。以下に手順を示す。
~/.ssh/id_rsa
- “git clone”コマンドにてリモートリポジトリをローカルリポジトリへ複製。
- ssh接続経由にて”git clone”コマンドを実施。
- [User]にはssh接続のユーザを記載。下記例では”user01″。
- [FQDN]には接続リポジトリのURLもしくはIPアドレスを記載。下記例では”source.developers.google.com”。
- [port]には接続先のポート番号を記載。下記例では2022。
- [リポジトリの絶対パス]は、GitHubやCloud Source RepositoriesのWebポータル上のリポジトリページから、SSHを利用したクローン用のコマンドや接続情報として確認できる。下記例では”/p/pj01/r/pj01_repo01″。
- コマンド実行後SSH接続の[パスフレーズ]入力が求められるので、入力する。
$ git clone ssh://[User]@[FQDN]:[port][リポジトリの絶対パス]
$ git clone ssh://user01@source.developers.google.com:2022/p/pj01/r/pj01_repo01
Cloning into 'pj01_repo01'...
Enter passphrase for key '/home/xxx/.ssh/id_rsa': [パスフレーズ]
warning: You appear to have cloned an empty repository.
ワークツリーからインデックスに変更内容を登録
- ここからの手順は基本的に先ほど複製したリポジトリのワークツリー配下で実施するため、ディレクトを移動する。
- 特にワークツリーのディレクトリ名を指定していない場合は、ディレクトリ名はリポジトリ名となる。
- 本例では”pj01_repo01″リポジトリを複製しているので、ディレクトリ”pj01_repo01″に移動する。
$ cd pj01_repo01
- ワークツリー内に更新のテスト用として新規ファイルを作成する。
$ touch test.txt
- ワークツリーからインデックス (ローカルリポジトリにコミットする前に更新内容を一時保存する場所) に変更内容を登録。
- 下記例ではワークツリー配下全ての変更を対象とするため”*”を指定。一部のみを更新したい場合は指定する。
$ git add *
- gitにて管理しているファイル等の現在の状態を確認する。ワークツリー内のみ更新されたファイルや、そこからインデックス登録されたファイル、さらにリポジトリにコミットまでしたファイル、といった状態が確認できる。
- 下記例では、”test.txt”が、インデックスには登録されているが、リポジトリには登録されていない状態が確認できる。
$ git status
ブランチ master
No commits yet
コミット予定の変更点:
(use "git rm --cached <file>..." to unstage)
new file: test.txt
インデックスからローカルリポジトリへコミット
- インデックスの内容を利用して、実際に”git commitコマンドにて”ローカルリポジトリにコミットし、更新する。
- -mオプションにてコミット時のメッセージを指定し、後でコミット内容を把握できるようメッセージを残す。下記例では”first commit”と指定している。
$ git commit -m "first commit"
[master (root-commit) a5559fa] first commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test.txt
- gitにて管理しているファイル等の現在の状態を確認する。
- 下記例では、コミットされていないファイルがワーキングツリー内になく全てコミットされていることが確認できる。
$ git status
ブランチ master
Your branch is based on 'origin/master', but the upstream is gone.
(use "git branch --unset-upstream" to fixup)
nothing to commit, working tree clean
ローカルリポジトリからリモートリポジトリへアップロード
- 以下のコマンドにてはじめに現リポジトリのコミット時に利用されるユーザを設定する。
- 前述の通り、現在は”pj01_repo01″リポジトリを対象に操作しているので、本設定の対象は”pj01_repo01″リポジトリである。
- 以下の例ではユーザ名を”user-a”、メールアドレスを”user-a@xxxx.nagarelab.com”に設定している。
- 本”local”設定を実施しない場合は、ローカル環境上システム全体のリポジトリを対象とした”system”設定や、現利用ユーザの全リポジトリを対象とした”global”l設定が優先される。これらの設定は”git config –global”といったコマンドにて設定可能となる。
$ git config --local user.name "user-a"
$ git config --local user.email "user-a@xxxx.nagarelab.com"
- 設定した内容が反映されているか確認する。
- 特定リポジトリのみに対する本local設定は、ワークツリー内にある”./.git/config”に記載されている。
- 下記コマンド結果から”[user]”が適切に設定されていることが確認できる。
$ cat ./.git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = ssh://user01@source.developers.google.com:2022/p/pj01/r/pj01_repo01
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[user]
name = user-a
email = user-a@xxxx.nagarelab.com
- “git push”にて、ローカルリポジトリからリモートリポジトリへ内容をアップロード。
- “-u”オプションにてpush先のリモートブランチを上流ブランチに設定し、次回以降のgit pushやgit pull利用時の連携先が本ブランチとなる。
- originはデフォルトのリポジトリ名を表しており、今回の例では、前述”git clone”コマンドで設定したCloud Source Repositories上のリポジトリを指している。
- masterはブランチ名を表しており、今回の例ではリポジトリのデフォルトで作成されるmasterブランチを指している。masterはローカル、リモート双方での同名のブランチ名を表している。ローカルブランチとリモートブランチが異なる名前のものにアップロードしたい場合は、単一のブランチ名ではなく、<LOCALBRANCHNAME>:<REMOTEBRANCHNAME>といったように記載する必要がある。
- “-u”オプションにてpush先のリモートブランチを上流ブランチに設定し、次回以降のgit pushやgit pull利用時の連携先が本ブランチとなる。
$ git push -u origin master
Warning: Permanently added the ECDSA host key for IP address '[XX.XXX.XXX.XX]:2022' to the list of known hosts.
Enter passphrase for key '/home/xxx/xxxxxx/id_rsa':
Counting objects: 3, done.
Writing objects: 100% (3/3), 205 bytes | 205.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://user01@source.developers.google.com:2022/p/pj01/r/pj01_repo01
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
この時点でリモートリポジトリ側を確認すると、更新情報がアップデートされていることが確認できる。更新者は前述の設定したユーザとなっている。
以降は、ワークツリー上を更新したら、”ワークツリーからインデックスに変更内容を登録”から、ここまでを繰り替えし実施することで、継続してリモートリポジトリを更新可能となる。
リモートリポジトリからローカルリポジトリへ更新内容をダウンロードし更新
前述までで、リモートリポジトリを複製し一つのローカルリポジトリを作成し、そのローカルリポジトリおよびリモートリポジトリ双方の更新する方法を記載した。
しかし、Gitを利用する場合複数人で開発することが想定されるため、他の人が更新したリモートリポジトリの内容を異なる環境のローカルリポジトリに更新するシーンも想定される。
そのため、リモートリポジトリからローカルリポジトリへ更新内容をダウンロードし、更新する方法も記載する。
以下は異なるローカルリポジトリからリモートリポジトリが更新された後の操作となる。
- ワークツリーのディレクトリに移動。
- 下記例では”git_repo”ディレクリ配下
$ cd ~/git_repo/pj01_repo01
- ローカルのブランチをmasterブランチを切り替え。
- 特に他のブランチ等に切り替えていなければ本コマンドは不要。
- もし切り替え前のブランチにて変更を加えており、インデックスやワークツリーに差分がある場合は、他ブランチに切り替えると、その変更内容は、切り替え先のブランチに移動する。そのため、必要に応じて変更内容をコミットや”git stash”にて退避する。
$ git checkout master
- “git pull”にて、リモートリポジトリからローカルリポジトリへ更新内容をダウンロードし、更新。
- “origin master”はpull先のリモートブランチを表している。
- originはデフォルトのリポジトリ名を表しており、今回の例では、前述”git clone”コマンドで設定したCloud Source Repositories上のリポジトリを指している。
- masterはブランチ名を表しており、今回の例ではリポジトリのデフォルトで作成されるmasterブランチを指している。
- “origin master”はpull先のリモートブランチを表している。
$ git pull origin master
上記コマンドでも問題ないが上記コマンドは下記2コマンドの複合コマンドであるため、下記をそれぞれ順番に実施しても良い。
- “git fetch”にて、リモートリポジトリのブランチからローカルのリモート追跡ブランチに更新内容をダウンロードする。
- 以下の”origin master”はfetch先のリモートブランチを表している。
- originはデフォルトのリポジトリ名を表しており、今回の例では、前述”git clone”コマンドで設定したCloud Source Repositories上のリポジトリを指している。
- masterはブランチ名を表しており、今回の例ではリポジトリのデフォルトで作成されるmasterブランチを指している。
- 本コマンドにて上記のブランチからローカルリポジトリの”origin/master”というリモート追跡ブランチへ更新内容をダウンロードする。この時点ではまだ、ローカルリポジトリのmasterブランチおよびワークツリーは更新されていない。
- 以下の”origin master”はfetch先のリモートブランチを表している。
$ git fetch origin master
- ローカルのブランチをmasterブランチを切り替え。
- 特に他のブランチ等に切り替えていなければ本コマンドは不要。
$ git checkout master
- “git merge”にて、リモート追跡ブランチを現在のブランチにマージする。
- 以下のorigin/masterはマージするリモート追跡ブランチを表している
- 本コマンドにて、ローカルリポジトリのmasterブランチおよびワークツリーが更新される。
$ git merge origin/master