svn その3 課題リストを消化するんご

■検証環境

・svn server

CentOS6.9、192.168.2.26、プロンプト:せ6>、リポジトリのパス:/var/svn/repos/project

svnサーバ起動

せ6> service svnserve start

・svn client A

CentOS7.3、192.168.2.7、プロンプト:せ7>、リポジトリのパス:/svn/project

・svn client B

OpenSuSE11.4、192.168.2.11、プロンプト:すぜ>、リポジトリのパス:/svn/project

 

■検証

1.同一ファイルの同時編集

【ポイント】

・リポジトリサーバではどうなるのか?

・ローカルリポジトリaではどうなるか?

・ローカルリポジトリbではどうなるか?

・上記が行われた後、bは作法上どうするのか?

・リポジトリサーバから見たリポジトリサーバ上とローカル上のリビジョン

・ツールとして使うsvnコマンド

 svn info                     svn情報表示

 svn info 「ディレクトリ」 ディレクトリ指定                    

 svn st                       ステータス表示 (表1参照)

 svn ls                        svnサーバのファイル一覧表示

 svn ls -v                    詳細表示(-v)

 svn ls 「ディレクトリ」    ディレクトリ指定                   

 svn log -l 10 -v     最新10件表示(-l 10)、変更のあったファイルも表示(-v)

 svn diff                      差分

 svn diff -r r26:r27        リビジョン間の差分

 svn diff -r r26:r27 「ファイル|ディレクトリ」  特定パスのリビジョン間の差分

 

表1    svn status の記号の意味

記号 意味
' ' 変更なし
A 追加されたファイル
D 削除されたファイル
M 修正されたファイル
C 競合しているファイル
I 無視されているファイル
? 管理下にないファイル
! 失われたファイル
+ コミット準備完了のファイル

【検証1-0】 aがaの変更箇所を確認する方法

【仕込み】 2つのクライアントの作業ディレクトリにおけるコンフリクト状態の作成

・svnサーバ側の設定

せ6> cat /var/svn/repos/project/conf/passwd
[users]
suse = dagyah                          # suse用ユーザ名とパスワード
centos7 = dagyah                     # centos7用ユーザ名とパスワード

せ6> service svnserve restart

・適当な大きさのファイルを両クライアントで同時編集してコンフリクトさせる

すぜ> cat -n /svn/project/trunk/passwd
・・・前略・・・
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  add by suse           ←suse側で加えた変更
     6  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
・・・後略・・・

せ7> cat -n /svn/project/trunk/passwd
・・・前略・・・ 
    19  postfix:x:89:89::/var/spool/postfix:/sbin/nologin
    20  add by centos7         ←CentOS7側で加えた変更
    21  sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

・・・後略・・・

・一方でファイルを作成してコミットして両方でアップデート後、一方で左記ファイルを編集し、もう一方で左記ファイルを削除してコンフリクトさせる

・一方でディレクトリを作成してディレクトリ配下にファイルを作成して両方でアップデート後、一方でディレクトリからファイルを一つ上の階層に移動して移動したファイルをsvn addしてコンフリクトさせる

・その他にもいろんなファイルを作成して双方で編集したり削除したり、双方でcommitしたりしなかったりさせて、双方のsvnクライアントの作業ディレクトリ(ローカルリポジトリ)の状態をいい具合に乱雑にしてみた

 

【検証1-0-0】 svnサーバのリポジトリを直接見る

すぜ> svn ls svn://192.168.2.26/var/svn/repos/project/trunk
README
fuga/
hoge
piyo/

すぜ> svn ls -v svn://192.168.2.26/var/svn/repos/project/trunk
     29 centos7               May 02 09:00 ./
     23 dagyah            294 May 02 06:50 README
     24 dagyah                May 02 07:17 fuga/
     22 dagyah             21 May 02 06:46 hoge
     26 dagyah                May 02 07:26 piyo/

※ svnサーバ上では「/var/svn/repos/project/」までがファイルシステム上の実ディレクトリで、「trunk」はDB上の論理的なディレクトリ

