Sort of. The OP doesn't write clearly. He's also confused about how git works. What he means is..
Say Bob has 2 commits (B1-B2) and Alice has 1 (A1)
Scenario 1: Alice merges each of Bob's commits in sequence (i.e. she replays his commit history onto her repo: A1-B1-B2).
Scenario 2: Alice merges only B2 (A1-B2).
The point is that, with git, Alice's repo will be different in each scenario. Because in scenario 2 git doesn't examine commit B1 and use that info to try and figure out what the content in commit B2 "means".
With darcs, on the other hand, her scenario 1 repo will be identical to her scenario 2 repo.
The flip side is that in scenario 2 git will always produce the same result for the same B2, because B1 is irrelevant. With darcs a change in B1 will change the result.
NOTE: "git pull --rebase" actually does "replay commit history" instead of "merge" when pulling code into your repo (result: B1-B2-A1). I use it as my default. The outcome is the same as darcs, the difference is that everything is explicit.
I don't understand where or how you could encounter a circumstance where this would matter. This complaint seems to be an abstract theoretical point (maybe to support git alternatives? dunno) that even esoteric usage of a DSCV would never come across.
I dunno, maybe i'm not being creative enough in my use of histories.
function B(){
return 1;
}
function A(){
return 1;
}
then this:
function A(){
return 1;
}
function B(){
return 1;
}
function A(){
return 1;
}
And then this in another branch off the base:
function A(){
return 2;
}
Now merge the two end points. Which is correct? This, assuming a purely line-based diff:
function A(){
return 2;
}
function B(){
return 1;
}
function A(){
return 1;
}
or this, assuming knowledge of the history of events?
function A(){
return 1;
}
function B(){
return 1;
}
function A(){
return 2;
}
In Javascript, where such code is acceptable, `A()` now returns 1 or 2.
In Git, or by applying patches manually, it depends on the order in which you merge. If you merge the `B()A()` branch with the `return 2` branch and then the `A()B()A()` one, you'll get the second result. But if you merge the `A()B()A()` directly with the `return 2` branch, you'll get first one. The same set of changes producing different outcomes.
In Darcs, the history between `A()`, `B()A()`, and `A()B()A()` are checked, and it's seen that the second `A()` is the "original" one, so the `return 2` is applied to that one.
Which means that you won't necessarily get the same behavior merging two Darcs patches as you would merging it within the repository, where there is a history. Git behaves exactly as if you were dealing with patches. I side with Git on this, personally, but it's a valid point - you have history, why not use it?
You know, I suspect that in many production cases, neither merge is "correct". The example involves a lot code duplication, and a change to the block of code which was duplicated.
The probable case is something like:
function foo(){
do_something_complex_but_not_correct();
}
with one person making the change to:
function foo(){
something_else();
do_something_complex_but_not_correct();
}
and then:
function foo(){
do_something_complex_but_not_correct();
something_else();
do_something_complex_but_not_correct();
}
in the stated two-step change, while another author makes the change to:
function foo(){
do_something_complex_and_also_correct();
}
The correct "merge" is going to be to apply the second change to both blocks of code, not just the first or the second:
function foo(){
do_something_complex_and_also_correct();
something_else();
do_something_complex_and_also_correct();
}
Which is why I side with explicit, patch-like behavior. Interpreting a `move-and-copy` as a `move` when there's a chunk of duplicate data that could mess things up means it's essentially doing a primitive semantic analysis of what you meant to do. It may be correct more of the time, but it can't be correct all of the time.
What I "meant to do" could have been as you stated, where both should have changed. Or I could have copied the internals of a function to a new one, and made minor changes around it, and actually do wish to use that new copy as the official version. There is no way to 100% accurately detect such intent without being explicit about it, so I'd prefer something dumb and therefore extremely predictable.
Sort of. The OP doesn't write clearly. He's also confused about how git works. What he means is..
Say Bob has 2 commits (B1-B2) and Alice has 1 (A1)
Scenario 1: Alice merges each of Bob's commits in sequence (i.e. she replays his commit history onto her repo: A1-B1-B2).
Scenario 2: Alice merges only B2 (A1-B2).
The point is that, with git, Alice's repo will be different in each scenario. Because in scenario 2 git doesn't examine commit B1 and use that info to try and figure out what the content in commit B2 "means".
With darcs, on the other hand, her scenario 1 repo will be identical to her scenario 2 repo.
The flip side is that in scenario 2 git will always produce the same result for the same B2, because B1 is irrelevant. With darcs a change in B1 will change the result.
NOTE: "git pull --rebase" actually does "replay commit history" instead of "merge" when pulling code into your repo (result: B1-B2-A1). I use it as my default. The outcome is the same as darcs, the difference is that everything is explicit.