ポータブル環境でVSCodeからGitHubプライベートリポジトリを使う
最終更新:2019年3月8日
このドキュメントは、ワクワクしながらVSCodeからGitHubのプライベートリポジトリを使おうとして、
とか、
の悪夢に悩まされている方向けです。それズバリ認証失敗です。
スマートな解決策が他にあるかもしれませんが、僕が色々試したところでは、どうしても/dev/tty問題が解決できず、VSCodeのパスフレーズ入力ダイアログを回避してssh-agentに認証を任せるしかありませんでした。ここではその手法を説明します。
構築に使用した環境
- Windows10 Version 1803
- Visual Studio Code 1.31.0 zip版
- (Portable)Git for Windows 2.20.1
- ポータブル環境ではないVSCodeとGitもインストールされている(がこちらは使わない)
- ポータブル環境は以下の様にVSCodeとPortableGitが展開されている
[jtHiuPortable]
├───[apps]
│ └───[win]
│ ├───[VSCode]
│ ├───[PortableGit]
│ └───Code.cmd
├───[files]
└───VSCode_Win.lnk
- 自前で用意した2つのファイルのうち、
Code.cmd
は以下の様な内容で、VSCode_Win.lnk
はCode.cmd
へのトリックショートカットである1
> echo start %~dp0VSCode\Code.exe > Code.cmd
ここまでで「えぇっと…」と思った方は、このページではなくステップバイステップの方で進めてください。
確認済みの事項
- ○ Windows7での動作を確認しました。
- ○ ネットワークドライブ(情報大のZ:ドライブ)での動作を確認しました。
- ○ OneDrive上での動作を確認しました。
- × パス中に日本語フォルダ名を含むとダメです。
- OneDrive母艦方式で
C:\Users\太郎>
とかいうのが一番厄介 - ↑「(Windows10のユーザーフォルダ名変更」の手順2がオススメです。
- OneDrive母艦方式で
- × UNCパスもダメです。
- Windowsエクスプローラーのホーム→新規→ショートカット→「ドライブとしてマップ」からドライブレターを割り当ててください。
- × Mac上VMwareのvmware-host経由では、ドライブとしてマップでもダメでした。
- デバイスごとWindowsに接続している場合は大丈夫です。OneDriveもOK。ただし、なぜかVSCode起動用バッチのコマンドプロンプトが終了しませんので、気にしないのが吉です。
ポータブル環境用Gitの使用を明示する
デフォルトでは当然、マシンにインストールされているGitを使いに行こうとしますが、まずはこれをポータブル環境へ引き込むためにパスなどの環境変数を設定するバッチファイルを作成します。
D:\jtHiuPortable> touch apps\win\setPath.cmd
@echo off
if Defined AppsWinRoot GoTo PostPathSettings
echo Portable Console is preparing environment variables.
set NOW_CD=%cd%
cd /D %~dp0..\..
set HOME=%cd%
cd /D %NOW_CD%
set AppsWinRoot=%HOME%\apps\win
set GitD=%AppsWinRoot%\PortableGit
set PATH=%GitD%\cmd;%GitD%;%GitD%\usr\bin;%path%
:PostPathSettings
echo Portable home has located in %HOME%
echo Portable applications have located in %AppsWinRoot%
要点解説:
- 2行目 … 多重起動によるPATH登録の無限増殖を防いでいます。
- %~dp0 … 「動作中のスクリプトファイルがあるパス」です。
- 環境変数HOMEの設定 … sshなどMSYS2(MinGW64)なコマンドは環境変数HOMEをホームディレクトリとして使用します。環境変数に相対パスの部分を残したくなかったので、ちょっと面倒な手順を踏んで設定しています。
-
PATHへの追加項目
-
%GitD%\cmd
… git起動用 -
%GitD%
… git-bash起動用 -
%GitD%\usr\bin
… MSYS2(MinGW64)各種コマンド向け
-
これを、きちんとポータブル環境で動作しているか確認するため、あえて標準のホームから叩いてみます。sshはもちろん接続にコケますが、ポータブル環境のホームに.ssh
フォルダが自動的に作成されたことを確認してください。
Microsoft Windows [Version 10.0.17134.590]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\MyName>D:\jtHiuPortable\apps\win\setPath.cmd
Portable Console is preparing environment variables.
Portable home has located in D:\jtHiuPortable
Portable applications have located in D:\jtHiuPortable\apps\win
C:\Users\MyName>git --version
git version 2.20.1.windows.1
C:\Users\MyName>git-bash
(git-bashのウィンドウが開く)
C:\Users\Nyname>ssh -T git@github.com
The authenticity of host 'github.com (192.30.255.113)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?
(とりあえず空Enter)
Host key verification failed.
MyName@MyWin MINGW64 /c/Users/MyName
$ ls ~
apps/ files/ VSCode_Win.lnk
これで、gitやsshが起動することと、git-bash上でホームディレクトリがきちんとポータブル環境のフォルダになっていることを確認できました。
apps\win
にあるVSCode起動用バッチファイルも、これを経由するようにします。
@echo off
call %~dp0setPath.cmd
start %~dp0VSCode\Code.exe
VSCodeのGit自動検索を回避する
VSCodeは起動時に、標準的なGit for Windowsのインストール場所を巡回して探してくるというポータブル環境にとっては大変余計なことをしてくれます。そんな訳で仕方なくsettings.json
のgit.path
にフルパス書くんですが汎用性が低い。なんで、これでいいです。てか、こう書いてください。
{
"git.path": "git"
}
セキュリティリスクは判るけどこれをデフォルトにしてくれよ…とも思うんですが… こうするとパスの通ったGit環境を使ってくれます。もちろん既に色々設定している方は、この一行(と行末にコンマも付けて)追加してください。ちなみにsettings.json
はCtrl+Shift+P
でコマンドパレットを開いて、open settings (j
ぐらいまで打てば開けます。
ポータブル環境向けのSSHキーを作成し、GitHubに登録する
既にSSHキーをお持ちの方も多いとは思いますが、ポータブルデバイス紛失のリスクを考えると、大事な秘密鍵を持ち歩きたくはありませんので、ポータブル用のキーペアを新たに作成する方が安心です。フォーマットはGitHubの流儀に従って作成します。
詳細は「SSHキーを作成してGitHubに登録する」にまとめましたので、やり方がピンとこない方はご参考に。
ここまでのフォルダ構造を確認すると以下の様な感じです。
[jtHiuPortable]
├───[.ssh]
│ ├───known_hosts
│ ├───rsa_GitHub
│ └───rsa_GitHub.pub
├───[apps]
│ └───[win]
│ ├───[VSCode]
│ ├───[PortableGit]
│ ├───Code.cmd
│ └───setPath.cmd
├───[files]
├───.bash_history //もちろんこれはなくてもいい
├───.gitconfig
└───VSCode_Win.lnk
ssh-agentを起動する
これでOKなはずなんですけどどうにもパスワードを聞いてくれない。そこでssh -v
とか色々とデバッグログを見ていると、きちんとポータブル環境のファイルは見に行ってるんだけど、パスフレーズの入力で/dev/tty
がねぇぞってことでコケる。もちろんコマンドで叩けばちゃんとcloneできる。ってなわけで、GCMとか色々物色して試したんですけどダメで、普通に(?)ssh-agentを使うことにしました。
まず、start-ssh-agent
を使うのですがバッチファイルから呼び出すとcmd
を起動してダンマリするので塩梅が悪いため、ファイルをコピーして、
> copy %GitD%\cmd\start-ssh-agent.cmd %AppsWinRoot%\summon-ssh-agent.cmd
1個のファイルをコピーしました。
下から2行目のcmd
起動部をREMっちゃいます。
~ 省略 ~
@IF NOT ERRORLEVEL 1 @(
REM @CALL cmd %*
)
そして、パス設定のバッチファイル最後で召喚します。一応全掲。
@echo off
if Defined AppsWinRoot GoTo PostPathSettings
echo Portable Console is preparing environment variables.
set NOW_CD=%cd%
cd /D %~dp0..\..
set HOME=%cd%
cd /D %NOW_CD%
set AppsWinRoot=%HOME%\apps\win
set GitD=%AppsWinRoot%\PortableGit
set PATH=%GitD%\cmd;%GitD%;%GitD%\usr\bin;%path%
:PostPathSettings
echo Portable home has located in %HOME%
echo Portable applications have located in %AppsWinRoot%
call %~dp0summon-ssh-agent
VSCodeを黙らせることが目的ですので、VSCode起動バッチの方に使用するキーを追加します。ちょっとだけ多重起動対策してます。4行目のssh-add
以降は、.ssh
のconfig
のIdentityFile
に書いたものをコピペしてください。ハードコードは美しくないんですが、この辺は後々構築が進んだら環境変数を使うことにします。
@echo off
call %~dp0setPath.cmd
ssh-add -l
if ErrorLevel 1 ssh-add ~/.ssh/rsa_GitHub
start %~dp0VSCode\Code.exe
あとは、VSCodeをバッチ経由で起動しようとすると、ssh-agentがいない場合は召喚し、パスフレーズが入力されていなければそれを承認してからVSCodeが起動します。
Portable Console is preparing environment variables.
Portable home has located in D:\jtHiuPortable
Portable applications have located in D:\jtHiuPortable\apps\win
Removing old ssh-agent sockets
Starting ssh-agent: done
The agent has no identities.
Enter passphrase for /d/jtHiuPortable/.ssh/rsa_GitHub:
(パスフレーズを入力してEnterキー)
ssh-agentを停止する
通常の使用であればVSCodeを開き直してもパスフレーズを再入力する必要がないので便利ですが、共有マシンなどでログインしっぱなしなのは問題がある場合も多いですし、何よりssh-agentの召喚中は「ハードウェアを安全に取り外してデバイスを取り出す」ができないので、召還するスクリプトrecall-ssh-agent.cmd
をapps\win
に用意して、ここに飛ぶトリックショートカットRecallAgent_Win.lnk
もポータブル環境フォルダに作成、必要に応じてダブルクリックして自動認証を終了させられるようにします。
@SETLOCAL EnableDelayedExpansion
@FOR /f "tokens=1-2" %%a IN ('tasklist /fi "imagename eq ssh-agent.exe"') DO @(
@ECHO %%b | @FINDSTR /r /c:"[0-9][0-9]*" > NUL
@IF "!ERRORLEVEL!" == "0" @(
@SET SSH_AGENT_PID=%%b
%~dp0PortableGit\usr\bin\ssh-agent -k
)
)
要点解説:基本的にはstart-ssh-agent.cmd
からPID取得部を持ってきています。
- 1行目 … 遅延展開の使用を宣言します。
- 2-3行目 … tasklistコマンドをforから用いて、起動中のssh-agentを検索し、PIDの部分を取得します。
- 4-6行目 … きちんと取得できたら、ssh-agentが参照する環境変数に代入し、さよならします。
オプション:VSCodeの英語モード起動をなんとかする
インストール直後はしょうがない。ただ、ポータブル環境デバイスを他のマシンで利用する時(恐らくドライブレターが変更された時)、初回のみ英語モードで起動してしまいます。code.cmd --locale ja
でもダメです。恐らく、起動時に拡張機能(各国語対応も拡張機能)を遅延読み込みするため、環境が変わってElectronが混乱している間に日本語拡張が読み込まれないままワークベンチが表示されてしまうからでは、と推測していますが、初回時(パスフレーズを入力する時)には自動的にVSCodeを再起動するように変更したCode.cmd
を示します。気にならない方はウザいだけですので変更しなくて結構です。
@REM WARNING: This Windows command script is tainted with BASH commands
@echo off
call %~dp0setPath.cmd
ssh-add -l
if ErrorLevel 1 (
setlocal EnableDelayedExpansion
ssh-add ~/.ssh/rsa_GitHub
echo ------------------------------------------------------------
echo ** WARNING **
echo Visual Studio Code will *RESTART* after boot. Please wait...
echo ------------------------------------------------------------
start %~dp0VSCode\Code.exe
:loop
sleep 1
set COUNT=0
for /f "skip=3 tokens=1" %%a in ('tasklist /fi "imagename eq code.exe"') do (
set /a COUNT+=1
)
if "!COUNT!" LSS "6" goto :loop
echo Visual Studio Code is restarting now. Please wait...
for /f "tokens=3" %%a in ('%~dp0VSCode\bin\code.cmd --status ^| grep code') do (
taskkill /PID %%a > nul 2>&1
)
endlocal
)
start %~dp0VSCode\Code.exe
要点解説:割愛
これが読めるようになると、大抵のバッチファイルは書けるはず。Electronがウィンドウ作るんで/minも>nulも効かないのがお騒がせになって残念。や、VSCodeのバグ取れるといいっすね。
クローンする
はいこれで本当にOK。早速git cloneしましょう。プライベートリポジトリの初期化はGitHubサイトの方で済ませておいてください。
リポジトリを開いたら右側のClone or download
ボタンをクリック、そのダイアログがClone with SSH
になっていることを確認、もしもClone with HTTPS
となっていたら、その横(画像ではUse HTTPSとなっている場所)にUse SSH
リンクがあるのでそれをクリックして切替、その下のアドレスがかかれた右側にある、クリップボードに左矢印ボタンを押してアドレスをコピーします。
Ctrl+Shift+P
でコマンドパレットを開き、git clone
ぐらいに入力するとGit: クローン
が出るのでそれを選択、
リポジトリのURLを聞かれるので、入力欄をクリックしてCtrl+V
で貼り付け、
Enter
キーを押すとダイアログが出るので、ポータブル環境のfiles
フォルダを選択してリポジトリの場所を選択
ボタンを押します。するとfiles
の下にリポジトリと同名のフォルダを作成して持ってきます。git initもいらないです。
下の奴が出てもこれはエラーじゃないんでビビらなくてOKです。
手順通りにやると、最終的にはこの様な配置になります。もちろんfiles
以下はクローンしたリポジトリによって様々です。
[jtHiuPortable]
├───[.ssh]
│ ├───known_hosts
│ ├───rsa_GitHub
│ └───rsa_GitHub.pub
├───[apps]
│ └───[win]
│ ├───[VSCode]
│ ├───[PortableGit]
│ ├───Code.cmd
│ ├───recall-ssh-agent.cmd
│ ├───setPath.cmd
│ └───summon-ssh-agent.cmd
├───[files]
│ └───[sandbox]
│ ├───[.git]
│ ├───.gitignore
│ ├───LICENSE
│ └───README.md
├───.bash_history
├───.gitconfig
├───VSCode_Win.lnk
└───RecallAgent_Win.lnk
以上です。では、Happy Coding!
-
.cmdファイルは「Windowsコマンドスクリプト」、.bat上位互換のいわゆるバッチファイルです。.batだと遅延展開など現代風のバッチが書けず、.ps1だと実行に管理者権限が必要な場合が多いので、ここでは*.cmdを使用します。 ↩