#contents
----
* 概要 [#Summary]
- 共有リポジトリをリモート(CentOS)上に作成し、ローカルリポジトリ(Windows)から更新する。

* インストール [#Install]
- git パッケージのインストール&br;
「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

* 共有リポジトリ [#RemoteRepository]

** 共有リポジトリに作業ファイルを保持 [#RemoteRepository_WithWorkingFile]
- 共有リポジトリ上に作業ファイルを保持し、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"

** 共有リポジトリは管理専用 [#RemoteRepository_Bare]
- 共有リポジトリは管理のみを行い、編集は作業用リポジトリ側で行う。
 # 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 上に共有リポジトリを作成 [#RemoteRepository_SMB]
- 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 できなくなる。
-- [[Push to repository in a shared folder doesn't work (regression from 2.10.2) #979>GitHub:git-for-windows/git/issues/979]]
-- [[git bash fail to push branch with error message: "object directory does not exist" - Stack Overflow>Stackoverflow:41115613]]
-- 回避策: ドライブレター付きのネットワークドライブとしてアクセスするようにする。

* Windows クライアントのインストール [#WinClientInstall]
- http://windows.github.com/ からインストーラをダウンロードし実行する。
- インストール後、GitHub アカウントの入力はキャンセルしてスキップ可能。
- 「tools - options」を開いて初期設定を行う。
- 「configure git」で、ユーザ名およびメールアドレスを設定する。&br;
コミットの際のユーザの区別に使用される。
- エクスプローラで「%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
-- [[OpenSSH SSH client configuration files:http://www.openbsd.org/cgi-bin/man.cgi?query=ssh_config]]
- global 設定
 %LOCALAPPDATA%/GitHub/PortableGit_xxx/etc/gitconfig

* ローカルリポジトリ設定 [#LocalRepository]
- 「GitHub」は終了して「Git Shell」を起動する。
- リモートリポジトリをローカルにコピーする。&br;
パスフレーズを聞かれたらタイプする。&br;
同名のフォルダが既にある場合はクローンに失敗する。
 > 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の環境変数を引き継がせる。&br;
(今 sync しているかどうかは分かるが push に失敗する x_x;)
 > github
- 「GitHub」に今作成した「test1.git」フォルダをドロップするとトラッキングされるようになる。
- 以降、作業は新しいブランチ側で行い、merge は共有リポジトリで行う。
- ファイル転送の際に改行コードの変換を行わない
-- コマンド
 > git config core.autocrlf false
-- config ファイル
 [core]
 	autocrlf = false

** 現在のリポジトリに別のリポジトリへの参照を追加 [#LocalRepository_RemoteAdd]
 $ git remote add <リモートリポジトリ名> <リモートリポジトリの場所>
 $ git fetch <リモートリポジトリ名>
 $ git branch <リモートリポジトリ用ブランチ名>
 $ git push --set-upstream <リモートリポジトリ名> <リモートリポジトリ用ブランチ名> (push 初回)
 $ git push <リモートリポジトリ名> <リモートリポジトリ用ブランチ名> (push 2回目以降)

- 「git remote add origin <uri>」で「fatal: remote origin already exists.」が出る場合は「origin」が既に設定されている。&br;
「origin」を上書きするには「git remote set-url origin <uri>」とする。

** push 時に複数のリポジトリを更新 [#PushToMultiRepository]
- リモートリポジトリ '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>

** 指定するファイルに関するコミット履歴を表示 [#ShowCommitLogForFile]
 > git log --all -- "*/filename"
- [[How to locate a deleted file in the commit history? - Stack Overflow>Stackoverflow:7203515]]

** リモートにあるブランチを追跡する [#TrackRemoteBranch]
- リモートのブランチを表示
 > git branch -r
   origin/HEAD -> origin/master
   origin/feature1
   origin/master   
- origin/feature1 を追跡する
 > git checkout --track origin/feature1

** ブランチ毎に別のリポジトリへプッシュ/プルする [#PushPullEachRepositoryByBranch]
- リモートリポジトリ(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>Stackoverflow:2765421]]

** git 出力のリダイレクト [#RedirectToFile]
- powershell 上で git の出力をファイルへリダイレクトすると、UTF-8 なソースの差分が UTF-16LE ファイルとして保存され、文字化けする。
- ファイルへリダイレクトする場合は、powershell ではなく cmd.exe 上で出力する。

- [[powershell - Git Shell in Windows: patch's default character encoding is UCS-2 Little Endian - how to change this to ANSI or UTF-8 without BOM? - Stack Overflow>Stackoverflow:13675782]]
 cmd /c "git diff > patch.diff"

** 指定日以降のコミットログ [#LogSince]
 > git log --since="yyyy-mm-ddThh:mm:ss+09:00"

** 指定日間の差分 [#DiffByDate]
- 差分全体
 > 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
#code(powershell){{{{
# 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'})
}}}}

** タグ [#Tag]
- 一覧
 > git tag
- 絞り込み
 > git tag -l "<pattern>"
- 追加&br;
shaを省略すると現在のコミットに対してタグが追加される。
 > git tag -a <tagname> -m "<comment>" [<sha>]
- 削除
 > git tag -d <tagname>
- 詳細表示
 > git show <tagname>
- リモートへのプッシュ&br;
明示的に操作しないとタグはリモートへプッシュされない。
 > git push origin --tags
- タグの指すコミットへのチェックアウト(一時的, ブランチを作らない)
 > git checkout refs/tags/<tagname>
- タグの指すコミットへのチェックアウト(ブランチを作る)
 > git checkout -b <branchname> refs/tags/<tagname>

* カスタマイズ [#Customize]

** Git ユーザ切替 [#Customize_gitConfigSwitcher]
- %HOMEPATH%\.gitconfig を複数ユーザで切り替える。
- %HOMEPATH%\ に .gitconfig.UserA, .gitconfig.UserB, ... のように予めユーザ分ファイルを用意しておく。
- 下記コマンドで切り替え。
 > gitConfigSwitcher.bat UserA
- gitConfigSwitcher.bat
#code(dosbatch){{{{
@echo off
type "%HOMEPATH%\.gitconfig.%1" > "%HOMEPATH%\.gitconfig"
}}}}

** 鍵ファイル作成 [#MakeRsaKey]
 $ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
- [[Generating SSH keys - User Documentation:https://help.github.com/articles/generating-ssh-keys/]]
- 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).
-- [[DSA SSH keys not in PubkeyAcceptedKeyTypes (#2943) - Issues - GitLab.org:https://gitlab.com/gitlab-org/gitlab-ce/issues/2943]]
-- [[OpenSSH 7.0 disables ssh-dss keys by default – Gentoo Linux:https://www.gentoo.org/support/news-items/2015-08-13-openssh-weak-keys.html]]

** 秘密鍵ファイル選択スクリプト [#Customize_SelectIdentityFile]
- &ref(add-id.zip);
#code(powershell){{{{
# 秘密鍵ファイルをリストから選択して追加するスクリプト

$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) [#AddSshId_CentOS]
- ~/.bash_profile の最後に追加 (exec 以降は実行されない)
 exec ssh-agent $SHELL
- シェルから id を追加
 $ ssh-add

** リポジトリごとに秘密鍵ファイルを切替 [#Customize_ChangeIdentityFile]
- 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 を読み取る機能を付けてみる。&br;
&ref(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>
- 環境変数確認&br;
なんで 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]
- pullAll.ps1
#code(powershell){{{{
Get-ChildItem -Directory |
  ForEach-Object { Write-Output $_.Name; Set-Location $_; git pull; Set-Location ..; }
}}}}

* リンク [#Link]
- [[Git:https://git-scm.com/]]
-- [[Pro Git 日本語訳:https://git-scm.com/book/ja/]]

- [[GitHub:https://github.com/]]
-- [[GitHub for Windows:http://windows.github.com/]]
- [[github:help:https://help.github.com/]]
-- [[Bootcamp:https://help.github.com/categories/54/articles]]
--- [[Set Up Git:https://help.github.com/articles/set-up-git]]
--- [[Create A Repo:https://help.github.com/articles/create-a-repo]]
--- [[Fork A Repo:https://help.github.com/articles/fork-a-repo]]
--- [[Be Social:https://help.github.com/articles/be-social]]
-- [[Markdown Basics:https://help.github.com/articles/markdown-basics]]
--- [[GitHub Flavored Markdown:https://help.github.com/articles/github-flavored-markdown]]
--- [[Writing on GitHub:https://help.github.com/articles/writing-on-github]]
--- [[Mastering Markdown:https://guides.github.com/features/mastering-markdown/]]
- [[GitHub Developer:https://developer.github.com/]]
-- [[Webhooks:https://developer.github.com/webhooks/]]
- [[GitHub Pages:https://pages.github.com/]]
-- [[Pages Help:https://help.github.com/pages/]]

- [[Gravatar:https://ja.gravatar.com/]] グローバルに認識されるアバター (Globally Recognized Avatars)
-- [[開発者向け資料:https://ja.gravatar.com/site/implement/]]
--- [[Perl Image Requests:https://ja.gravatar.com/site/implement/images/perl/]]
-- 指定サイズのアバターの取得, サイズ省略時は 80x80 pixel&br;
&#x68;ttps://www.gravatar.com/avatar/ハッシュキー?s=サイズ

- [[GitPrep - Github clone.:http://gitprep.yukikimoto.com/]]
-- [[GitHub:yuki-kimoto/gitprep]]

- [[分散バージョン管理システムGitの使い方入門 - SourceForge.JP Magazine:http://sourceforge.jp/magazine/09/02/02/0655246]]
- [[Gitを使いこなすための20のコマンド - SourceForge.JP Magazine:http://sourceforge.jp/magazine/09/03/16/0831212]]

- [[ハックガールズと学ぼう!ゼロから学ぶGit講座|gihyo.jp … 技術評論社:http://gihyo.jp/dev/serial/01/hackgirlsgit]]
-- [[第5回 Git操作をなかったことにする!:http://gihyo.jp/dev/serial/01/hackgirlsgit/0005]]

- [[【コラム】イマドキのIDE事情 (142) 「Github for Windows」でGithubをはじめてみよう! - マイナビニュース:http://news.mynavi.jp/column/ide/142/]]

- [[まったりSE備忘録 - 仕事・趣味を通して得た技術的なメモです。:http://sememo.blue-robin.jp/]]
-- [[Git の Master サーバー構築:http://sememo.blue-robin.jp/?p=479]]

- [[Log for Backup - Naoki_Rinの学習:http://d.hatena.ne.jp/naokirin/]]
-- [[私の使うGitコマンドまとめ 基本コマンド編:http://d.hatena.ne.jp/naokirin/20111201/1322576109]]

- [[uzullaがブログ:http://uzulla.hateblo.jp/]]
-- [[WindowsでGit(オチだけ読めばいいです):http://uzulla.hateblo.jp/entry/2012/07/30/015015]]

- [[西尾泰和のはてなダイアリー:http://d.hatena.ne.jp/nishiohirokazu/]]
-- [[gitのHEADがブランチから外れてしまう現象とその直し方:http://d.hatena.ne.jp/nishiohirokazu/20110513/1305290792]]

- http://tazyamah.tumblr.com/
-- [[• gitで複数のauthorを使い分けたかったので頑張った:http://tazyamah.tumblr.com/post/21048111291/git-author]]

- [[unoh.github.com:http://unoh.github.com/]]
-- [[快適なsshクライアント生活:http://unoh.github.com/2010/03/12/ssh_config.html]]

- [[トリコロールな猫:http://www.nekotricolor.com/]]
-- [[ベアリポジトリとノンベアリポジトリ:実践編:http://www.nekotricolor.com/blog/2013/05/02/965/]]

- [[Windowsユーザー向けGit入門:CodeZine:http://codezine.jp/article/corner/479]]

- [[Anton: How to avoid GitHub client's "The diff is too large to show here" issue:http://www.amaslo.com/2012/09/how-to-avoid-github-clients-diff-is-too.html]]

- [[Unity で GitHub しよう!:http://keijiro.github.io/unity-github-tutor/]]

- [[castor4bit - Qiita:http://qiita.com/castor4bit]]
-- [[圧縮/難読化されたJavaScriptファイルのgit diffをみやすくする:http://qiita.com/castor4bit/items/782ca023e92ae6ff8e51]]

- [[Automatic prune with git fetch or pull - Stack Overflow>Stackoverflow:18308535]]

- [[hnwの日記:http://d.hatena.ne.jp/hnw/]]
-- [[GitHubへpull requestする際のベストプラクティス:http://d.hatena.ne.jp/hnw/20110528]]

リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS