→まとめ
個人PCで作業を行なう場合でも,大切なファイル(ディレクトリ)は リモートリポジトリにマスターファイルを置き,つねに同期を取りながら バックアップのある状態で作業する。
また,修正履歴を全て保存できるので,「ファイル名を変えてバックアップ」 のようなことを一切せずに済むようになる。
この操作にはSCMソフトウェア Mercurial を使用するので,あらかじめインストールしておく。
~/.emacs
ファイルに以下の記述を追加。
(load "mercurial")
~/.hgrc
ファイルに以下の書式で自分のローマ字氏名と
メイルアドレスを記述する。
[ui] username = KOEKI Taro <mail@add.ress>
研究室用の共有サーバを www.yatex.org 上に作成した。 ここに繋ぐための準備手順を示す。そのためには公開鍵認証用の 鍵ファイルを作成する。計算機故障等でなくすと困るのでroyで作成して それを手元計算機にコピーするようにする。
royにログインし,以下のようにコマンド起動する。 なお,インターネット演習でこの作業をした場合は不要。
ssh-keygen Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): パスフレーズ入力 Enter same passphrase again: : パスフレーズ入力
パスフレーズは15〜20文字程度のすばやく打てるものを付ける。
手元の計算機にroy上の鍵ファイルをコピーする。
scp c1yyxxx@roy.e.koeki-u.ac.jp:.ssh/id_rsa'*' ~/.ssh
c1yyxxx にはroyでの自分のユーザ名を入れる。
作成してコピーしてきた ~/.ssh/id_rsa.pub
ファイルを広瀬宛てに送る。これを読んでいる時点で完了しているはず。
手元の計算機の ~/.ssh/config
に以下の記述を追加する。
Host labosv HostName www.yatex.org User koeki Port 2422 AddressFamily inet
上記手順全て完了したら,手元の計算機の端末から接続できるか確認する。
ssh labosv hostname Enter passphrase for key '/home/taro/.ssh/id_rsa': (パスフレーズ入力) www.yatex.org
上記のコマンド実効に成功したら,サーバ上に自分のディレクトリを 作成する。
ssh labosv mkdir taro # 自分のユーザ名
保存したい作業ディレクトリを決めて,
そこでMercurialリポジトリを構築する。ここでは ~/hoge
をそのディレクトリとする。
cd hoge cat > .hgignore<<_EOF_ syntax: glob *.aux *.log *.toc *.o *~ \#* tmp/ _EOF_ hg init; hg ci -m init -A
続けて,手元のリポジトリ(.)をサーバ上に複製する。 複製する先のディレクトリ名を最後に指定するが, これはサーバ上の自分用ディレクトリ下の名前にする。
hg clone . ssh://labosv/taro/foo
リモート上に作成したリポジトリをさらに手元に複製する。
cd # ホームディレクトリに戻る hg clone ssh://labosv/taro/foo
これで ~/foo
に,リモートリポジトリを
原本としたクローンリポジトリができる。最初の作業ディレクトリ
(この例では ~/hoge
)と中味を比べる。
ls hoge ls foo
完全に同じであることが確認できたら元のディレクトリは消してしまってよい。
rm -rf hoge # これをやらずに残しておいてもよい
以後 ~/foo
で編集作業する準備ができた。
hg status
- 状態を見る
cd したらとにかく hg st
(status) する。
リポジトリの状態が分かる。修正があるファイルに M マーク,
未登録ファイルに ? マークなどが付く。
とにかく hg st
で何もメッセージが出ない状態を保つ。
hg pull -u
- リモートサーバの更新を取得(+反映)
サーバの修正を取得する。作業開始時に必ず行なう。
hg ci -m "メッセージ"
- コミット
行なった修正をリポジトリに登録する。 登録したものが番号付けされ永久保存版になる。
hg push
- 更新をリモートサーバに送る
コミットした更新群をまとめてリモートサーバに送る。 席を離れる前に忘れずに。
Emacsでファイルを編集した場合は,ある程度の修正ができたところで コミット(C-x v v)や,push (C-c h >) をする。
コミットすると,ログ記述バッファが開くので,やった作業の簡潔な説明を書き, C-c C-c で確定する。
一度サーバリポジトリに登録しておけば,作業の続きをネットに繋がった 別ホストで行なえる。たとえば,royやpanで行なう例を示す。
大まかな流れとしては,roy/panなどにログイン後, サーバからリポジトリを複製する。その後は以下の流れで作業を行なう。
必ず「pullしてから作業開始」と, 「作業の最後にpush」を忘れないようにする。
なお,pullのときに他のリポジトリを指定すると,そこから更新を
直接取得できる。たとえば,royのtaro/
ディレクトリで作業した
結果をサーバにpushしていなくても,たとえばmypcから,
cd ~/foo hg pull -uv ssh://roy/foo
とすると更新をmypcに取得でき,さらにこれを
hg push
するとサーバに更新を送り込むことができる。
[サーバリポジトリ] | | | | | 複製C | 複製B 複製A
上図のような関係で運用していて,複製Aで行なった更新をサーバにpushし, 次の日,複製Bで作業を始めるときにpullし忘れてから作業し始めたとする。 すると,Bでコミットしたものをpushするときに以下のようになる。
hg push
pushing to ssh://labosv/taro/foo
searching for changes
abort: push creates new remote head 38a9b881abe5!
(you should pull and merge or use push -f to force)
先にAでの更新を取り込んでおくべきだった。この場合はあとで Aの更新を取り込み,マージする。
hg pull -uv pulling from ssh://labosv/taro/foo searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge)
このようにしたら hg merge
でマージ(修正の併合)を行なう。
hg merge 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit)
don't forget とあるように,コミットを忘れず行なう。
hg ci -m merged
マージすべきときに,同じ箇所に違う修正を施していると衝突が起こる。
hg merge merging hello.c merge: warning: conflicts during merge merging hello.c failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon hg resolve -l # 衝突ファイル一覧を得る U hello.c
ファイルを開くと衝突箇所に `<<<<<<<
'
というマークが付く。2つの修正候補のどちらかを残して他を消す。
int main(int argc, char **argv) { <<<<<<< /tmp/mh2/hello.c printf("HELLO, WORLD!\n"); ======= printf("Hello, world!\n"); >>>>>>> /tmp/hello.c~other.WW1aE0 return 0; }
ここでは下(赤)の方を選んだとして,
int main(int argc, char **argv) { printf("Hello, world!\n"); return 0; }
のように修正し,修正済みマークを `hg resolve -m
'
で付け,コミットする。
hg resolve -m hello.c hg resolve -l R hello.c hg ci -m Resolved
リモートサーバへの接続時のパスフレーズ入力を代理で済ませてくれる
ソフトウェア ssh-agent を使うと頻繁なpush/pullが楽になる。
~/.ssh/id_rsa
ファイルを用意し終えた状態で,仮想端末から
ssh-add を起動し,以下のようなパスフレーズ入力プロンプトが出たら
既に ssh-agent が常駐している。
ssh-add
Enter passphrase for /home/taro/.ssh/id_rsa
このままパスフレーズを入れておけば,次回の公開鍵認証の パスフレーズ入力が省略される。
ssh-add で無反応の場合は,別途 ssh-agent を起動する必要がある。 エージェントを利用する仮想端末をひとつ決めてそこで以下のように操作する。
ssh-agent $SHELL ssh-add emacs &
上記のように,編集作業などはこのシェルから起動したemacsを用いる。
リポジトリ管理しているファイルの,コピー/移動/削除は cp/mv/rm で行なってはいけない。リポジトリの登録情報とずれるからである。 これらは全てhgのサブコマンド cp/mv/rm で行なう。
hg cp |
履歴を含めてファイルをコピーする。ディレクトリをまるごとコピーする こともできる。 |
hg mv |
履歴ごとファイルを移動する,またはリネームする。 ディレクトリをまるごと移動することもできる。 |
hg rm |
リポジトリ内ファイルと作業ディレクトリのファイルを両方削除する。 ディレクトリごと削除することもできる。 |
hg log | less
してみると,全ての履歴に
日付けとチェンジセットIDが付いているのが分かる。
このIDでリビジョン指定ができ,その時点の状態を特定できる。
たとえば,2013年2月2日の時点のファイルを取り出したいとする。 眺めたいだけ,1つだけファイルを取り出したい,全てのファイル集合を見たい, 場合によって切り替える。以下,REV というリビジョンの ファイルの取り出し方について示す。
hg cat -r REV ファイル | less
などとする。
あるいは,Emacsで見たいファイルを開き C-x v g (vc-annotate) を呼び,p や n や j で任意のリビジョンを表示させる。
hg cat -r REV ファイル >
出力先ファイル
などとする。
hg archive を使う。
hg archive -r REV 出力ディレクトリ
このようにすると,「出力ディレクトリ」に そのリビジョンの時点のファイル一覧が書き出される。
# リビジョン321の集合を /tmp/hogehoge-1.2.3 ディレクトリに作成 hg archive -r 321 /tmp/hogehoge-1.2.3 # リビジョン321の集合を /tmp/hogehoge-1.2.3.tar.gz ファイルに作成 hg archive -t tgz -r 321 /tmp/hogehoge-1.2.3.tar.gz
あとから取り出すであろうリビジョンにはタグ をつけられる。
# 現在のワーキングリビジョンに hogehoge-1 というタグをつける hg tag hogehoge-1 # リビジョン321に hogehoge-0.5 というタグをつける hg tag -r 321 hogehoge-0.5
タグをつけたリビジョンは,タグ名でアクセスできる。たとえば,
hg cat -r hogehoge-0.5 hg archive -r hogehoge-0.5 /tmp/hogehoge-0.5
コマンド | はたらき |
---|---|
hg status | リポジトリの状態表示 |
hg clone |
hg clone URL1 URL2
で URL1 のリポジトリを URL2 に複製する。 URLにはリポジトリを示すディレクトリや, ssh://サーバ/ディレクトリ 形式が指定可能。 |
hg pull |
複製元リポジトリの更新を取得する。後ろにリポジトリURLを 指定して別のリポジトリからの取得も可能。 |
hg push |
複製元リポジトリへ更新を送り込む。後ろにURLを指定可。 |
hg update |
リポジトリにある更新を作業ディレクトリに適用する。 |
hg merge |
2つの更新をマージする。 |
hg resolve |
マージで生じた衝突を解決する。
-l 衝突ファイル一覧
|
hg add |
指定したファイルを新たにリポジトリに登録 |
hg log |
更新履歴とログを出力 |
hg diff |
リポジトリ登録版との差分出力 hg diff -r REV [ファイル] とすると,リビジョン REV との差分を出力する。 REV1 : REV2
とすると,REV1 から
REV2 への差分を出力する。
|
hg revert [file] |
最後のコミット以後の修正を破棄して元に戻す。hg revert -a で全てのファイルを戻す。 |
キー | はたらき |
---|---|
C-x v v | コミット |
C-x v l | ログを見る |
C-x v = | 差分を見る C-u C-x v = として,2つのリビジョンを指定すると それらの差分を見られる。 |
C-x v g | hg annotate を行なう どの行をどのリビジョンで採り入れたかを視覚的に調べられる |
C-c h < | hg pull を行なう |
C-c h > | hg push を行なう |
C-c h c | 複数ファイルをまとめてコミット |
C-c h s | hg status を行なう |
キー | はたらき |
---|---|
n | 次(下)のログへ |
p | 前(上)のログへ |
d | そのチェンジセットの差分表示 |
a | そのリビジョンで annotate 表示 |
vc-annotate は,タイムマシンのように目の前に以前のリビジョンの 内容がどんどん現われるので,昔のリビジョンをじっくり参照したいときに便利。
キー | はたらき |
---|---|
p | 古いリビジョンへ |
n | 新しいリビジョンへ |
j | カーソル行のリビジョンへ |
a | カーソル行のリビジョンの直前リビジョンへ |
w | ワーキング(作業中)リビジョンへ |
v | 冗長表示切り替え |
d | 該当リビジョンの差分表示 |
l | 該当リビジョンのログ表示 |