ラベル subversion の投稿を表示しています。 すべての投稿を表示
ラベル subversion の投稿を表示しています。 すべての投稿を表示

2009年4月11日土曜日

subversion - 変更の取り消し

コードの変更を取り消したい時はたぶん今後あると思う。
その時には、どうしたらいいのかなんてのは絶対に覚えておく必要はあるよね。

大きくわけて、コミット前とコミット後があるよね。
コミット前ならローカルの修正を元に戻せばいいけど、コミット後だと焦るよね。

1. コミット前
 ローカルの変更の削除
> svn revert

2. コミット後
最初に必要なのは、更新を実行して、リポジトリとの同期を確保する事。
 > svn update

続いて、変更結果を取り消すべきリビジョンを性格に特定する。
 これには、svn log と、svn diff が役に立つ。

 > svn log Contacts.java
> svn diff -r 26:27 Contacts.java

変更を元に戻すには、
> svn merge -r 27:26 Contacts.java .

この場合だと、r27の修正を取り消す様な指示をしている。

day.txt
r28: 中身を空っぽにする
data.txt
r29: 一番上を削除する

day.txtの修正を元に戻す

> svn merge -r 28:27 Day.txt .
> svn commit -m "z"

ここでのDay.txtの中身は?
 データが入ってれば、修正の取り消しが出来ている。
 データが入ってなければ、修正の取り消しが失敗している。
 データが入っていて、Data.txtの修正が消えていたら失敗

svn update -r[n]
r28の時点では、Day.txtの中身は確かにからっぽ

svn update
HEADに更新をかけると、Day.txtの中身が元に戻った。

subversion -履歴

*履歴
リポジトリから履歴を調べたい場合は、以下のようにできる。
> svn log Number.txt
> svn log sesame | more
> svn log -r 19:24 Clock.java
> svn log -r 24 -v Clock.java

前にも書いたけど、svn update を忘れない様に。
じゃないと、あれ?最新版がログに出て来ないとかに成りかねないし。
確認するには、svn status -v や, svn status -u とかで確認をしておくのがベター

*犯人探しのお供に

一行単位での履歴も実は追う事ができたりする。

> svn blame Number.txt
 ファイルの中身の一行一行で、どのリビジョンで更新されたか、誰が行ったかなんてのが、
 一目瞭然でわかったりする。

オプションなしの場合
> svn blame Number.txt
5 asdf ZERO
7 asdf ichi
7 asdf due
1 asdf three
1 asdf four
3 asdf five
4 asdf SIX
9 asdf Seven
11 asdf eight
11 addf

饒舌にさせた場合
> svn blame Number.txt -v
5 asdf 2009-04-11 13:38:45 +0900 (土, 11 4 2009) ZERO
7 asdf 2009-04-11 13:44:20 +0900 (土, 11 4 2009) ichi
7 asdf 2009-04-11 13:44:20 +0900 (土, 11 4 2009) due
1 asdf 2009-04-11 13:27:24 +0900 (土, 11 4 2009) three
1 asdf 2009-04-11 13:27:24 +0900 (土, 11 4 2009) four
3 asdf 2009-04-11 13:35:00 +0900 (土, 11 4 2009) five
4 asdf 2009-04-11 13:37:24 +0900 (土, 11 4 2009) SIX
9 asdf 2009-04-11 16:54:59 +0900 (土, 11 4 2009) Seven
11 asdf 2009-04-11 17:01:07 +0900 (土, 11 4 2009) eight
11 asdf 2009-04-11 17:01:07 +0900 (土, 11 4 2009)

変更がないリビジョンを指定した場合
> svn blame -r 20:24 Number.txt -v
- - - ZERO
- - - ichi
- - - due
- - - three
- - - four
- - - five
- - - SIX
- - - Seven
- - - eight
- - -

subversion - 変更のコミット

変更をする際に、ひとまとめで実施したほうがいいコマンド群
ここらへんぐらいは、一括で出来る様になったら便利だろうに。

> svn update
> # ... 競合を解消する ...
> # ... テストを実行する ...
> svn commit -m "check in message"

 他の開発者の作業内容がマージされるんで、ここで自分のコードのテストが実施できる効果は、
 かなり大きいと思われる。

 といっても、単体テストでいいとは思うんだけど、作成を楽にできないもんかなー。

subversion - 競合の解消方法