すぜ> svn ls -v svn://192.168.2.26/var/svn/repos/project/trunk/piyo
     26 dagyah                May 02 07:26 ./
     25 dagyah              5 May 02 07:21 piyo.data
     26 dagyah              5 May 02 07:26 piyo.txt

すぜ> svn ls -v svn://192.168.2.26/var/svn/repos/project/trunk/fuga
     26 dagyah                May 02 07:26 ./
     25 dagyah              5 May 02 07:21 piyo.data
     26 dagyah              5 May 02 07:26 piyo.txt

すぜ> svn ls -v svn://192.168.2.26/var/svn/repos/project/trunk/README
     23 dagyah            294 May 02 06:50 README
すぜ> svn cat svn://192.168.2.26/var/svn/repos/project/trunk/README
これは初期データです
suseで一行追加
suseで2行目追加
c7で3行目追加
suseで4行目追記
suseで5行目追記
c7で6行目追記
suseで7行目追記
c7で8
unko 20180430
20180502 19:36 edited by CentOS7
2018年 5月 2日 水曜日 19:49:23 JST edite by CentOS7
chiko

 

【検証1-0-0.1】 クライアント(suse)のローカルリポジトリを見る

すぜ> pwd
/svn/project/trunk

すぜ> ls -lA
total 32
drwxr-xr-x 6 root root 4096 May  2 10:48 .svn
-rw-r--r-- 1 root root    2 Feb 25 10:45 a
-rw-r--r-- 1 root root  154 Feb 25 10:46 a.zip
drwxr-xr-x 3 root root 4096 May  2 08:35 fuga
drwxr-xr-x 3 root root 4096 May  2 10:46 piyo
-rw-r--r-- 1 root root    5 May  2 08:54 piyo.data
-rw-r--r-- 1 root root  109 May  2 08:16 svn-commit.2.tmp
-rw-r--r-- 1 root root  110 May  2 08:14 svn-commit.tmp

すぜ> svn ls
README
fuga/
hoge
piyo/

すぜ> svn ls -v
     29 centos7               May 02 09:00 ./
     23 dagyah            294 May 02 06:50 README
     24 dagyah                May 02 07:17 fuga/
     22 dagyah             21 May 02 06:46 hoge
     26 dagyah                May 02 07:26 piyo/

すぜ> svn st
?       a                     ←これらはsvnサーバには登録されてないやつら
?       a.zip
?       svn-commit.tmp
?       svn-commit.2.tmp

!     C passwd                ←こいつはsuseでsvn delして消したファイルでコンフリクトが起こってる
      >   local delete, incoming delete upon update
!       piyo/piyo.data            ←こいつはsuseで一つ上の階層に移動してsvn addしてコンフリクトが起こってる
D     C hoge                                    ←こいつはsuseでsvn delして消したディレクトリでコンフリクトが起こっている
      >   local delete, incoming edit upon update   ←さらにsuseでcommitする前にcentos7で編集して先にcommitしてる

A       piyo.data              ←こいつはsuseで一つ上の階層に移動してsvn addしたのでここにいる
D     C README             ←こいつもsuseでsvn delして消したファイルでコンフリクトがおこっている
      >   local delete, incoming edit upon update

すぜ> svn st -v
                29       29 centos7      .
?                                        a
?                                        a.zip
?                                        svn-commit.tmp
?                                        svn-commit.2.tmp
!     C                                  passwd
      >   local delete, incoming delete upon update
                29       26 dagyah       piyo     ←は作業コピーの最終リビジョンではsvnサーバにあるリビジョン
!               29       25 dagyah       piyo/piyo.data
                29       26 dagyah       piyo/piyo.txt
D     C         29       22 dagyah       hoge
      >   local delete, incoming edit upon update
                29       24 dagyah       fuga
                29       24 dagyah       fuga/fuga.txt
A                0       ?   ?           piyo.data   ←svn addはしたけどまだcommitしてないので作業コピーのリビジョンは0でsvnサーバには無い
D     C         22       16 dagyah       README      
      >   local delete, incoming edit upon update

