プログラマ・アゲイン blog

還暦を過ぎたけどプログラマ復帰を目指してブログ始めました

GitとGithubを連携してソースのバージョン管理を行う方法

バージョン管理の必要性

JavaScriptCSSで、ソースコード貼り付け用ボックスの作成を行いましたが、その時にソースのバージョン管理の必要性を感じました。

少しづつ開発していったので、はてなブログのデザインに登録したJavaScriptCSSの日別のバックアップ・ファイルを、手で作成していました。また、そこから切り出してテストもしていたので、テスト結果を元ソースに反映するのも手で行っていました。特にテストで、変更してはテストし、戻しては変更してテストするを繰り返していると、どこを変更したのか管理するのが大変でした。

やはり、これらの事はバージョン管理のソフトウェアで行うべきと思い、Gitを導入して使ってみることにしました。Gitの導入から使用までと、Githubとの連携を以下にまとめます。

 

参考にしたページ

「Gitとは」から導入方法、使用法方法までを、次のWebを参考にさせていただきました。

backlog.com

特にインストール方法については、次のページを参考にさせていただきました。

eng-entrance.com

2台のPC(Windows)を使用しているので、Githubも使用します。GitとGithubの連携については、以下のページを参考にさせていただきました。

employment.en-japan.com

 

Gitの導入

まず、Gitを導入します。

Gitのインストール

Gitのダウンロードから、インストールまでは、以下の流れでした。

ダウンロード

https://git-scm.com/ からダウンロードします。画面右下の「Download 2.22.0 for Windows」をクリックします。

f:id:hanasakag:20190702171431p:plain

 

早速ダウンロードの確認ポップアップが出てくるので、「ファイルを保存」をクリックします。

f:id:hanasakag:20190702171459p:plain

インストーラの実行

ユーザーの「ダウンロード」フォルダーに次のファイルがダウンロードされています。ダブルクリックして、実行します。

f:id:hanasakag:20190702171517p:plain

 

ここから、導入画面が続きます。

「Next」をクリックします。

f:id:hanasakag:20190702171531p:plain

 

導入ディレクトリーを変える必要がなければ、デフォルトのまま「Next」をクリックします。

f:id:hanasakag:20190702171550p:plain

 

チェック・ボックスにチェックして導入するコンポーネントを選択し、「Next」をクリックします。