* 競合の解消方法
 自分の担当分を修正をして、svn updateをした後にConflictedが出た場合の修正方法を
 知っておくのは必須だろ。常識的に考えて。

 # コーディングスタイルの違いで、Conflicted するのはアホ臭いので除外。

競合状態のファイルがある場合は、コミットができなくなるので、
 ログが長いから気付かなかったとかの言い訳は意味がない。

 競合が発生する場合の多くは、コミュニケーションエラーが多発することに起因するため、
 どっちかっていうと、ポストモーテムでもしたほうがいいときが多い。

 自分ので修正を上書きして、他のメンバーの作業を台無しにするのはおすすめしない。
 
0. svn commit を実施、なんか競合しているぞ!とエラーが返される。
  そしたら、svn update を実施すると、競合状態のファイルが生成される。

 こうなった後の選択肢はあんまりないので、ここに列挙してみる。

1.自分の変更を破棄して、リポジトリのバージョンを使う事を決めた!
> svn revert Number.txt
> svn update Number.txt
svn revert を実施した時点で、競合ファイルは消えるので、
 白旗あげたらシステムがうまくやった感じ。

2.自分の変更を保持して、リポジトリの修正を上書きする事に決めた!
 > cp Number.txt.mine Number.txt (自分の作業内容で、ファイルを上書き)
> svn resolved Number.txt
> svn commit -m "[check in messages]"

3.手動でファイルを修正して、マーカの部分を削除する事に決めた!
> edit Number.txt
> svn resolved Number.txt
> svn commit -m "[check in messages]"

subversion - コマンド編

* チェックアウト
> svn checkout svn://olio/sesame/trunk
 この例だとチェックアウト元のディレクトリ名になってしまう。
 ディレクトリ名を変更したい場合は、もう一つ引数を与えてあげるといい。

> svn checkout svn://olio/sesame/trunk sesame
 これで、最新のリビジョンが、sesameディレクトリにチェックアウトされる。

過去のリビジョンを指定してチェックアウトをしたい場合は、もう1つ引数を与えるといい。
> svn checkout -r 7 svn://olio/sesame/trunk old-sesame

作業コピーのチェックアウト元を調べたい場合は、svn info が使える。
Repository Rootってのが二行目ぐらいにあって、それがどこからコピーされたものかがわかる。

* 最新状態の維持
 作業を進めているうちに別の開発者がリポジトリを普通に更新されていく。
 そのときには、比較的短い期間で更新をしていったほうが競合の可能性が少ないので、
 結果的に手間が少なくなる。通常一時間程度で更新を続けるのが望ましい。

 svn updateを使うと、そのディレクトリ以下にあるすべてのファイルが再帰的に更新されて、
 リポジトリと同期される。

 その結果、リポジトリに追加されたファイルとディレクトリは作業コピーに追加される。
 逆に、リポジトリから削除されたファイルとディレクトリは作業コピーからも削除される。

 一部だけ同期を取りたい場合は、svn update の後ろに指定してあげるのも可能だ。
 でも、他のファイル群と一貫性が一時的に保たれなくなるので、注意も必要になる。

> svn update build.xml src/ test/

> 誰かがコミットした時に電子メールが関係者に配信されるように設定もできる
http://svn.haxx.se/users/archive-2006-05/att-0593/SVN-Apache-SVNNotify-HowTo-En.pdf
CPANのモジュールを使うのが一番簡単?それとも, post-commitに仕込みを入れるのがいいのかも。

* 変更の読み方
 A:リポジトリに追加されたファイルを作業コピーに追加された事を示す
 U:作業コピーがリポジトリの更新されたファイルで更新されたことを示す
 D:既にリポジトリから削除されていたので、ローカルファイルも削除されたことを示す
 G:作業コピーのローカルで変更されたファイルにリポジトリの更新が反映されてマージしたことを示す
 C:ローカルで変更済みのファイルがリポジトリのファイルとマージしようとそして失敗した事を示す
  ユーザが修正するまでは、チェックインができなくなる。

ついでに、変更をsubversionが出力する時には、二行出力している。
それは何かと聞かれれば、ファイル本体とファイル属性についてです。

* ファイルとディレクトリの追加
> svn add timelib
とかをすると、ユーザがリポジトリにファイルかディレクトリを追加するように指示できる。
 このときの処理としては、追加予約をしただけであって、実際にはまだ処理が実行されない事に注意。

 実際にリポジトリを修正したい場合は、svn commit を忘れずにすること。