すぜ> svn info
Path: .
URL: svn://192.168.2.26/var/svn/repos/project/trunk
Repository Root: svn://192.168.2.26/var/svn/repos/project
Repository UUID: e112b0dd-4d9d-45c6-b232-96d9d69c4d33
Revision: 29
Node Kind: directory
Schedule: normal
Last Changed Author: centos7
Last Changed Rev: 29
Last Changed Date: 2018-05-02 09:00:44 -0400 (Wed, 02 May 2018)

すぜ> svn log -l 1 -v
------------------------------------------------------------------------
r29 | centos7 | 2018-05-02 09:00:44 -0400 (Wed, 02 May 2018) | 1 line
Changed paths:
   D /trunk/passwd

------------------------------------------------------------------------

すぜ> svn diff
Index: hoge
===================================================================
--- hoge        (revision 29)
+++ hoge        (working copy)
@@ -1,3 +0,0 @@
-this is hoge
-aaa
-bbb
Index: piyo.data
===================================================================
--- piyo.data   (revision 0)
+++ piyo.data   (revision 0)
@@ -0,0 +1 @@
+unko
Index: README
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

すぜ> svn diff -r r27:r28
Index: passwd
===================================================================
--- passwd      (revision 27)
+++ passwd      (revision 28)
@@ -17,6 +17,7 @@
 polkitd:x:998:996:User for polkitd:/:/sbin/nologin
 tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
+add by centos7
 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
 chrony:x:997:995::/var/lib/chrony:/sbin/nologin
 dagyah:x:1000:1000:dagyah:/home/dagyah:/bin/bash

 

【検証1-0-0.2】 クライアント(suse)のローカルリポジトリを見る

せ7> pwd
/svn/project/trunk
せ7> ls -lA
合計 8
-rw-r--r--. 1 root root 294  5月  2 21:08 README
drwxr-xr-x. 2 root root  22  5月  2 21:37 fuga
-rw-r--r--. 1 root root  21  5月  2 21:05 hoge
drwxr-xr-x. 2 root root  39  5月  2 21:43 piyo

せ7> svn ls
README
fuga/
hoge
passwd
piyo/

せ7> svn ls -v
     28 dagyah                 5月 02 20:53 ./
     23 dagyah            294  5月 02 19:50 README
     24 dagyah                 5月 02 20:17 fuga/
     22 dagyah             21  5月 02 19:46 hoge
     28 dagyah           1598  5月 02 20:53 passwd
     26 dagyah                 5月 02 20:26 piyo/

せ7> svn st
せ7> svn st -v

                28       28 dagyah       .
                28       23 dagyah       README
                28       24 dagyah       fuga
                28       24 dagyah       fuga/fuga.txt
                28       22 dagyah       hoge
                28       26 dagyah       piyo
                28       25 dagyah       piyo/piyo.data
                28       26 dagyah       piyo/piyo.txt

せ7> svn info
パス: .
Working Copy Root Path: /svn/project
URL: svn://192.168.2.26/var/svn/repos/project/trunk
リポジトリのルート: svn://192.168.2.26/var/svn/repos/project
リポジトリ UUID: e112b0dd-4d9d-45c6-b232-96d9d69c4d33
リビジョン: 28
ノード種別: ディレクトリ
準備中の処理: 特になし
最終変更者: dagyah
最終変更リビジョン: 28
最終変更日時: 2018-05-02 20:53:02 +0900 (水, 02  5月 2018)

 

【検証1-0-1】 差分の確認方法

svn diff

または、

svn diff -r r27:r28

※上記参照

 

【検証1-0-2】 リビジョンを指定した確認方法

すぜ> pwd
/svn/project/trunk

すぜ> svn copy -r 22 README README_22

すぜ> svn copy -r 22 README README_23

すぜ> ll
total 40
drwxr-xr-x 6 root root 4096 May  3 03:03 .svn
-rw-r--r-- 1 root root  287 May  3 03:02 README_22
-rw-r--r-- 1 root root  294 May  3 03:03 README_23
-rw-r--r-- 1 root root    2 Feb 26 00:45 a
-rw-r--r-- 1 root root  154 Feb 26 00:46 a.zip
drwxr-xr-x 3 root root 4096 May  2 21:35 fuga
drwxr-xr-x 3 root root 4096 May  2 23:46 piyo
-rw-r--r-- 1 root root    5 May  2 21:54 piyo.data
-rw-r--r-- 1 root root  109 May  2 21:16 svn-commit.2.tmp
-rw-r--r-- 1 root root  110 May  2 21:14 svn-commit.tmp

