4

私の混乱は、ここから取られた次のステートメントから生じます:

互いに競合するパッチをプルする場合(たとえば、ファイルの同じ部分を変更する場合)、Darcsは競合を検出し、リポジトリコンテンツにマークを付けます。次に、ユーザーが問題を解決できるようにします。

これは私が見ているものと矛盾しているように見えたので、darcs2.5.2を使用して次のワークフローを作成しました。

  1. repofooを作成します。
  2. fooに空でないファイルを作成し、それを記録します。
  3. fooをbarにクローンします。
  4. fooのファイルを削除し、記録します。
  5. バーのファイルに別の行を追加して記録します。
  6. fooからbarにプルし、競合通知を取得します。

これらの手順を実行darcs whatsnewした後、私はバーで実行し、2つの「パッチプリミティブ」が表示されました。

  1. 「fooの空でないファイル」をすべて削除するハンクですが、追加されてバーに記録された行については言及されていません。
  2. ファイルを削除するrmfile。

私の質問は次のとおりです。バーに追加および記録された行についての言及がないのはなぜですか?

バーで実行するdarcs revertと、すべてが理にかなっています。ここから抜粋したこのステートメントのように、競合するパッチの影響を受けていない「空でないファイル」が表示されます。

コマンドdarcsrevertは、競合マークを削除し、競合するパッチの前の状態に戻ります。

しかし、実行するdarcs mark-conflictsと、プル後と同じ状態に戻ります。上記の2つの「パッチプリミティブ」があり、追加されてバーに記録された行についての言及はありません。


参考/複製のために、ここにコマンドラインからの私の完全なワークフローがあります:

$ mkdir foo
$ cd foo/
foo$ darcs initialize

foo$ touch shopping
foo$ vi shopping          <-- add a couple of lines
foo$ darcs add shopping

foo$ darcs record 
addfile ./shopping
Shall I record this change? (1/2)  [ynW...], or ? for more options: y
hunk ./shopping 1
+cake
+pie
Shall I record this change? (2/2)  [ynW...], or ? for more options: y
What is the patch name? Added shopping
Do you want to add a long comment? [yn]n
Finished recording patch 'Added shopping'

foo$ cd ..
$ darcs get foo/ bar
$ cd bar/

bar$ vi shopping    <-- add another line
bar$ darcs record 
hunk ./shopping 2
+beer
Shall I record this change? (1/1)  [ynW...], or ? for more options: y
What is the patch name? Added beer
Do you want to add a long comment? [yn]n
Finished recording patch 'Added beer'

bar$ cd ../foo
foo$ rm shopping 
foo$ darcs record 
hunk ./shopping 1
-cake
-pie
Shall I record this change? (1/2)  [ynW...], or ? for more options: y
rmfile ./shopping
Shall I record this change? (2/2)  [ynW...], or ? for more options: y
What is the patch name? Removed shopping
Do you want to add a long comment? [yn]n
Finished recording patch 'Removed shopping'

foo$ cd ../bar
bar$ darcs pull
Pulling from "../foo"...
Mon Nov 14 19:26:44 GMT 2011  dukedave@gmail.com
  * Removed shopping
Shall I pull this patch? (1/1)  [ynW...], or ? for more options: y
Backing up ./shopping(-darcs-backup0)
We have conflicts in the following files:
./shopping
Finished pulling and applying.

bar$ darcs whatsnew 
hunk ./shopping 1
-cake
-pie
rmfile ./shopping
4

1 に答える 1

7

bar 内で実行するdarcs changes -vと、競合するパッチをプルした結果として導入された競合者を含む、変更の履歴が表示されます。

私はあなたの例を少し短いものに要約しました:

DARCS=/usr/bin/darcs

$DARCS init --repo foo
cd foo

echo 'a' > myfile
$DARCS add myfile && $DARCS record -am 'Add myfile'

$DARCS get . ../bar

rm myfile
$DARCS record -am 'Remove myfile'

cd ../bar

echo 'b' >> myfile
$DARCS record -am 'Change myfile'

$DARCS pull -a ../foo

$DARCS changes -v

