[darcs-users] unexpected merge conflicts

Aggelos Economopoulos aoiko at cc.ece.ntua.gr
Fri May 16 18:40:08 UTC 2003


Hi David,

to keep up with darcs development, I use a local repository to which I 
regularly pull the changes from http://abridgegame.org/repos/darcs. This repo 
is only pulled from and has never been changed in any way. Trying to update 
today, I got:

aggelos at erwin:~/src/darcs/darcs> darcs pull `cat _darcs/prefs/repos`
[make cgi repos dir configurable.
droundy at abridgegame.org**Mon May 12 06:11:02 EDT 2003]
Shall I pull this patch? [ynvaswh] y
[fix patch ordering bug along with push/pull.
droundy at abridgegame.org**Wed May 14 08:51:00 EDT 2003]
Shall I pull this patch? [ynvaswh] y
[code beautification in depends.
droundy at abridgegame.org**Wed May 14 08:53:37 EDT 2003]
Shall I pull this patch? [ynvaswh] y
[fix unravel bug
droundy at abridgegame.org**Thu May 15 10:40:47 EDT 2003]
Shall I pull this patch? [ynvaswh] y
[fix pull bug triggered when pulling a few out of many patches.
droundy at abridgegame.org**Fri May 16 06:09:22 EDT 2003]
Shall I pull this patch? [ynvaswh] y
[add new unit test for unravel.
droundy at abridgegame.org**Fri May 16 07:24:44 EDT 2003]
Shall I pull this patch? [ynvaswh] y
So far so good... the merge succeeded.
We have conflicts in the following files:
./Depends.lhs ./Pull.lhs ./Push.lhs
Finished pulling.
aggelos at erwin:~/src/darcs/darcs>

I only found conflict markers in Depends.lhs (attached).

(end of bug report)

Also, two requests unrelated with coding:

i) could you take the time to describe the manifestation of the bugs you fix 
(in the changelog, maybe, or even better in darcs-users)? The case described 
in (ii) seems to be related to

[fix pull bug triggered when pulling a few out of many patches.
droundy at abridgegame.org**Fri May 16 06:09:22 EDT 2003]

but I can't tell for sure.

ii) could you state what the supported (will work) merge cases are? known 
cases where darcs falls apart? I've managed to turn a repo into a rather ugly 
mess while trying to gradually (yes, I did more than a few partial pulls 
while at it) merge three development lines back to the parent repo and I'm 
not really sure if *I* did something wrong/unsupported or I just hit a bug in 
darcs. I haven't found the time to try to reproduce it yet.

Thanks,
Aggelos


-------------- next part --------------
%  Copyright (C) 2003 David Roundy  
%
%  This program is free software; you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation; either version 2, or (at your option)
%  any later version.
%
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with this program; if not, write to the Free Software Foundation,
%  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\section{Dependencies}
\begin{code}
module Depends ( get_common_and_uncommon, get_tags_right,
                 optimize_patchset,
               ) where
import List ( elem, delete, intersect )
import Monad ( liftM )
import Maybe ( fromJust )

import Patch
import PatchInfo
import RepoTypes ( PatchSet, PatchSequence )
\end{code}

\begin{code}
get_tags_right :: PatchSet -> [PatchInfo]
get_common_and_uncommon :: (PatchSet,PatchSet) ->
                           ([PatchInfo],PatchSet,PatchSet)
\end{code}

\begin{code}
safehead [] = []
safehead (a:_) = a
get_common_and_uncommon (ps1,ps2)
    | null ps1 || null ps2 = ([],[concat ps1],[concat ps2])
get_common_and_uncommon ([(pi1,_)]:_,[(pi2,_)]:_)
    | pi1 == pi2 = ([pi1],[],[])
get_common_and_uncommon (ps1:ps1b:ps1s,ps2:ps2b:ps2s) =
  if (fst $ head $ reverse ps1) == (fst $ head $ reverse ps2)
  then case (map fst ps1) `intersect` (map fst ps2) of
       common -> (map fst $ safehead $ optimize_patchset $
                  [filter ((`elem` common).fst) ps1],
v v v v v v v
                  [get_extra [] common ps1],
                  [get_extra [] common ps2])
*************
                  [get_extra_r [] common ps1],
                  [get_extra_r [] common ps2])
^ ^ ^ ^ ^ ^ ^
  else if length ps1 > length ps2
       then get_common_and_uncommon (ps1:ps1b:ps1s, (ps2++ps2b):ps2s)
       else get_common_and_uncommon ((ps1++ps1b):ps1s, ps2:ps2b:ps2s)
get_common_and_uncommon ([ps1],[ps2]) =
    case (map fst ps1) `intersect` (map fst ps2) of
    common -> (map fst $ safehead $ optimize_patchset $
               [filter ((`elem` common).fst) ps1],
v v v v v v v
               [get_extra [] common ps1],
               [get_extra [] common ps2])
*************
               [get_extra_r [] common ps1],
               [get_extra_r [] common ps2])
^ ^ ^ ^ ^ ^ ^
get_common_and_uncommon ([ps1],ps2s) =
    get_common_and_uncommon ([ps1],[concat ps2s])
get_common_and_uncommon (ps1s,[ps2]) =
    get_common_and_uncommon ([concat ps1s],[ps2])

get_extra skipped concat [] = []
get_extra skipped common ((pi, mp):pps) =
    if pi `elem` common && is_tag pi
    then case liftM getdeps mp of
         Just ds -> get_extra (fromJust mp:skipped) (ds++delete pi common) pps
         Nothing -> get_extra (fromJust mp:skipped) (delete pi common) pps
    else if pi `elem` common
         then get_extra (fromJust mp:skipped) (delete pi common) pps
         else case commute (join_patches skipped, fromJust mp) of
              Just (p', skipped_patch') ->
                  (pi,Just p') : get_extra (flatten skipped_patch') common pps
\end{code}

\begin{code}
is_tag pi = take 3 (just_name pi) == "TAG"

get_tags_right [] = []
get_tags_right (ps:_) = get_tags_r ps

get_tags_r [] = []
get_tags_r ((pi,mp):pps)
    | is_tag pi = case liftM getdeps mp of
                  Just ds -> pi : get_tags_r (drop_tags_r ds pps)
                  Nothing -> pi : map fst pps
    | otherwise = pi : get_tags_r pps
drop_tags_r :: [PatchInfo] -> PatchSequence -> PatchSequence
drop_tags_r [] pps = pps
drop_tags_r _ [] = []
drop_tags_r ds ((pi,mp):pps)
    | pi `elem` ds && is_tag pi =
        case liftM getdeps mp of
        Just ds' -> drop_tags_r (ds'++delete pi ds) pps
        Nothing -> drop_tags_r (delete pi ds) pps
    | pi `elem` ds = drop_tags_r (delete pi ds) pps
    | otherwise = (pi,mp) : drop_tags_r ds pps
\end{code}

\begin{code}
optimize_patchset :: PatchSet -> PatchSet
optimize_patchset [] = []
optimize_patchset (ps:pss) = opsp ps ++ pss
opsp :: [(PatchInfo,Maybe Patch)] -> PatchSet
opsp [] = []
opsp ((pi,mp):pps) =
  if is_tag pi
  then if get_tags_right [(pi,mp):pps] == [pi]
       then[[(pi,mp)]] ++ opsp pps
       else boring
  else boring
  where boring = case opsp pps of
                 [] -> [[(pi,mp)]]
                 (pps':rest) -> ((pi,mp):pps') : rest
\end{code}


More information about the darcs-users mailing list