すぜ> diff README_22 README_23
12a13,14
> chiko
>

これで一応ほしいリビジョンのファイルをコピーできるが・・・

あと、対象ファイルの変更履歴はsvn logで調べられる

すぜ> svn log -v | less

で検索して該当ファイルの欲しいリビジョンを特定して上記の方法でリビジョンを指定したファイルを取得できる

【検証1-0.5】 aがbの変更箇所を確認する方法

【検証1-0.5-1】 差分の確認方法

→svn log -vでリビジョンを特定して、svn copy -r リビジョン番号でファイル取得してdiff

または、

→ svn diff -r r26:r27 ファイル名 で直接diffを取る

 

【検証1-0.5-2】 リビジョンを指定した確認方法

→上記参照

 

【検証1-1】 aがbの変更を破棄してaの編集を採用 

【検証1-1-1】 リビジョンを指定したbの変更の破棄

→できない?

【検証1-2】 aがaの変更を破棄してbの編集を採用

【検証1-2-1】 リビジョンを指定したrevert

→?

とりあえず、やらかした変更を取り消すなら

svn revert ファイル名 でOK

その後、いかようにも変更を反映できる

【検証1-3】 aがaのローカルリポジトリ上で、aとbの変更ををどっちも破棄したものを採用

※bがcommitしでリポジトリサーバ上ではリビジョンがnに上がったあと、aがcommitしようとしたらコンフリクトが判明したので、bの変更のうちaとコンフリクトしてないファイル(ディレクトリ)だけをとりあえずコミットしなおして、これのリビジョンをnにして、その後、aがaとbのコンフリクトしてるファイル(ディレクトリ)のみを編集したものをリビジョンn+1にする
 
【検証1-4】 ファイル削除とコンフリクトおよびコンフリクトの解消

【検証1-4-1】 svn delコマンドで削除(コンフリクトが無い場合)→

→svn delする前にファイルをローカルにコピーするかbranchにコピーしてからsvn upして間髪入れずにsvn delしてここでも間髪入れずにsvn ciすればsvn delしたことがコンフリクトにならない。別のクライアントでもし同じファイルを編集中だった場合は、svn upした瞬間に編集したファイルが消えちゃうけど。そういうことにならないように、svn upする前に作業コピーをローカルかbranchにコピーしてからsvn upしてすぐsvn ciすればOK
 

【検証1-4-2】 svn delコマンドで削除(コンフリクトがある場合)してコンフリクトを解消してファイル削除をsvnリサーバ全体で確定する

→svn delしたクライアント側では、コンフリクト状態はsvn revertすることで解消できる。

他の方法は知らない・・・

svn delしてない方のクライアント側では、コンフリクトと表示されない。

なのでsvn delした方のクライアントで、とりあえずsvn revertしてコンフリクト状態を解消してから、新しく作るなりsvnサーバでバージョン管理対象だったならsvn updateかsvn copyでもしてとってくる

 

【検証1-4-3】 rmコマンドでファイルを削除してしまった場合

→削除したクライアントで svn update したら削除前の状態に戻る

 
【検証1-5】 ディレクトリ作成とコンフリクトおよびコンフリクト解消
【検証1-5-1】 ディレクトリとファイルを同時に作成してsvn addしてsvn ci 

 
【検証1-6】 ディレクトリ削除とコンフリクトおよびコンフリクト解消 
【検証1-6-1】 svn delコマンドで削除(コンフリクトが無い場合)

 

【検証1-6-2】 svn delコマンドで削除(コンフリクトがある場合)してコンフリクトを解消してディレクトリおよびディレクトリ配下のファイル削除をsvnリサーバ全体で確定する

 

【検証1-6-3】 rm -rfコマンドでファイルを削除してしまった場合