その後、次の出力が表示されますdarcs changes -v

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Remove myfile
    conflictor [
    hunk ./myfile 2
    +b
    ]
    |:
    hunk ./myfile 1
    -a
    conflictor {{
    |:
    hunk ./myfile 2
    +b
    |:
    hunk ./myfile 1
    -a
    }} []
    |hunk ./myfile 1
    |-a
    |:
    rmfile ./myfile

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Change myfile
    hunk ./myfile 2
    +b

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Add myfile
    addfile ./myfile
    hunk ./myfile 1
    +a

それでは、「Remove myfile」のクレイジーな出力について説明しましょう。「Remove myfile」は foo に次のように存在します。

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Remove myfile
    hunk ./myfile 1
    -a
    rmfile ./myfile

したがって、1行目のハンクとファイルの削除。

「remove myfile」を bar にプルすると、bar 内の他のプリミティブと競合する「Remove myfile」内のプリミティブを表す特別な「conflictor」プリミティブを導入して、パッチの内容を変更します。注意:ここでは情報の損失はありません。競合する変更をプル解除することで、元のプリミティブにいつでも戻ることができます。この場合は、"change myfile" をプル解除します。

競合者は紛らわしいですが、AFAICT は基本的に、現在のパッチ x と競合する変更を 2 つのセットに分けます。「ix」は、次を含むパッチのセットです: i) x と競合するパッチおよびレポ内の他のパッチ ii) パッチthat conflict with a patch that conflicts with x "xx" は、パッチ x とのみ競合する一連のパッチです。これが行われる理由は、コンフリクターが競合を引き起こすプリミティブを「元に戻す」効果があるが、別のコンフリクターによって元に戻されていないプリミティブのみがあるためだと思います。

出力は次のようになります。

"conflictor" ix "[" xx "]" x

私は表記法を乱用していますが、うまくいけばそれをある程度解読できます (完全なストーリーについては、darcs.net リポジトリの src/Darcs/Patch/V2/(Real.hs|Non.hs) を参照してください)。

この場合、"Remove myfile" には 2 つのプリミティブ パッチがあり、(この場合) bar にプルされると 2 つの対応するコンフリクターがあります。

最初のプリミティブ (myfile から 1 行目を削除) は、「Change myfile」内のプリミティブ (myfile の 2 行目に 'b' を追加) とのみ競合するため、これが最初の競合元です。

conflictor [    <--- The start of xx (no ix here)
hunk ./myfile 2
+b
]               <--- The end of xx
|:
hunk ./myfile 1 <--- x
-a

NB (「|:」は、プリミティブ自体から「非」プリミティブのコンテキストを区切るマーカーです。これ以上説明しようとはしません。問題のプリミティブを確認するには、以下を読んでください |: )

2 番目のプリミティブ (remove myfile) はもう少し複雑です: (rmfile myfile) は (add 'b' to line 2 of myfile) と競合しますが、これは既知のように (remove line 1 from myfile) と競合するため、両方とも " ix」、「xx」にはパッチがありません。不要な「|:」区切り文字を削除し、スペースを空けます。

conflictor {{

hunk ./myfile 2
+b

hunk ./myfile 1
-a

}} 
[]               <--- no xx

|hunk ./myfile 1 <--- start of x
|-a
|:
rmfile ./myfile  <--- end of x

最後の (rmfile myfile) には、参照している正確なプリミティブを識別するためのコンテキストがあります (これが必要な理由/方法はよくわかりませんが、必要です)。 「|:」で区切ります。

darcs whatsnew最後に、 in foo;の出力について説明します。複数のパッチが競合する場合、コンフリクターの実際の効果は、競合するパッチを「元に戻す」ことであり、どちらの効果も与えません。いくつかの説明の始まりを示します: http://en.wikibooks.org/wiki/Understanding_Darcs/Patch_theory_and_conflicts .

あなたが見ているのは、「Change myfile」と「Remove myfile」の強制交換の結果であると思います。それぞれそれらAを呼び出しますB。次に、2 つをマージするために、Darcs は createA^-1と commutesA^-1Bto give B'and (A^-1)'whereB'の効果がありA^-1ます (交換を強制的に機能させるため) B'。 「Change myfile」で行った行の追加。

どのように機能するかを見る時間がなかったので、バーでdarcs mark-conflicts見られる作業上の変更についてはまだ説明できません.darcs changes

于 2011-11-15T20:18:28.070 に答える