デフォルトで、「Windows Explorer integration」と「Git LFS(Large File Support」はチェックが付いていますが、別のPCにインストールした時にはついていませんでした。意味は、次のような感じなので、デフォルトのままでいきます。

  • Windows Explore integration:エクスプローラーで、フォルダーの右クリックメニューのリストに「Git Bash here」「Git GUI Here」を追加します。
  • Git LFS (Large File System):Git LFS(大きなサイズのファイル・システム)の導入を行います。LFSは、Gitで動画やグラフィックス用の大きなファイルを扱うための拡張機能なので当面使用することはないと思いますが、導入していてもLFSを初期化しなければ問題なさそうです。

f:id:hanasakag:20190702171639p:plain

 

スタート・メニューのフォルダーを変える必要がなければ、デフォルトのまま「Next」をクリックします。

f:id:hanasakag:20190702171655p:plain

 

Gitのコミット時のコメントを記入する時などに呼び出される、デフォルトのエディターを選択します。

プル・ダウン・メニューから、VS Codeを選択しました。通常使っているエディターを選択して、「Next」をクリックします。

f:id:hanasakag:20190702171729p:plain

 

Recommendedの内容で問題無ければ、デフォルトのまま「Next」をクリックします。

f:id:hanasakag:20190702171754p:plain

 

HTTPS接続の設定なので、デフォルトのまま「Next」をクリックします。

f:id:hanasakag:20190702171811p:plain

 

Windows PCのみの使用なので、テキスト・ファイルのチェックアウトやコミットを行う時にGitで行末の変換を行わない「Checkout as-is, commit as-is」を選択して、「Next」をクリックします。

f:id:hanasakag:20190702171832p:plain

 

Git Bashと共に使うターミナル・エミュレータを変える必要がなければ、デフォルトのまま「Next」をクリックします。

f:id:hanasakag:20190702171857p:plain

 

拡張オプションとして「Enable file system caching」と「Enable Git Credential Manager」を選択して、「Next」をクリックします。

f:id:hanasakag:20190702171914p:plain

 

実験的なオプションを使用しないのであれば、デフォルトのまま「Install」をクリックします。

f:id:hanasakag:20190702171932p:plain

 

以上でインストールが始まります。

インストールが終了すると、次のGit Setupウィザード完了画面が出るので、デフォルトのまま「finish」をクリックします。ただし、リリース・ノートを見る必要がなければ、チェックを外しておきます。

f:id:hanasakag:20190702171955p:plain

 

Gitの初期設定

Gitの初期設定は、Git Bashのコマンド・ラインを使用して行います。Git Bashは、スタート→Gitフォルダー→Git Bashと進めば起動されます。

バージョンの確認

正しくGitが導入されているか、バージョンの確認「git --version」で行います。

「git version 2.22.0.windows.1」が表示されれば、OKです。

f:id:hanasakag:20190704110015p:plain


必要最小限の初期設定

Gitの初期設定として、「git config --global」で最低限以下の項目を設定します。

  • ユーザー名 --- user.name
  • メール・アドレス --- user.email

それぞれ設定された内容を確かめるためには、設定値を入れずにコマンドを打つか、「git config --list」で行います。

f:id:hanasakag:20190712152940p:plain



追加の設定

その他の設定として、同じく「git config --global」で以下の項目を設定します。

  • color.ui auto : gitの出力をカラーリングする
  • core.quotepath off : 日本語のファイル名を文字化けさせない

f:id:hanasakag:20190704134215p:plain

その他にも有用な設定があるようですので、以下のページも参考にして今後設定します。

qiita.com

 

結果として、ユーザー・ディレクトリーに「.gitconfig」ファイルが作成されます。中身は、導入時に設定したエディターや初期設定した内容が入っています。

[core]
    editor = \"C:\\Program Files\\Microsoft VS Code\\Code.exe\" --wait
    quotepath = off
[user]
    name = ユーザー名
    email = e-mailアドレス
[color]
    ui = auto

以上で、取り敢えずの初期設定は終了です。

 

Gitの使用

実際に、Gitを使用してみます。

Git単体での使用

単体での使用は、Git Bashで行います。言葉のそれぞれの意味については参照のWebページを見ることにして、実際にやってみた結果をまとめます。

リポジトリの作成

先ずは、履歴を管理するGitのリポジトリを作成します。

Gitの管理対象はフォルダーなので、対象のフォルダーを作成して、cdコマンドで移動します。そこで「git init」で、そのフォルダーの中にリポジトリである「.git」フォルダーを作成します。

$ cd tutorial
AzureAD+xxxxxxxx@LAPTOP-HBS14TBN MINGW64 /c/data/git/tutorial
$ git init
Initialized empty Git repository in C:/DATA/Git/tutorial/.git/
インデックスに登録

サンプルのソースを作成して、上記で作成したGitの管理対象のフォルダー「tutorial」に保存します。「sample.txt」というファイルを作成します。

「git staus」でワークツリーとインデックスの状態を確認します。履歴の追跡対象になっていないファイルとして「sample.txt」があるので、これを「git add」でインデックスに登録します。特に何もメッセージは出てきませんが、「git status」で確認すると、インデックスに「sample.txt」が追加され、コミットの準備が整っていることが判ります。

$ git status
On branch master
No commits yet
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        sample.txt
nothing added to commit but untracked files present (use "git add" to track)

$ git add sample.txt

$ git status
On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   sample.txt
コミット

「git commit」でコミットします。

次の例では、-mオプションを指定して「first commit」というコメントを付けています。-mオプションでは、エディタを開くことなく、素早くコミットを作成することができます。「git status」で確認すると、コミットされていない変更はなくなっています。

$ git commit -m "first commit"
[master (root-commit) 4c0e6a2] first commit
 1 file changed, 1 insertion(+)
 create mode 100644 sample.txt

$ git status
On branch master
nothing to commit, working tree clean

commitコマンドについては、以下のページに使い方がまとめられています。

www-creators.com

 

VS Codeでの使用

Gitを単体で使用するのでも良いのですが、VS CodeからGitに連携することができるので、それも使用してみました。コマンドをいちいち入れる必要がないので、こちらの方が使いよさそうです。

リポジトリの認識

先ず、VS CodeにGitのリポジトリを認識させます。

VS Codeエクスプローラーで、Gitの管理対象になっているフォルダー(Gitのリポジトリがあるフォルダー)を開きます。すると、自動的にVS CodeがGitリポジトリを認識してくれます。

ファイルの変更

既にGitにコミットされているファイルを、更新してみます。更新して保存すると、アクティビティバーのソース管理のアイコンに①の数字が表示され、「HATENABLOG」フォルダーの横のアイコンにカーソルを合わせると、変更済みのものが表示されます。

f:id:hanasakag:20190703175723p:plain

インデックスに登録(ステージング)

変更されたものを、Gitのインデックスに登録します。ソース管理のアイコンをクリックすると、変更対象のファイルが表示されます。そのファイルの横に、「変更をステージ」と表示されるアイコンがあるので、クリックします。

余談ですが、「インデックスに登録」という言い方は、他には「ファイルステージにアップ」とか、いろいろあるようです。個人的には、「ステージング」という言い方が馴染みやすいです。

f:id:hanasakag:20190703175743p:plain

コミット

インデックスに登録されると、ステージング済みになります。ソース管理: GITの横の「コミット」が表示されるアイコンをクリックして、コミットします。

f:id:hanasakag:20190703175801p:plain

 

GitのエディターとしてVS Codeを登録しているので、そのままコミット・メッセージを入力する欄が表示されます。変更内容がわかるようなコメントを記入して、「Enter」します。これでコミットされます。

f:id:hanasakag:20190703175826p:plain

 

GitLensの使用

Gitで管理しているソースの差分を確認したりするのに、GitLensが良いと書かれていました。そこで、GitLensを導入して、使用してみました。

ytnobody.net

GitLensを導入すると、アクティビティバーにソース管理のアイコンを上下逆さにして〇で囲ったようなアイコンが追加されます。カーソルを持っていくと、「GitLens」と表示されます。

f:id:hanasakag:20190703175842p:plain

 

「GitLens」のアイコンをクリックすると、「REPOSITORIES」や「FILE HISTRY」などが表示されます。

f:id:hanasakag:20190703175903p:plain

 

「FILE HISTORY」で該当のコミット・コメントをクリックすると、新旧のファイルの比較が表示されます。色も付くので、非常に見やすいと思います。

f:id:hanasakag:20190703175930p:plain

 

Githubとの連携

2台のPCを使用しているので、2台のPCでの開発の同期をとるために、Githubを使用することにしました。GitとGithubは別物なので、覚えることが多くなってしまうのですが、複数で情報を管理するためにはGithubは必須だと思います。

SSHキー(鍵)

Githubリポジトリ(リモートのリポジトリ)とやり取りする際、SSHHTTPSのどちらかを使用することができますが、HTTPSだと認証はGitHubのユーザー名、パスワードになるので、取り敢えずSSHの方がよさそうです。

まず、SSHのキーとして、公開鍵と秘密鍵を作成します。公開鍵と秘密鍵の関係は、相手に公開鍵を渡して、自分が持っている秘密鍵と照合することで、相手の認証と通信の暗号化を行う、といった感じです。

そこで、GithubSSHでアクセスするために、公開鍵とペアになる秘密鍵を作成します。公開鍵は、Github上に登録することになります。

SSHキー(鍵)の作成

SSHキー(鍵)の作成は、Git bashで行います。

Git Bashを立ち上げて、以下のssh-keygenコマンドを入力します。「-C」のオプションで鍵にコメントを付加できるので、何の鍵かわかるように付けています。

コマンドを入力すると、鍵を生成する場所とファイル名を聞いてきます。

場所は、デフォルトで「ユーザー・ディレクトリー(C:/Users/ユーザー名)に、.sshフォルダーを作成します。後の指定の事もあるので、デフォルトのままにします。

ファイル名は、デフォルトで「id_rsa」になります。デフォルトのままの方が後の指定が楽なところもあるのですが、Github用であることが判るように「_github」を付けます。

最後に、パスフレーズを聞いてきます。パスフレーズは任意であり、指定しない方が楽なところもあるのですが、やはり昨今のセキュリティの事を考えて付けます。

正常にカギが作成されると、以下の2つのファイルが作成されます。

user@DESKTOP-EUGK5HR MINGW64 ~
$ ssh-keygen -t rsa -b 4096 -C "sshkey@github"
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/user/.ssh/id_rsa): /c/Users/user/.ssh/id_rsa_github
Created directory '/c/Users/user/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/user/.ssh/id_rsa_github.
Your public key has been saved in /c/Users/user/.ssh/id_rsa_github.pub.
The key fingerprint is:
・・・
The key's randomart image is:
・・・
秘密鍵パーミッション

