概要
- 共有リポジトリをリモート(CentOS)上に作成し、ローカルリポジトリ(Windows)から更新する。
インストール
- git パッケージのインストール
「user1」は ssh でログインできるユーザ。# yum install git # su user1 $ git config --global user.name "Your Name" $ git config --global user.email you@example.com $ git config --global core.autocrlf false $ git config --global core.quotepath false $ git config --global core.pager "LESSCHARSET=utf-8 less" $ git config --global fetch.prune true $ git config --global remote.origin.prune true $ git config --global push.default simple
共有リポジトリ
共有リポジトリに作業ファイルを保持
- 共有リポジトリ上に作業ファイルを保持し、merge も共有リポジトリ上で行う。
- 共有リポジトリで checkout されているブランチに対して push しようとするとエラーになる。
- 共有リポジトリの作成
# mkdir -p /var/git/test1.git # cd /var/git # chown user1. test1.git # su user1 $ cd test1.git $ git init --shared $ touch README.txt .gitignore $ chmod 644 README.txt .gitignore $ git add README.txt .gitignore $ git commit -a -m "first commit"
共有リポジトリは管理専用
- 共有リポジトリは管理のみを行い、編集は作業用リポジトリ側で行う。
# mkdir -p /var/git/test1.git # cd /var/git # chown user1. test1.git # su user1 $ cd test1.git $ git init --bare --shared $ git config core.quotepath false $ mkdir ~/git $ cd ~/git $ git clone /var/git/test1.git $ cd test1 $ touch README.txt .gitignore $ chmod 644 README.txt .gitignore $ git add README.txt .gitignore $ git commit -a -m "first commit" $ git push origin master
NAS 上に共有リポジトリを作成
- Windows ファイル共有フォルダ内に共有リポジトリを作成する。
- パスの区切りは「\」ではなく「/」を使用する。
> git init --bare --shared //nas_name/path-to-repository/repository_name.git
- 作業用リポジトリ作成(1) ブランチ 'master' をトラックする場合
> git clone //nas_name/path-to-repository/repository_name.git
作業用リポジトリ作成(2) 'master' 以外のブランチをトラックする場合(ブランチ 'develop' の例)
> git init repository_name > cd repository_name > git remote add origin //nas_name/path-to-repository/repository_name.git > git fetch origin develop > git pull origin develop > git checkout develop
-
リモートリポジトリを UNC パス形式で指定すると「***.git/objects does not exist」エラーとなり push できなくなる。
Windows で OpenSSH-Win64 を使用する
-
Chocolateyで git および OpenSSH をインストールする。
> cinst -y -params /GitAndUnixToolsOnPath git > cinst -y -params /SSHAgentFeature openssh
- %USERPROFILE%/.gitconfig に使用するSSHコマンドを登録。
> git config --global core.sshCommand "'C:/Program Files/OpenSSH-Win64/ssh.exe'"
Windows クライアントのインストール
- http://windows.github.com/ からインストーラをダウンロードし実行する。
- インストール後、GitHub アカウントの入力はキャンセルしてスキップ可能。
- 「tools - options」を開いて初期設定を行う。
- 「configure git」で、ユーザ名およびメールアドレスを設定する。
コミットの際のユーザの区別に使用される。 - エクスプローラで「%USERPROFILE%/.ssh」を開く。
> cd /d %USERPROFILE%/.ssh
- リモートリポジトリの ssh 用秘密鍵をここにコピーする。
> copy repo1.example.com_rsa %USERPROFILE%/.ssh/
- 秘密鍵ファイル名は「id_rsa」以外だとうまく動かないみたいだ。
> copy repo1.example.com_rsa %USERPROFILE%/.ssh/id_rsa
- 「config」を %USERPROFILE%/.ssh フォルダに作成する。
host RemoteRepo1 user user1 hostname repo1.example.com port 22 identityfile ~/.ssh/id_rsa.repo1.example.com
- global 設定
%LOCALAPPDATA%/GitHub/PortableGit_xxx/etc/gitconfig
ローカルリポジトリ設定
- 「GitHub」は終了して「Git Shell」を起動する。
- リモートリポジトリをローカルにコピーする。
パスフレーズを聞かれたらタイプする。
同名のフォルダが既にある場合はクローンに失敗する。> git clone ssh://user1@RemoteRepo1/var/git/test1.git
- 作業用のブランチ(例:testing)を作成
> git branch testing
- master から testing へブランチを切り替える。
> git checkout testing
- 作業用のブランチを共有リポジトリに送信(1回目, 追跡ブランチに登録)。
> git push --set-upstream origin testing
- 作業用のブランチを共有リポジトリに送信(2回目以降)。
> git push
- 「Git Shell」から「GitHub」を起動し、SSH_AGENTの環境変数を引き継がせる。
(今 sync しているかどうかは分かるが push に失敗する x_x;)> github
- 「GitHub」に今作成した「test1.git」フォルダをドロップするとトラッキングされるようになる。
- 以降、作業は新しいブランチ側で行い、merge は共有リポジトリで行う。
- ファイル転送の際に改行コードの変換を行わない
- コマンド
> git config core.autocrlf false
- config ファイル
[core] autocrlf = false
- コマンド
現在のリポジトリに別のリポジトリへの参照を追加
$ git remote add <リモートリポジトリ名> <リモートリポジトリの場所>
$ git fetch <リモートリポジトリ名>
$ git branch <リモートリポジトリ用ブランチ名>
$ git push --set-upstream <リモートリポジトリ名> <リモートリポジトリ用ブランチ名> (push 初回)
$ git push <リモートリポジトリ名> <リモートリポジトリ用ブランチ名> (push 2回目以降)
- 「git remote add origin 」で「fatal: remote origin already exists.」が出る場合は「origin」が既に設定されている。
「origin」を上書きするには「git remote set-url origin 」とする。
push 時に複数のリポジトリを更新
- リモートリポジトリ 'origin' に push する際に別のリポジトリに push する。
- pushurl が設定されていると元の url には push されなくなるので、元の url にも push したい場合は改めて pushurl に元の url を登録する必要がある。
> git remote set-url --add --push origin <元々のurl> > git remote set-url --add --push origin <別のリポジトリのurl>
指定するファイルに関するコミット履歴を表示
> git log --all -- "*/filename"
リモートにあるブランチを追跡する
- リモートのブランチを表示
> git branch -r origin/HEAD -> origin/master origin/feature1 origin/master
- origin/feature1 を追跡する
> git checkout --track origin/feature1
ブランチ毎に別のリポジトリへプッシュ/プルする
- リモートリポジトリ(remote1)を追加
> git remote add remote1 <url>
- 現在のリモートリポジトリを表示
> git remote -v
- ローカルにブランチ(branch1)を作成
> git checkout -b branch1
- 編集結果をコミット
> git commit
- リモート(remote1)にブランチ(branch1)を作成
> git push -u remote1 branch1
- ローカルとリモートの全てのブランチを表示
> git branch -a
リモート(remote1)のブランチ(branch1)の更新を取り込み
> git pull
How do I push a new local branch to a remote Git repository and track it too? - Stack Overflow
git 出力のリダイレクト
- powershell 上で git の出力をファイルへリダイレクトすると、UTF-8 なソースの差分が UTF-16LE ファイルとして保存され、文字化けする。
ファイルへリダイレクトする場合は、powershell ではなく cmd.exe 上で出力する。
cmd /c "git diff > patch.diff"
指定日以降のコミットログ
> git log --since="yyyy-mm-ddThh:mm:ss+09:00"
指定日間の差分
- 差分全体
> git diff "master@{yyyy-mm-ddThh:mm:ss+09:00}" "master@{yyyy-mm-ddThh:mm:ss+09:00}"
- ファイル名のみ
> git diff "master@{yyyy-mm-ddThh:mm:ss+09:00}" "master@{yyyy-mm-ddThh:mm:ss+09:00}" --name-only
- PowerShell スクリプト GitDiffFrom.ps1
# Show changed files between "From" and "To" Param( [string]$From = '', [string]$To = '', [switch]$Content = $false, [string]$Branch = 'master' ) $repo = Split-Path -Leaf (git.exe rev-parse --show-toplevel) if (!$repo) { Write-Warning 'Not in git repository' Break } if (!$From) { $envGitDiffFrom = "GitDiffFrom_${repo}" $From = [Environment]::GetEnvironmentVariable($envGitDiffFrom) if (!$From) { Write-Warning "No environment variable: ${envGitDiffFrom}" Break } } if (!$To) { $To = Get-Date -format 'yyyy-MM-ddTHH:mm:ssz' } git.exe diff "${Branch}@{${From}}" "${Branch}@{${To}}" $(if ($Content) {''} else {'--name-only'})
タグ
- 一覧
> git tag
- 絞り込み
> git tag -l "<pattern>"
- 追加
shaを省略すると現在のコミットに対してタグが追加される。> git tag -a <tagname> -m "<comment>" [<sha>]
- 削除
> git tag -d <tagname>
- 詳細表示
> git show <tagname>
- リモートへのプッシュ
明示的に操作しないとタグはリモートへプッシュされない。> git push origin --tags
- タグの指すコミットへのチェックアウト(一時的, ブランチを作らない)
> git checkout refs/tags/<tagname>
- タグの指すコミットへのチェックアウト(ブランチを作る)
> git checkout -b <branchname> refs/tags/<tagname>
カスタマイズ
Git ユーザ切替
- %HOMEPATH%.gitconfig を複数ユーザで切り替える。
- %HOMEPATH%\ に .gitconfig.UserA, .gitconfig.UserB, ... のように予めユーザ分ファイルを用意しておく。
- 下記コマンドで切り替え。
> gitConfigSwitcher.bat UserA
- gitConfigSwitcher.bat
@echo off type "%HOMEPATH%\.gitconfig.%1" > "%HOMEPATH%\.gitconfig"
鍵ファイル作成
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
- Generating SSH keys - User Documentation
- DSA は GitHub Desktop 3.0.8 からサポートされなくなったので、DSA を使っていた場合は RSA で作り直す必要がある。
Skipping ssh-dss key /home/user1/.ssh/id_dsa for not in PubkeyAcceptedKeyTypes Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
秘密鍵ファイル選択スクリプト
-
add-id.zip
# 秘密鍵ファイルをリストから選択して追加するスクリプト $ssh_path = "~/.ssh/" $ids = @{} $index = 1 foreach ( $id in Get-ChildItem $ssh_path -include id_rsa.* -Name ) { Write-Host "${index}: ${id}" $ids[$index] = $id ++$index } $in = Read-Host "鍵の番号を入力して下さい。" $key = 0 [void][int]::TryParse( $in, [ref]$key ) $id = $ids[ $key ] if ( $id ) { $absPath = Convert-Path "${ssh_path}${id}" ssh-add $absPath } else { Write-Host "入力した番号は無効です。" }
ssh id の追加 (CentOS)
リポジトリごとに秘密鍵ファイルを切替
GUI を立ち上げる前に Git Shell 立ち上げて「ssh-add %USERPROFILE%/.ssh/id_rsa.repo1.example.com」をやっておけば切り替えなくても大丈夫なのかな?
./.git/config で秘密鍵ファイルを指定できれば、リポジトリごとに別の鍵が使えるんじゃね?
[remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = ssh://user1@RemoteRepo1/var/git/test1.git identityfile = ~/.ssh/id_rsa.repo1.example.com
- %LOCALAPPDATA%/GitHub/PoshGit_xxx/GitUtils.ps1 に config を読み取る機能を付けてみる。
GitUtils_2.zip - shell を立ち上げると確かに鍵ファイルが切り替わってるけど、GUI の方は切り替わってなくて sync に失敗する。 ← 今ココ
- ssh-agent もプロセスが重複して立ち上がってるみたいだし、Windows 向けにはあんまり作りこんでないのかなぁ。
- ssh-agent の終了
> ssh-agent -k (現在のプロセスのみ)
- ssh-agent のプロセス ID 確認
> tasklist | Select-String ssh
- プロセスの強制終了
> taskkill /f /pid <プロセスID>
- 環境変数確認
なんで Select-String で grep できないんだろ?> Get-ChildItem env: | Sort-Object Name > Get-Item env:SSH_AGENT_PID > Get-Item env:SSH_AUTH_SOCK
- GitUtils.ps1 の diff
--- GitUtils.ps1 2012-10-22 16:43:04.253827100 +0900 +++ GitUtils_2.ps1 2012-11-26 00:03:14.126000000 +0900 @@ -246,8 +246,12 @@ if (!$sshAdd) { Write-Warning 'Could not find ssh-add'; return } if ($args.Count -eq 0) { - $sshPath = Resolve-Path ~/.ssh/id_rsa - & $sshAdd $sshPath + #$sshBakPath = Join-Path (Resolve-Path ~/.ssh/) "id_rsa.bak" + #$sshIdPath = Join-Path (Resolve-Path ~/.ssh/) "id_rsa" + $sshBranchPath = Resolve-Path (Get-IdentityFile (Get-GitBranch)) + #Copy-Item -Path $sshIdPath -Destination $sshBakPath -Force + #Copy-Item -Path $sshBranchPath -Destination $sshIdPath -Force + & $sshAdd $sshBranchPath } else { foreach ($value in $args) { & $sshAdd $value @@ -285,3 +289,42 @@ } git checkout -q $head } + +# get a identityfile for branch +function Get-IdentityFile($branch) { + $conf_path = Join-Path (Get-Location) "/.git/config" + if ( Test-Path $conf_path ){ + $config = @{} + $block = "" + foreach($line in Get-Content $conf_path){ + switch -regex ($line) + { + "^\[\s*([^\s]+)(?:\s+`"([^`"]+)`")?\s*\]$" { + if ( $matches[2] ){ + $block = $matches[1] + "-" + $matches[2] + } else { + $block = $matches[1] + } + $config[$block] = @{} + break + } + "^\s*([^=\s]+)\s*=\s*(.*)$" { + $config[$block][$matches[1]] = $matches[2] + break + } + default { + #write-host "ignored: $line" + break + } + } + } + + $remote = $config["branch-$branch"]["remote"] + $identityfile = $config["remote-$remote"]["identityfile"] + } + #write-host $identityfile + if ( !$identityfile ){ + $identityfile = "~/.ssh/id_rsa" + } + return $identityfile +}
すべてのサブフォルダを更新
- pullAll.ps1
Get-ChildItem -Directory | ForEach-Object { Write-Output $_.Name; Set-Location $_; git pull; Set-Location ..; }
リンク
- github:help
- GitHub Developer
-
Gravatar グローバルに認識されるアバター (Globally Recognized Avatars)
- 開発者向け資料
- 指定サイズのアバターの取得, サイズ省略時は 80x80 pixel
https://www.gravatar.com/avatar/ハッシュキー?s=サイズ
【コラム】イマドキのIDE事情 (142) 「Github for Windows」でGithubをはじめてみよう! - マイナビニュース
Anton: How to avoid GitHub client's "The diff is too large to show here" issue