* 属性
 ファイルに属性を付けたい場合は、以下のようにする。
 コードに、Reviewerの名前が付くのもいや感じもするけどなぁ。
 > svn propset checked-by "Mike Mason" Number.txt

subversionで予約済みの属性ってのもいくつかあって、そういう属性はsvn:という
 プレフィックスが付いている。

 複数の行を修正したい場合は、以下の様に
> svn propedit checked-by Number.txt

 属性の一覧を表示するには、以下の様に
> svn proplist Number.txt

 属性の値の取り出しをしたい場合は、以下の様に
> svn propget checked-by Number.txt

 属性の削除をしたい場合は、以下の様に
> svn propdel Number.txt

* 管理対象外としたい場合の指定の方法
 ディレクトリに対して属性を指定すればok
 '.'を指定すると、vimがエラーを返したので上位ディレクトリで、
 > svn propedit sesame としたほうがいいのかも。
 結果の出力をよく見ないとアレ?ということになりかねない。

svn:ignore の属性とかは、コミットされると他のユーザにも影響を与える。
 ついでに補足で、下位ディレクトリまで再帰的には処理を行わない。

* 属性の自動設定
 自動設定は、サーバ側の設定と思われがちだが、実はクライアント側の設定だったりする。
 # 設計ミスってんじゃねーのか、これ。
 んで、ユーザごとに .subversion/config とかファイルがあるんで、その中のエントリにある項目を
 各自修正しないといけない、と。

* ファイルとディレクトリのコピーと移動
 > svn copy Number.txt Data.txt

Changed paths:
A /sesame/trunk/Data.txt (from /sesame/trunk/Number.txt:17)

この場合だと、Numer.txt:17からコピーしてきたことが分かる。

 注1:svn copyやsvn moveは、一度に1つしか指定ができない。
 スクリプトやらシェルの支援機能と組み合わせるのがベター

 注2: svn log のデフォルトだと、あらゆるコピー操作や移動操作とかの前の履歴も全部表示する。
 コピーや移動の後の履歴のみを普通は見たい。
 そう言う場合は、 --stop-on-copy のオプションを指定するといいかも。

 ファイルの名前変更は素直に、svn move を使う方が簡単。
 > svn move Time.java Clock.java

 svn move のログを-v付きで見てみるとオモロいのが、実際には名称変更ってのが、
 コピーして別名で追加処理で、元のファイルの削除をしているだけってこと。

------------------------------------------------------------------------
Changed paths:
A /sesame/trunk/Clock.java (from /sesame/trunk/Time.java:19)
D /sesame/trunk/Time.java

changed file name of Time.java to Clock.java

 ディレクトリについてもファイルと同じファーストクラスの管理対象のオブジェクトなので、
 普通に svn move で、ディレクトリの名称の変更ができる。

subversion - リポジトリへのアクセス

[2009-04-11 18:58] >>> ~/howm/2009/04/2009-04-11-154426.howm

ファイルアクセスの場合は、まぁこんな感じ
svn co file:///home/mike/svn-repos/sesame/trunk sesame

ネットワーク経由に付いてまとめてみる。

その前に、指定するURIについて、構成要素を分解すると、
file:///c:/svn-repos/sesame/trunk

->
 file:// スキーム(アクセス方法の指定)
 /c:/svn-repos/ リポジトリの場所の指定
 sesame/trunk リポジトリ内のパス

* svn(svnserve)
 svnserveを使う方法が一番簡単。
 シンプルなネットワークサーバで、社内で使うのには向いているかも(しれない)
 
 起動方法:
  > svnserve --daemon --root /home/mike/svn-repos

* svn + ssh
 svnserveはパスワードは平文で送受信しないけど、ファイルとかは平文で送ってしまう。
 そのため、盗み見られない様にするためには、SSHを使うのがいいらしい。

* http
 Apacheが必須ってのは正しくないけど、設定の自由度が高いから相性がいいぽい。
 アクセス方法は、こんな感じ。

 svn checkout http://olio.mynetwork.net/svn-repos/sesame/trunk sesame

 

subversion - 基本編

* リポジトリの作成方法
mkdir /home/mike/svn-repos
svnadmin create /home/mike/svn-repos

* プロジェクトの作成方法
svn import -m "importing Sesame project" . file:///home/mike/svn-repos/sesame/trunk

# sesame/trunk は、実際にはまだ作っていないのに、追加できた。