秘密鍵パーミッションを変更します。他の人のページでは、変更しないと接続時に困るようです。

しかし、パーミッションを 600(rw-------)に設定するようにガイドされているのですが、Windowsではできません。一応、ファイルのプロパティの隠しファイルを変更してみましたが、あまり意味はなかったかもしれません。詳細設定まですればよかったかもしれません。

f:id:hanasakag:20190704165547p:plain

ただ、Git Bashでlsコマンドで確認してみると、以下のように 644 になっているので、自分以外は書き込めないし、取り敢えず使えているので大丈夫だろうと思います。

$ ls -l
-rw-r--r-- 1 AzureAD+ 4096 3434  7月  3 10:49 id_rsa_github
-rw-r--r-- 1 AzureAD+ 4096  746  7月  3 10:49 id_rsa_github.pub
configファイルの編集

最後に、SSHのconfigファイルを編集します。GitHubSSH接続する際に、ファイル名をデフォルトから変更しているので、どの秘密鍵を使用するかを指定します。configファイルは、ユーザー・ディレクトリー(C:/Users/ユーザー名)の.sshフォルダーの配下に、「config」という名前で作成します。

Hostは、ssh接続の識別名なので何でもよいと思いますが、わかりやすく「github」にしています。

HostNameは「github.com」、Userは「git」で、そのままにしないと接続できませんでした。因みに、Githubヘルプに、「リモートURLへの接続を含むすべての接続は、 "git"ユーザーとして作成されなければなりません。 GitHubのユーザー名で接続しようとすると失敗します。」という記述がありました。

