Karl and I want to propose a very simple change to 'svn merge' default
behavior in svn 0.37. Allow me to explain.
1. We have a problem
Early this week I merged all of the book changes from trunk to the 1.0
branch. The merge seemed simple enough -- a bunch of files got
patched, but one had a conflict. I couldn't figure out why there'd be
a conflict... the book never changed on the branch. After some
investigation, I discovered that totally bogus hunks of text had been
applied to the wrong files! Most the local mods from 'svn merge' were
What happened? My trunk changes involved renames; I moved ch06->ch07,
ch07->ch08, and ch08->ch09. 'svn merge', just like 'svn diff',
ignores file ancestry (copy history) by default. So it was applying
ch07 changes from trunk to a similarly named (but totally unrelated!)
file on the branch. After reverting the bogus merge, I ran 'svn merge
--notice-ancestry' and got the correct set of changes: a bunch of
deletes and adds of identically-name files. Everything was fine.
2. The history of this issue
Once upon a time, diff and merge used to both notice ancestry by
default. But this angered users of 'svn diff'. When running 'svn
diff URL1 URL2', people would be annoyed that diff was being "too
smart". It would notice that two identical file paths were unrelated,
and show a delete of one file (all minuses) and the add of the other
file (all pluses). But when running 'svn diff', the user usually
doesn't give a darn about whether identically-named files are related
or not: they just want to see the diff between them! (The diff format
doesn't understand tree changes anyway, so why include that
So, we did the right thing: we made 'svn diff URL1 URL2' ignore
ancestry by default, and "dumbly" diff identical file paths. But in
the interest of consistency, folks decided that diff and merge should
behave the same. So both commands now ignore ancestry by default, and
require a long option to notice ancestry.
3. The proposal
Very simple: allow 'svn diff' continue to ignore ancestry by default,
but change 'svn merge' to notice ancestry by default.
(The patch for this involves no API changes; internally, the diff and
merge client functions already have the ability to ignore ancestry or
not. The patch is a trivial change to cmdline client's default
behaviors only. A long option can always be used to override either
subcommand's default behavior.)
Yes, I understand that this breaks our nice consistency between diff
and merge. But Karl and I think the risk for producing munged local
mods here is just too high.
99% of the time, when people are merging changesets from one branch to
another, people want ancestry to be noticed and copies to be honored.
It's dangerous and foolish to default to the 1% use-case. Keep in
mind, I wrote the *book* chapter about branching and merging, and I
still got burned by merge's default behavior. It's not always so
obvious to detect the munged local mods... if I hadn't received a
conflict, I might have accidentally committed garbage.
So yes, it's "nice" to have consistent default behaviors in diff and
merge, but this route leads to either (1) 'svn diff' not showing diffs
by default (very user-unfriendly), or alternately (2) a significant
risk of 'svn merge' creating bogus local mods by default. In my
mind, neither evil is worth the "niceness" of consistency. It's hard
to enumerate the concrete benefits of consistency, except,
well... "it's consistent."
I've already talked about this proposal with kfogel, ghudson, and epg.
But I wanted other developers to see the proposal and have a chance to
To unsubscribe, e-mail: firstname.lastname@example.org
For additional commands, e-mail: email@example.com
Received on Thu Jan 15 18:25:55 2004