[GitHub]如何在同一台 mac 中建立兩個不同的 GitHub account ?
Table of Contents
Why need 2 or more Git(Hub) accounts in the same mac?
我現在的目的就只是為了能熟悉 Git 操作, 利用多個 Git accounts 來觀察實驗結果, 而遠端的服務選擇的是 GitHub.
在設定多個帳戶過程中遇到了一些困難, 藉由此篇記錄相關知識.
網路上很多使用者是利用多個 Git accounts 來使得開發者的環境, 可以同時存在個人以及公司的 Source Version Control, 這才是真正的使用場景.
2 Major Domain knowledge need to understand
SSH
and Git Configuration
是兩個基礎知識, 本篇記錄這兩個部分.
SSH (Secure SHell protocol)
目前利用這種密鑰的登入服務是主流方法(因為設定成功後, 使用者就可以不用 type 密碼.), 利用開發者產生的私鑰和公開密鑰, 將公開密鑰放到遠端服務上, 來做匹配帳號的事.
現在我的 mac 上是用 OpenSSH 這個實作 SSH 的 Open Source, 應該是 macOS 的標準配備.
ssh-keygen
利用 ssh-keygen
除了可以產生公鑰和私鑰之外, 呈現密鑰, 還可以管理 /.ssh/known_hosts
- 一個記錄著你透過 ssh 方式登入過遠端服務器的列表檔案.
Generate Key - ssh-keygen
底下是常用的生成密鑰命令, 執行成功後會在你設定的路徑(跟在 -f
之後)產生私鑰和公鑰(副檔名為 .pub
)兩個檔案:
ssh-keygen -t rsa -b 4096 -C "Developer Key Note" -f ~/.ssh/brad_github_id_rsa
-t
: ssh-keygen support 4 types – dsa
, ecdsa
, ed25519
,and rsa
. The default value is rsa
type(SSH-2).
ssh-keygen -t dsa
-f
: Use -f
to give the file name of private key, and public key with .pub
. If have no -f
parameter, .ssh/id_rsa
or .ssh/id_dsa
will be the default file name of private key, .ssh/id_rsa.pub
or .ssh/id_dsa.pub
will for public key.
-b
: The length of key. For rsa type key, 最小要求768位,默认是2048位。DSA密钥必须恰好是1024位(FIPS 186-2 标准的要求). In the GitHub online doc, they used 4096.
-C
: This parameter just is a comment for display, 其實很多講到使用 ssh-keygen 都說 -C
用 email, 其實不用, 這只是個用來呈現該密鑰是誰或是可以做什麼, 不寫也沒關係, Provides a new comment
是 BSD General Commands Manual 對這參數的說明. 若在建立的過程沒加入, 可以後來再透過 -c
來添加.
Display public key on stdout by inputing private key
ssh-keygen -y
ssh-keygen -y -f privateKeyPath
可以利用 -y
後面接著私鑰的檔名, 結果會輸出公鑰到螢幕.
其實使用者可以直接 cat
公鑰的也可以看到.
Manage .ssh/known_hosts
當第一次透過 ssh 登入遠端服務器時, 本地端會在 ~/.ssh/known_hosts
中存放這些遠端服務器的公鑰. 而 ssh-keygen
也提供一些方式來管理查看這些遠端服務器的公鑰. 其實使用者可以直接打開 known_hosts
觀察.
Clear public key in .ssh/known_hosts
ssh-keygen -R HostName
Find specific hostname from .ssh/known_hosts
ssh-keygen -F HostName
ssh-keygen -F HostName -l
ssh-agent, ssh-add
http://www.zsythink.net/archives/2407
What is the ssh-agent
ssh-agent
一個幫助管理私鑰的代理程式, 通常是被預設啟動的, 若沒有被啟動, 用如下的命令呼叫:
eval 'ssh-agent'
而管理哪些私鑰是透過 ssh-add
來加入.
ssh-add
ssh-add ~/.ssh/id_rsa_personal
將特定私鑰加入 ssh-agent
這個服務.
List all of private key from agent
ssh-add -l -E md5
Move out specific private key from ssh_agent
ssh-add -d '~/.ssh/id_rsa_custom'
Move out all of private key from ssh_agent
ssh-add -D
Git Configuration
在 ~/.gitconfig
中記錄著 git 的 global configuration, 包含了預設編輯器, diff tool, …等等.
設定使用者
git config --global user.name "User Name"
git config --global user.email "UserName@email.address"
如果你的電腦環境對不同的遠端服務器(或者公司服務器)所記錄的帳號資料都相同, 可以設定成全域值.
這兩個欄位主要是會在 commit log 中顯示的名字和郵件.
不過一般來說對公司的環境, 應該是會用公司的郵件資料. 所以建議這兩個欄位是放在 locale, 也就是根據不同的倉庫對應到個別的 user name/ e-mail. 若要同時可以存在對同一個遠端服務器的多個帳號, 也建議用 locale user name/ email.
在個別的倉庫目錄下設定各自的 user name/ email:
git config --local user.name "User Name"
git config --local user.email "UserName@email.address"
--local
其實可以省略.
Git clone new repository
如果環境設定中將 user.name
and user.emial
從 global 設定中移除, 那麼在每一次 git clone git@github.com:someone/some.git
完之後, 會比較麻煩要額外設定 user.name and user.email locally.
所以只要在 .zshrc
中添入如下 alias, 之後只要執行 gitclone git@github.com:someone/some.git
, 就會一起設定 user.name and user.email.
alias gitclone='git clone --config user.name="your name" --config user.email="youremail@address.com" $@'
利用 alias 可能遇到的問題
在實際的操作會有多個 alias 來對應不同帳號, 以方便輕易的填入 name, email 等資料. 但常常會遇到一個情況:
輸入完所要的 gitclone alias 之後, 後面直接貼上從 github 複製過來的 github path.
gitclone git@github.com:bradleetw/flask-tutorial.git
單一帳號都沒問題, 但多個帳號就會有狀況, 你可能選了不同的 gitclone alis command, 然後直接複製貼上 github path, 如下:
gitclone2 git@github.com:bradleetw/flask-tutorial.git
問題就發生在 github.com
, 這個要改成不同帳號的相對 ssh remote host name, 也就是下一節的內容, 一般都會忘了改, 導至 clone 成功後, 卻因為 ssh key 不對而無法上傳.
.ssh/config, 設定遠端服務器資料
打開 .ssh/config
可以看到如下的資料:
Host github.com-personal
HostName ssh.github.com
Port 443
UseKeychain no
User git
IdentityFile ~/.ssh/sgithub_id_rsa
IdentitiesOnly yes
這個檔案裡可以放入多個遠端服務器的資料, 而在 Host 後頭跟著的名稱, 就是當你要決定連到哪一個遠端服務器時, 要填入的名.
git clone git@github.com-personal:someone/some.git
ssh -T github.com-personal
如果要連到同一個遠端服務器, 但是是用不同的帳號時, 要在 .ssh/config
裡在設定一組 Host, 重要的是在新的 Host setting 的 IdentityFile
欄位要設成另一個帳號的私鑰檔案.
Verify whether is workable
ssh -T AliasNameInSSH_Config
ssh -vT AliasNameInSSH_Config
AliasNameInSSH_Config: 就是在 .ssh/config
中每一組遠端服務器設定的 Host
欄位, 跟在後面的名字.
相關設定若是正確, 會有以下的顯示輸出:
Hi accountNameOfRemoteServer! You've successfully authenticated, but GitHub does not provide shell access.
若想知道連接過程的細項流程, 加入 -vT
.
若失敗就會出現 Permission denied (publickey).
.
原則上若是單一帳戶的使用場景, 這些設定其實就可以了.
How to enable second git account in the same mac
- 利用
ssh-keygen
建立另一組新的密鑰. - 將新的公鑰上傳至遠端服務器.
- 利用
ssh-add
將新的私鑰放到ssh-agent
. - 在
~/.ssh/config
中增加新的 Host 資料, 並透過IdentityFile
告知所使用的密鑰. - 透過
ssh -T HostName
檢驗是否設定成功.
設定成功後, 表示你可以用不同帳號下載或 clone, 但不一定可以上傳, 原因就是遠端服務器是否有開上傳權限給你.
Push failed
原先因為我對 GitHub 的一知半解, 以為所有在 GitHub 上的資料, 除了可以任意下載, 還可以任意上傳. 這樣的觀點只對一半, 若是下載上傳的倉庫都是你自己的單一帳號, 那是沒問題的. 但若是別人的帳號, 上傳的權限就要原倉庫擁有者開放給你, 之後才可以上傳. 就是因為不清楚, 以為前面提的五個步驟設定完成就可以用不同帳號下載上傳, 然後就一直出現以下的 error message.
ERROR: Permission to userA/Scripts.git denied to UserB.
fatal: 无法读取远程仓库。
请确认您有正确的访问权限并且仓库存在。
GitHub Help reference: https://help.github.com/articles/error-permission-to-user-repo-denied-to-user-other-repo/
Set an organization repository
參考以下 GitHub Help 設定合作開發專案:
https://help.github.com/articles/adding-outside-collaborators-to-repositories-in-your-organization/
設定成功後, 在透過 invite other user 來將第二個帳號加入同一個開發專案. 第二個帳號只要接受了邀請, 就可以 push commit.
第二個帳號上傳失敗的可能原因
Reference
https://blog.alantsai.net/posts/2015/09/use-ssh-in-windows-for-github
https://kuanyui.github.io/2016/08/01/git-multiple-ssh-key/
http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html
https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/