→削除したクライアントで svn update したら削除前の状態に戻る

 
【検証1-7】 複数のクライアントで複数のコンフリクトが入り乱れてしっちゃかめっちゃかな場合の解消方法
※複数のファイルやディレクトリで、作成、削除、および変更が複数のクライアントで相互にコンフリクトしていて複数のクライアントのローカルリポジトリがしっちゃかめっちゃかな状態になっているとき、コンフリクト箇所を確認して、解消してすべてのクライアントおよびサーバのリポジトリを正常な状態にするためのアプローチ
 

【検証1-7-1】 一方のクライアントだけからすべてのコンフリクトを調べ上げて解消する

 

【検証1-7-2】 svnサーバにログインしてsvnサーバから「あるべき状態」に修正して、すべてのクライアントのローカルリポジトリを一斉に強制的に同期させることはできるか?

※多分そんなことはできないと思うけど・・・

 

【検証1-7-3】 一旦ローカルリポジトリをすべて削除してチェックアウトしなおす

 

【複数で同じtrunkを共同編集する場合の作法(案)】

・作業コピー(ローカルリポジトリ)を編集する前にファイルをローカルかbranchにコピーする。

・間髪入れずにsvn upする

 ※自分が編集中の作業コピー上のファイルを別の人が変更していたり、svn delで削除して

  いた場合、編集中のファイルsvn upすることで自分の編集部分やファイル自体が削除され

  てしまう。

・trunkの作業コピーを編集する

・svn ciする

・もし、自分が編集中に別の人が別のファイルを編集したあとコミットしていたら、「・・・はリポジトリ側と比べて古くなっています」と怒られてコミットできない。

この場合は、自分が編集したファイルをコミットせずにローカルコピーかbranchにコピーしておいて、rmコマンドで編集したファイルを削除してsvn upする。

そうすると、リポジトリ上の最新リビジョン(つまり別の人がコミットした最新のリビジョン)が作業コピーに現れるので、事前にバックアップしておいたファイルと最新リビジョンをmergeする。

・もし、自分がsvn delした後、別の人がファイルを編集してコミットしていたら、一旦自分のsvn delをsvn revertしてから、svn up 「ファイル名」もしくは、svn copy -r 「リビジョン番号」で他者が編集を終えてコミットしたファイルのリビジョンを作業コピーに取得して直接開くなり、svn diffで変更箇所を調べて、他人の変更箇所を特定して、他者の変更と自分の削除のどっちが正しいか判断したうえで、最終変更者にことわってもう一度svn delしてsvn ciするか、他の人のコミットを採用する。

・もし自分が編集したファイルをコミットする前に同じファイルを他の人がコミットしてしまった場合で、さらに自分が編集したファイルを削除しなかった場合、もしくは同名のファイルを再度作成してsvn addしている場合は、svn addしようとしたら、コンフリクトだと怒られる。

この場合は、下記のように出力される

せ7> svn up
Updating '.':
'/svn/project/trunk/passwd2' で競合が見つかりました。
選択: 延期 (p), 全差分 (df), 編集 (e), 衝突自分 (mc), 衝突他人 (tc), すべてのオプションを表示 (s):

ここで、「df」と入力すると、自分の変更と他者の変更の差分が出力される。
また、ここで「p」と入力すると、自分のコミットが延期されて、作業コピーに下記のようなファイルが現れる

ファイル名.r最新リビジョン番号 ※他の人がコミットしたリポジトリ上の最新リビジョン

ファイル名.r変更前リビジョン番号 ※自分が変更を加える元になったリビジョン

ファイル名.mine   ※自分が変更してコミットに失敗したファイル

なお、上記はコンフリクトを解消してコミットした時点で自動的に削除される。
一番簡単なのは、マージしたファイルを別名で作って、作業コピーからコンフリクトしているファイルを一旦rmで削除してsvn updateしてから変更箇所を作業コピーに反映してsvn ciする。
・複数のファイルを編集してそのうちのいくつかが他の人に編集されて先にコミットされていた場合は、svn ciしたときに、どのファイルがコンフリクトを起こしているかは「M」の記号がついて出力されるのでわかるから、コンフリクトを起こしているファイルだけを
svn ci -m "メッセージ" 「ファイル名1」 「ファイル名2」 ・・・
のように、ファイル名を指定して部分的にコミットしておいて、コンフリクトを起こしてるファイルだけ、別途上記の方法で手動でマージする。