* 作業開始
svn co file:///home/mike/svn-repos/sesame/trunk sesame

# 作業コピーは作業ディレクトリ内のsesameディレクトリにコピーされる
# 作業コピーには、.svnという隠し属性付きの管理ディレクトリが作成される

* subversionがプロジェクトの状態をどう捕らえているか確認する
svn statusは、ローカル環境の状況を表示する
svn status -v 追加情報が出る
svn status -u リポジトリとワークのリポジトリについて情報がでる

ディレクトリ自体がリビジョンNoの管理に入っている

修正やリポジトリと違う場合は、svn statusで出てくる。
この時に、M とか出て来たら、差異があることを示してくれる

# svn update は、ローカルで更新をしているファイルがある場合は
勝手にマージの動きをする?この手順だと修正は消えない。
実際に消したい場合は、revertを使うべきぽい。
svn update は、指定されたリビジョンのデータを拾ってくるだけで、
指定が無ければ、最新版のを拾う動きになる。最新版はHEADで表現できる。
たぶん、タグ名とかでも可能。

* 修正内容の差分の表示方法
svn diff は、ローカル環境とリポジトリとの差分を表示する動きをする.
svn diff -r[n] nに比較をしたいリビジョンNoを入れるとそれとの差分になる
svn diff -r[m]:[n] mからnまでのリビジョンの間の差を表示する

 指定しなければ、ワーキングディレクトリにあるファイル全部が対象
 個別にファイルの指定も可能になっているので、工夫はできる。

* リポジトリの更新方法
svn commit -m "[comment contents]"

commitを実施すると、リポジトリのデータベースが更新をされる。

 ファイルをcommitをして、statusを表示をさせたとする。
 ただ、この時点ではワーキングディレクトリのリビジョンは更新されていない。
 不一致が発生する場合は、svn update でディレクトリのリビジョンを更新しないといけない。
# 手順が分かれているのは理由がありそうだけど、現時点では不明

Number.txtを修正して、commit を実施しただけの時点

svn status -v
7 7 tota .
8 8 tota Number.txt
7 2 tota Day.txt

-------------------------------------------------------
svn update
-------------------------------------------------------
svn status -v
8 8 tota .
8 8 tota Number.txt
8 2 tota Day.txt

* リポジトリの更新の履歴を見る方法
svn log
svn log -v # 追加情報の表示モード
svn log -v -r PREV:HEAD PERV->HEADまでのログを表示する
出力の順番は、引数の与え方で変化する

* 競合の発生したときの確認方法と修正方法
 この状況は、svn commit が衝突した時に発生する。
 基本的には、先勝ちなので修正が遅い人にどのように修正するかの責任が発生する。
 ユーザに通知される時には、コミットが失敗しましたと言われることになる。
 
 解消の手順は以下のようになる。
  まずは、svn update を実施する。
  この時に、ローカルファイルの変更点が、リポジトリのバージョンの変更点とマージされる。
  修正箇所が同じじゃなければね。

 同じ業の場合は、svn update を実施しても、Conflicted だーと言われる事に成る。

 ここの確認方法は、Gがシステムでマージしてくれたことを示して、
 Cがシステムでマージの判断が出来なかった事を表している。

svn resolved PATH...
 このときの修正の方法としては、競合したファイルを開くと、ぶつかった位置にマーカが入っている。
 そこの修正を取捨選択をして、Subversionに競合が解消できましたーと教えてあげるといい。

 ただし、どのファイルの競合が解消できたかの宣言が必要で、
 ディレクトリ丸ごととかの横着はさすがに許してくれない。

 繰り返しの注意点としては、文脈上の解消をしてくれるわけじゃなくて、
 競合マーカをクリアするだけで、マーカとかは取ってくれないからね。

 競合マーカってのは、"<<<<<<" ">>>>>" で囲まれたところのこと
.mineってのが自分の修正した内容の部分で、.r[N]の部分がリポジトリの中の部分

* ファイル単位のリビジョン
 ディレクトリはログ関係もあるから、大体最新版と同じリビジョンNoになる
 ファイルも一つ一つリビジョンを持っていて、修正されたタイミングで更新される。
 ただ、連番に意味はなくて、そのときのディレクトリのリビジョンNoと同じ値に更新される

+ リポジトリへのオプションの設定方法ってどうやるんだろ?
 ログないとコミット禁止とか
 mantisへの指定方法とか