IdentityFileで、秘密鍵のパスとファイル名を指定します。

Host github
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa_github

 

Githubの準備

Github側で、SSH接続するための準備を行います。

Githubのアカウント作成

まず、Githubのアカウントを持っていなければ、アカウントを作成します。アカウントを持っていなかったので作成しましたが、取得手順については参考にさせていただいたページに詳細に記述されているので省略します。

Githubのアカウントでログインします。

公開鍵の登録

先ほど作成した公開鍵をGitHubに登録します。

保存した公開鍵(~/.ssh/id_rsa_github.pub)をエディタで開き中の文字列をコピーするか、Git Bashで次のコマンドを入力してコピーします。

$ clip < ~/.ssh/id_rsa_github.pub

公開鍵のGithubへの登録手順については、参考にさせていただいたページに詳細に記述されているので省略します。

 

GitとGithubssh接続

上記までの準備ができたら、GithubSSH接続できるか確認します。

一番最初の接続

今までの準備で接続しようとした時、以下のように「Permission denied (publickey)」のエラーになって接続できません。

$ ssh github
hanasakag@github.com: Permission denied (publickey).
対処法

Webでいろいろググると、結構いっぱいヒットします。その中で、Generating SSH Keys · GitHub Helpに、以下の記載があります。

新しい SSH キーを生成して ssh-agent に追加する - GitHub ヘルプ

