|
現: 2024-11-07 (木) 10:50:39 yuji |
| + | *共有リポジトリの作成と運用 [#u8c9db25] |
| + | 複数の人で共有するリポジトリがあると便利。 このような目的で使用するリポジトリを,リモートリポジトリ(共有リポジトリ)と呼んでいます。 |
| | | |
| + | ** リモートリポジトリ(共有リポジトリ)を作成 [#h3a83340] |
| + | Linuxマシンでは, |
| + | $ mkdir /var/www/git/hogehoge.git |
| + | $ cd /var/www/git/hogehoge.git |
| + | $ git --bare init --shared <-- 共有出来るようにsharedを付ける |
| + | $ chmod -R 777 ./objects |
| + | $ chmod -R 777 ./refs |
| + | このようにして,/var/www/git/hogehoge.gitというリモートリポジトリ(共有リポジトリ)を作成する。 |
| + | |
| + | Windowsマシンでは,共有ディレクトリにリモートリポジトリを作る場合は,~ |
| + | エキスプローラーで,共有ディレクトリに''hogehoge.git''のようなgitでアクセスするためのディレクトリを作成する。~ |
| + | 例えば,''\\xxxxx\gitrepo/hogehoge.git''ディレクトリを作成した場合は, |
| + | > md \\modulesrv\gitrepo\hogehoge.git |
| + | > git --bare init --shared \\xxxxx\gitrepo\hogehoge.git <-- 共有出来るようにsharedを付ける |
| + | Initialized empty shared Git repository in //xxxxx/gitrepo/hogehoge.git/ |
| + | として,''\\xxxxx\gitrepo\hogehoge.git''というリモートリポジトリ(共有リポジトリ)を作成する。~ |
| + | 誰でもアクセス出来るように,セキュリティ設定を行っておきます。 |
| + | |
| + | 要するに,作成したいディレクトリに,''git --bare init --share''コマンドで,空のリモートリポジトリを作成します。~ |
| + | |
| + | この時注意することとして,WindowsのGit(Git for Windows)から共有ファイルを指定する場合は,''ディレクトリの区切りに\ではなく/を使用したほうが良いです。'' |
| + | |
| + | ''リモートリポジトリ(共有リポジトリ)は,いろいろな人と共有するリポジトリなので,上記のようにリモートリポジトリを作成した上で,リモートリポジトリをファイルサーバーやネットワーク上に公開してアクセス出来るように構築する必要があります。'' |
| + | |
| + | リポジトリ名として,Gitの場合はxxxxxx.gitと.gitを付けたディレクトリ名にするのが慣例のようだ。~ |
| + | |
| + | ** リモートリポジトリ(共有リポジトリ)に反映させる [#r916b897] |
| + | まず,使用するリモートリポジトリを登録します。~ |
| + | $ git remote add <name> <url> |
| + | とします。 |
| + | |
| + | 例えば,//xxxxx/repos/hogehoge.git(MS Networkの共有ディレクトリに作ったリモートリポジトリ)の場合, |
| + | $ git remote add origin //xxxxx/repos/hogehoge.git |
| + | として,登録します。~ |
| + | |
| + | 登録できたか確認は, |
| + | $ git remote -v |
| + | origin //xxxxx/repos/hogehoge.git (fetch) |
| + | origin //xxxxx/repos/hogehoge.git (push) |
| + | で確認できます。 |
| + | |
| + | これで準備できましたので,pushコマンドを使ってリモートリポジトリに反映させます。 |
| + | $ git push origin master |
| + | |
| + | これで,リモートリポジトリ(共有リポジトリ)に登録できたんで,複数人で共同作業が行えるようになった。 |
| + | #ref(流れ.png,,70%) |
| + | |
| + | ** リモートリポジトリ(共有リポジトリ)がある場合の流れ [#u79b6e18] |
| + | + ''git clone''でリモートリポジトリ(共有リポジトリ)からファイルをコピーする~ |
| + | + ファイルを編集,新規作成~ |
| + | + ''git commit''でリポジトリに変更を登録~ |
| + | $ git commit -m "説明・・・" |
| + | + ''git push''でリモートリポジトリ(共有リポジトリ)を更新~ |
| + | |
| + | ** リモートリポジトリ(共有リポジトリ)からコピーを持ってくる(clone) [#bd4804e3] |
| + | リモートリポジトリ(共有リポジトリ)があれば,そこからまるごと複製して自分の手元で作業をすることが出来るようになります。~ |
| + | |
| + | リモートリポジトリ(共有リポジトリ)を手元に複製するには,''clone(クローン)''という操作をします。~ |
| + | $ git clone //xxxxx/repos/hogehoge.git |
| + | とかすればOK。~ |
| + | #ref(clone.png,,70%) |
| + | |
| + | ''clone''コマンドした場合,どこのリポジトリを取得したかの情報が''origin''として記録される。~ |
| + | この時は,リモートリポジトリの内容をまるまるダウンロードしてきて,手元のPCにローカルリポジトリとして作成されます。~ |
| + | |
| + | Subversionのcheckoutに似ているんだけど,gitでは''リポジトリサーバーが保持しているデータを全てコピーします。''~ |
| + | つまり履歴も含んだ全てが''git clone''とすることで手元に持ってこれる。~ |
| + | これは,リモートリポジトリが万が一壊れちゃっても,どこかに残っているcloneしたデータを戻してやれば復元も可能になり,これまでの履歴ももちろん復元される。~ |
| + | このへんが,Subversionとは違うところ。~ |
| + | |
| + | その後,編集後,例えば,hogehoge.newでfile1.txtを作成後,共有レポジトリに反映させる時には,~ |
| + | $ git commit -a -m "add file1.txt" |
| + | $ git push origin master |
| + | |
| + | これで,共有レポジトリにfile1.txtが追加される。~ |
| + | gitのpushは,Subversionでのコミットに相当します。~ |
| + | |
| + | *** 最新の履歴だけをコピーする [#xb6656f5] |
| + | ファイルをリモートリポジトリから取得するためだけに使う場合,最新の履歴だけで済むことがある。~そんなときは,~ |
| + | $ git clone --depth 1 <repository> |
| + | |
| + | とする。この場合,このコピーからclone,fetch,pushすることは出来ない。また,このコピーにpush することもできない。~ |
| + | |
| + | *** サブモジュールも合わせて取得する [#d55e78cc] |
| + | リモートリポジトリにサブモジュールが含まれている場合,''-–recursive''オプションで一括で取得できる。~ |
| + | $ git clone --recursive git://example.com/repo.git |
| + | |
| + | これは,リモートリポジトリをクローンした後に,~ |
| + | $ git submodule update --init --recursive |
| + | を実行したことと同じ。~ |
| + | |
| + | *** リポジトリをコピーして特定のブランチをワークツリーにする [#rb274b24] |
| + | ブランチBRANCHをもつリモートリポジトリからcloneするときに,~ |
| + | $ git clone -b BRANCH https://example.com/repo.git |
| + | とすると,コピーされたリポジトリのブランチがBRANCHになる。~ |
| + | |
| + | *** ローカルにあるリポジトリを複製する [#k4f45888] |
| + | $ git clone /path/to/repo |
| + | で,マシンの/path/to/repoにあるリポジトリが,カレントディレクトリにコピーされる。~ |
| + | ローカルのパスが対象の時は,デフォルトで''-l''または''–local''オプションの動作になり,可能な場合はディスクスペースの節約のために''.git/objects''ディレクトリ以下のファイルはハードリンクされる。~ |
| + | |
| + | 普通にコピーしたい場合は,''-–no-local''オプションを使う。~ |
| + | $ git clone --no-local /path/to/repo |
| + | |
| + | ** リモートリポジトリからプルする(pull) [#wc794159] |
| + | リモートリポジトリ(共有リポジトリ)を共有して複数人で作業すると,みんながリモートリポジトリにプッシュしていきます。~ |
| + | すると,自分のローカルリポジトリに,ほかの人がプッシュした変更内容を取り込む必要が出てきます。~ |
| + | #ref(pull2.png,,70%) |
| + | ''Pull''コマンドを実行すると,リモートリポジトリから最新の変更履歴をダウンロードしてきて,自分のローカルリポジトリに自動的にマージが行われます。~ |
| + | |
| + | hogehogeディレクトリで,今までの更新を反映させるには,~ |
| + | $ cd hogehoge |
| + | $ git pull //moduledesign/ModuleDesign/repos/hogehoge.git |
| + | |
| + | とすると,hogehogeが,hogehoge.newと結果的には同じになる。pullは,別の人によって行われた変更を取得するにも使われます。~ |
| + | |
| + | これで共同でファイルを編集・更新が出来るようになります。~ |
| + | |
| + | *** ワークディレクトリの変更をcommitせずにpullしたい [#wd61d7e3] |
| + | ワークディレクトリで何らかの変更をしていて,それをコミットせずに''pull''しようとすると以下のようなエラーで怒られる。 |
| + | error: Your local changes to the following files would be overwritten by merge: |
| + | path/to/file |
| + | Please, commit your changes or stash them before you can merge. |
| + | Aborting |
| + | |
| + | こんな時は,''stash''コマンドを使って変更を一時的に隠すようにしてから''pull''する方法があります。~ |
| + | - stash save: 現在の状態を保存し,git上から変更箇所を隠す。~ |
| + | $ git stash save <コメント> |
| + | Saved working directory and index state On master: <コメント> |
| + | HEAD is now at 13770bf hoge |
| + | コメントをつけてもつけなくてもOK。つけたほうが後でわかりやすいが・・・~ |
| + | - stash list: shashの一覧を見る。~ |
| + | $ git stash list |
| + | stash@{0}: On master: <コメント> |
| + | - pullする。~ |
| + | $ git pull |
| + | - stash pop: 自分の変更したものを戻す。~ |
| + | $ git stash pop |
| + | Auto-merging path/to/file |
| + | : |
| + | (snip) |
| + | : |
| + | Dropped refs/stash@{0} (fb418991e1ace34585c49007c0976a19e89f3efd) |
| + | |
| + | ** リモートリポジトリからfetchする(fetch) [#g85d2e70] |
| + | pullコマンドを実行すると,リモートリポジトリの内容が変更されていれば自動的にマージが行われる。~ |
| + | しかし,単にリモートリポジトリの内容を確認したいだけの時は,マージをしたくない場合もあります。~ |
| + | |
| + | こんな時は,''fetch''コマンドを使用します。~ |
| + | ''fetch''コマンドを使うと,リモートリポジトリのデータをローカルリポジトリにコピーするだけを行います。~ |
| + | #ref(fetch.png,,70%) |
| + | |
| + | ''fetch''コマンドで取得したコミットは,''名前の無いブランチ''として取り込まれます。~ |
| + | この名前の無いブランチは,''FETCH_HEAD''という名前でチェックアウトすることが出来ます。~ |
| + | |
| + | 例えば,ローカルリポジトリとリモートリポジトリの''origin''のそれぞれに,Bから進んだコミットがある状態で''fetch''コマンドを行うと,下の図のような履歴になります。~ |
| + | #ref(フェッチ1.png,,70%) |
| + | この状態から,リモートリポジトリの内容をローカルリポジトリの''master''に統合する場合は,''FETCH_HEAD''をマージするか,改めて''pull''を実行します。~ |
| + | #ref(フェッチ2.png,,70%) |
| + | |
| + | マージを行うと,''pull''の時と同じ履歴になります。~ |
| + | |
| + | ** リモートリポジトリにpushする(push) [#bf4dac80] |
| + | ローカルリポジトリの内容をリモートリポジトリに送信する場合は,''push''を使用します。~ |
| + | この時,''push''したブランチが''fast-forward''マージされるようにしておく必要がある。~ |
| + | もし,競合が発生するような場合は''push''は拒否される。~ |
| + | $ git push origin master |
| + | |
| + | ローカルリポジトリで作成したブランチを共有したい場合は,明示的に''push''する必要があります。~そのため,''push''しない場合はリモートリポジトリに影響を与えることなく,自分だけのブランチを自由に作成することが出来ることになります。~ |
| + | |
| + | リモートリポジトリで共有しているコミットは,基本的に書き換えてはいけません。~ |
| + | もし書き換えてしまうと,そのリモートリポジトリと同期している他のリポジトリの履歴がおかしな状態になることがあるからです。~ |
| + | |
| + | ** プロジェクトを別リポジトリにpushする場合 [#m1e7548c] |
| + | 普通git pushは,git cloneしてきたリモートリポジトリに対して行う。~ |
| + | |
| + | 例として,以下の様な状況を考えてみる。~ |
| + | |
| + | 取り込み元 https://github.com/moto/torikomi_moto.git~ |
| + | 取り込み先 https://github.com/saki/torikomi_saki.git~ |
| + | $ git clone https://github.com/saki/torikomi_saki.git |
| + | $ cd torikomi_saki |
| + | $ git remote add torikomi_repo https://github.com/moto/torikomi_moto.git |
| + | $ git pull torikomi_repo master |
| + | $ git add . |
| + | $ git commit -m 'get torikomi_moto |
| + | $ git remote rm torikomi_repo |
| + | $ git push origin master |
| + | |
| + | + 一旦取り込み先のリポジトリをcloneする。~ |
| + | $ git clone https://github.com/saki/torikomi_saki.git |
| + | + 取り込み先のディレクトリへ移動。~ |
| + | $ cd torikomi_saki |
| + | + 取込元をremoteに登録。~ |
| + | $ git remote add torikomi_repo https://github.com/moto/torikomi_moto.git |
| + | + torikomi_repoからマスターにpullする。~ |
| + | $ git pull torikomi_repo master |
| + | + ファイルを追加する。~ |
| + | $ git add . |
| + | + コミットする。~ |
| + | $ git commit -m 'get torikomi_moto' |
| + | + torikomi_repoを削除。~ |
| + | $ git remote rm torikomi_repo |
| + | + $ git push origin master |
| + | |
| + | 5,6,8については,addしてcommitしてpushする。~ |
| + | |
| + | ** リモートリポジトリを他のものに移行する [#f07684fc] |
| + | リモートリポジトリを移行したい場合は,リモートリポジトリを変更します。~ |
| + | |
| + | - まず,移行先のリモートリポジトリを作成する~ |
| + | - ローカルのリポジトリを,現在のリポジトリの最新状態を取得する~ |
| + | $ git fetch |
| + | - 現在のリモートリポジトリの接続情報を確認する~ |
| + | $ git remote -v |
| + | - 現在のリモートリポジトリを削除する。(変更する場合)~ |
| + | 例:originリモートリポジトリを削除する。~ |
| + | $ git remote remove origin |
| + | - 変更したいリモートリポジトリに変更する~ |
| + | 例:orijinリモートリポジトリを変更したところを追加する。~ |
| + | $ git remote add origin https://user@hogehoge.com:new/reponame.git |
| + | - ローカルリポジトリを空の変更先リモートリポジトリに追加する~ |
| + | $ git push origin master |
| + | |
| + | pushにけっこう時間がかかってれば,まあだいたい成功してる。~ |
| + | 移行先サービスで,コミットログを確認し移行していることが確認したらOK。~ |
| + | |
| + | 前に作った個人用レポジトリを共有リポジトリに反映させる。~ |
| + | $ git push /var/www/git/hogehoge.git master |
| + | これで,共有リポジトリに登録できたんで,複数人で共同作業が行えるようになる。~ |
| + | |
| + | ** リモートリポジトリが更新されているかどうかを確認する方法 [#ya8dd1c8] |
| + | リモートリポジトリ(共有リポジトリ)は複数人で作業するので,知らないうちに更新されていく。~ |
| + | |
| + | なので,更新されているかどうかの確認が必要になることがあります。~ |
| + | |
| + | *** 方法1: git fetch 後にdiffをとる [#j2db44d9] |
| + | $ git fetch origin |
| + | $ git diff origin/master |
| + | この方法は,一般的な方法と思われる。 |
| + | ただ,fetchを行う必要があるという点でやや面倒。しかし,diffで確認する場合には必須となる。 |
| + | |
| + | *** 方法2: git ls-remote コマンドを使用する [#mb24d358] |
| + | git ls-remoteを使用することで,リモートリポジトリのコミットIDが取得できます。 |
| + | |
| + | リモートリポジトリの最新コミットID(HEAD)とローカルの最新コミットID(HEAD)を比較して,その2つが異なっていれば差分があると判断できる。~ |
| + | |
| + | さらに,リモートのコミットIDが過去に存在しないものであれば,ローカルのリポジトリが古い(マージしていないコミットがリモートに存在する)ことになる。 |
| + | > git ls-remote origin HEAD |
| + | be2027435764077703711e88c5e455379ad9b0d0 HEAD |
| + | > git log -1 HEAD |
| + | commit 39426be6bc92d14af859b5519c7de21cc4a914b6 |
| + | Author: Yuji Ueno <y-ueno@yueno.net> |
| + | Date: Fri Apr 5 17:55:21 2019 +0900 |
| + | |
| + | 確定注文分割時に,数量を登録すると一つ前の説明部分が元に戻ってしまう不具合を修正。 |
| + | |
| + | 方法1に比べてfetchする必要がなく,ざっくりと更新状況を見たい場合に利用出来る。~ |
| + | |
| + | *** 方法3: git remote show コマンドを使用する [#w4dd1a56] |
| + | 以下のように,実行結果の最終行に(local out of date)と表示されていれば,ローカルの方が古いことになる。 |
| + | ブランチが複数ある場合は,複数行表示される。 |
| + | > git remote show origin |
| + | * remote origin |
| + | Fetch URL: //xxxxx/yyyyy/test/naps.git |
| + | Push URL: //xxxxx/yyyyy/test/naps.git |
| + | HEAD branch: master |
| + | Remote branch: |
| + | master tracked |
| + | Local ref configured for 'git push': |
| + | master pushes to master (local out of date) |
| + | ただし,リモートブランチと同名のブランチがローカルにも存在する場合のみ表示される。 |
| + | また,リモートブランチと異なる名前のブランチは,upstream/tracking branchを設定していても表示されない。(残念…) |
| + | |
| + | 方法2と同様fetchする必要がなく,ざっくりと更新状況を見たい場合に利用出来る。~ |
| + | こちらのほうがわかりやすい気がする。~ |
| + | |
| + | ** 変更の統合(マージ) [#lb180be1] |
| + | #ref(merge1.png,,70%) |
| + | 最後にpullを実行してから次のpushをするまでの間に,他の人がpushをしてリモートリポジトリを更新してしまっていた場合には,自分のpushが拒否されてしまいます。~ |
| + | #ref(merge2.png,,70%) |
| + | |
| + | この場合,マージという作業を行なって,他の履歴での変更を取り込むまで,自分のpushは拒否されます。~ |
| + | マージを行わないままリモートリポジトリを更新してしまうと,他の人がpushした変更が失われてしまうからです。 |
| + | |
| + | *** 競合の解決 [#fe42c7c8] |
| + | マージ(merge)を行うとGitが変更箇所を自動的に統合します。しかし,自動でマージ出来ない場合もあります。~ |
| + | |
| + | リモートリポジトリとローカルリポジトリでファイル内の同じ箇所を変更していた場合は,自動ではマージできません。この場合,どちらの変更を取り込むか自動では判断できないのでエラーメッセージが表示されます。~ |
| + | |
| + | 競合が発生した箇所は,Gitがファイルの内容を図のように修正して表示してくれる。~ |
| + | #ref(merge3.png,,70%) |
| + | |
| + | なので,表示してくれている内容を参考に,該当のファイルを手動で編集します。~ |
| + | |
| + | その後,その後改めてコミットするのですが,この時,修正したファイルをステージします。~ |
| + | これをしないとgitは問題が解消したことに気づかないのです。~ |
| + | $ git add 修正したファイル |
| + | $ git status |
| + | 問題が解消したことを確認したら,~ |
| + | $ git commit -m "競合を修正してマージ" |
| + | でコミットする。その後pushすれば完了。~ |