# start the ssh-agent in the background
$ eval "$(ssh-agent -s)"
> Agent pid 59566
$ ssh-add ~/.ssh/id_rsa

上記の内容は、いろいろググった結果、以下のようなことだと思います。

Git Bashを使用している場合は 、ssh-agentをオンにします。eval(イーバル)は、文字列を式として評価する関数、または複数の文をプログラム中のあるコンテキストで実行するサブルーチンです。ssh-agentを実行すると、次のような値が戻されます。この結果をevalコマンドに渡して、環境変数に登録します。特に、SSH_AGENT_PIDは、「ssh-agent -k」コマンドでssh-agentを終了する時に、プロセスを特定するために参照されます。

$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-dACAlw5972/agent.5972; export SSH_AUTH_SOCK;
SSH_AGENT_PID=6496; export SSH_AGENT_PID;
echo Agent pid 6496;

ssh-addコマンドを実行して、パスフレーズを入力すれば、このGit Bashのセッションの間は、パスフレーズ入力を省略できるようになります。ほとんどのシステムでは、デフォルトの秘密鍵(~/.ssh/id_rsa、~/.ssh/id_dsa、および~/.ssh/identity)がssh-agentに自動的に追加されます。 ssh-add path/to/keyを生成するときにファイル名を上書きしない限り、ssh-add path/to/keyを実行する必要はありません。今回はファイル名を変更しているので、秘密鍵を登録する必要があります。

以上のことから、以下のようにコマンドを入力すると、パスフレーズを聞いてきました。「You've successfully authenticated」が表示されて、正常に接続することが確認できました。

$ eval `ssh-agent`
Agent pid 1752

$ ssh-add ~/.ssh/id_rsa_github
Enter passphrase for /c/Users/user/.ssh/id_rsa_github:
Identity added: /c/Users/user/.ssh/id_rsa_github (sshkey@github)

$ ssh github
PTY allocation request failed on channel 0
Hi User-name! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

 

ssh-agentへの対応

ssh-agentは、Windowsを立ち上げている間はバックグラウンド・タスクとして稼働していますが、立ち上げ直せばまたコマンドを入力して稼働させなくてはなりません。毎回入力するのも手間なので、対応を検討しました。

対応内容

検討した結果、Git Bashを立ち上げた時に、ssh-agentも自動で稼働し秘密鍵も登録されるようにしたいと思います。また、そのままだとGit Bashを立ち上げる度にssh-agentが起動され、複数のssh-agentが稼働してしまいます。そこで、Git Bash終了時に、ssh-agentも終了するようにしたいと思います。尚、パスフレーズは、セキュリティの観点から毎回入れることにします。

以下のページを参考にさせていただき、「~/.bashrc」に立ち上げ時の処理、「~/.bash_logout」に終了時の処理を組み込みました。

d.hatena.ne.jp

.bashrc

作成した.bashrcは、以下のようになりました。Git Bashを起動した時のディレクトリーも、cdコマンドで変えることにしました。

#ssh-agent
eval `ssh-agent`
ssh-add ~/.ssh/id_rsa_github
cd c:/Git
.bash_logout

作成した.bash_logoutは、以下のようになりました。

eval `ssh-agent -k`

 

リポジトリの連携

ざっと、Gitの導入から使用、Githubまでの連携をまとめてみました。実際の使用にあたっては、リポジトリの共有や連携が肝心です。以下のページを参考に、Githubのリモートリポジトリを経由した、2台のPCのGitローカル・リポジトリの連携を行いました。

流れとしては、PC-AのGitでローカル・リポジトリとファイルを作成 → Githubにリモートリポジトリを作成しpush → PC-BでGithubからリポジトリのclone を行っています。

qiita.com

Gitでのローカルリポジトリの作成

Git単体での使用」ですでに書いたように、先ずPC-AでGitのローカルリポジトリを管理するディレクトリを作成し、Git Bashでそのディレクトリにローカルリポジトリを作成します。

そのディレクトリにファイルを作成し、ステージングとコミットをします。

$ cd JavaScript_tutorial

$ git init
Initialized empty Git repository in C:/DATA/Git/JavaScript_tutorial/.git/

$ git status
On branch master
No commits yet
Untracked files:
  (use "git add ..." to include in what will be committed)
        alert.js
        basic_task1.html
nothing added to commit but untracked files present (use "git add" to track)

$ git add .

$ git status
On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached ..." to unstage)
        new file:   alert.js
        new file:   basic_task1.html

$ git commit -a
hint: Waiting for your editor to close the file...
[master (root-commit) 776419c] Hellow World タスク
 2 files changed, 14 insertions(+)
 create mode 100644 alert.js
 create mode 100644 basic_task1.html

 

Githubのリモートリポジトリへの登録

Githubのリモートリポジトリへ登録するために、Github側でリポジトリを作成します。

f:id:hanasakag:20190712154120p:plain

 

Githubリポジトリを作成した時に表示される、次の赤枠の内容をコピーします。

f:id:hanasakag:20190712151209p:plain

 

次に、PC-Aで作成したGitのローカルリポジトリを、Githubのリモートリポジトリと連携させます。次のコマンドを、PC-AのGit Bashで入力します。このコマンドによって、originという名前(識別子)でローカルリポジトリがリモートリポジトリを指すようになります。

$ git remote add origin git@github.com:User-name/JavaScript_tutorial.git

 

これにより、PC-AのGitローカルリポジトリで管理しているものを、Githubリモートリポジトリにpushすることができます。pushした結果は、以下のようになります。

$ git push -u origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 465 bytes | 465.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To github.com:User-name/JavaScript_tutorial.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

 

Githubで確認すると、リモートリポジトリに正常にアップロードされています。

f:id:hanasakag:20190712155455p:plain

 

別PCのGitにローカルリポジトリをコピー

今度は、別のPC PC-BでGithubのリモートリポジトリから、Gitのローカルリポジトリにcloneで複製します。

再度、Githubのリモートリポジトリのページの右側の「Clone or download」をクリックし、「Use SSH」を選択して赤枠のリポジトリ名をコピーします。

f:id:hanasakag:20190712204112p:plain

 

PC-BのGit Bashリポジトリを保存するディレクトリに移動し、Git cloneコマンドに先ほどコピーしたリモートリポジトリ名を付けて実行し、Githubのリモートリポジトリを複製します。ディレクトリが作成されて、ソースもコピーされています。

$ cd git

$ git clone git@github.com:User-name/JavaScript_tutorial.git
Cloning into 'JavaScript_tutorial'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 4 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.

$ cd JavaScript_tutorial

$ ls -l
total 2
-rw-r--r-- 1 user 197609  24  7月 12 20:43 alert.js
-rw-r--r-- 1 user 197609 269  7月 12 20:43 basic_task1.html

 

以上で、GitとGithubを連携させて、バージョン管理を何とか出来るようになりました。

 

[更新履歴]

2019/07/12 リポジトリの共有について追記しました。