qarks.com Forum Index qarks.com
AVS forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to get the merged file?

 
Post new topic   Reply to topic    qarks.com Forum Index -> JDiff
View previous topic :: View next topic  
Author Message
jpletard



Joined: 06 Nov 2008
Posts: 4

PostPosted: Thu Nov 06, 2008 9:02 am    Post subject: How to get the merged file? Reply with quote

Hello Everybody,
I'm trying to use the jDiff lib to obtain a basic version of a merged file. Here is the code to read the 3 files and obtain a "MergeResult" :
Code:

         String commonAncestor = FileHelper.getFileContent(new File("C:\\JP\\fichiers de test\\ancestor.txt"));
         String version1 = FileHelper.getFileContent(new File("C:\\JP\\fichiers de test\\test V1.txt"));
         String version2 = FileHelper.getFileContent(new File("C:\\JP\\fichiers de test\\test V2.txt"));

         MergeResult mergeResult = Diff.quickMerge(commonAncestor, version1, version2);

         MergeResultItem mergeResultItem = MergeResultItem.merge ( MergeResultItem.Type.WARNING_DELETE , mergeResult.getMergeItems());


But now, I don't find a method to get the result of the merging in a String for example. Is this kind of method already exist or have I to write it? (I think I can start by using a part of the GUI code).
I know it can have conflict but I'm looking for a default merging result like in the GUI.
Thank you by advance for your response

PS : sorry for the English mistakes, I hope you could understand me!
Back to top
View user's profile Send private message
jpletard



Joined: 06 Nov 2008
Posts: 4

PostPosted: Thu Nov 06, 2008 9:31 am    Post subject: Reply with quote

I respond myself...
I think the following code is fine for me :
Code:
ArrayList<FileLine> mergingResult = new ArrayList<FileLine>();
         for (MergeResultItem mergeResultItem : mergeResult.getMergeItems()) {
            if (mergeResultItem.isConflict()) {
               System.out.println("conflit");
            } else {
               if (mergeResultItem.getDefaultVersion() == MergeResultItem.DefaultVersion.LEFT) {
                  mergingResult.addAll(mergeResultItem.getLeftVersion());
               } else {
                  mergingResult.addAll(mergeResultItem.getRightVersion());
               }
            }
         }
Back to top
View user's profile Send private message
spampete
Site Admin


Joined: 04 May 2007
Posts: 89

PostPosted: Thu Nov 06, 2008 10:12 am    Post subject: Reply with quote

well no, it is not that simple, you also have to handle warning cases, but now you ask, I do realize you are right, the MergeResult class should provide a simple way to get the merge result, of course.

I will provide the missing helper before tomorrow
Back to top
View user's profile Send private message Send e-mail
jpletard



Joined: 06 Nov 2008
Posts: 4

PostPosted: Thu Nov 06, 2008 10:42 am    Post subject: Reply with quote

I add some treatment for the warning cases, maybe this code can help you or smbd :
Code:
for (MergeResultItem mergeResultItem : mergeResult.getMergeItems()) {
            if (mergeResultItem.getType() == MergeResultItem.Type.NO_CONFLICT) {
               if (mergeResultItem.getDefaultVersion() == MergeResultItem.DefaultVersion.LEFT) {
                  mergingResult.addAll(mergeResultItem.getLeftVersion());
               } else {
                  mergingResult.addAll(mergeResultItem.getRightVersion());
               }
            } else { //conflict or waring
               conflictLog.append("line ").append(mergeResultItem.getLineCount()).append(" ").append(mergeResultItem.getType());
               conflictLog.append(" edited").append(mergeResultItem.getLeftVersion()).append(" generated").append(mergeResultItem.getRightVersion());

               if (defaultMargedContent == Diff2Files.DefaultMargedContent.EDITED_FILE) { //add the selected content to merging
                  mergingResult.addAll(mergeResultItem.getLeftVersion());
               } else {
                  mergingResult.addAll(mergeResultItem.getRightVersion());
               }

            }
         }
Back to top
View user's profile Send private message
spampete
Site Admin


Joined: 04 May 2007
Posts: 89

PostPosted: Thu Nov 06, 2008 10:48 am    Post subject: Reply with quote

well yes, it should look like something like this.

I have not tested yet, but something here is what I will test when I am available:

Code:

package com.qarks.util.files.diff;

import java.util.ArrayList;

public class MergeResult {

   private ArrayList<MergeResultItem> mergeItems;
   private ParsedFile leftFile = null;
   private ParsedFile rightFile = null;
   private String eol = System.getProperty("line.separator");

   public MergeResult(ArrayList<MergeResultItem> mergeItems) {
      this.mergeItems = mergeItems;
   }

   public ParsedFile getLeftFile(){
      if (leftFile==null){
         ArrayList<FileLine> lines = new ArrayList<FileLine> ();
         for (int i = 0; i < mergeItems.size(); i++) {
            lines.addAll(mergeItems.get(i).getLeftVersion());
         }
         leftFile = new ParsedFile(lines);
      }
      return leftFile;
   }

   public ParsedFile getRightFile(){
      if (rightFile==null){
         ArrayList<FileLine> lines = new ArrayList<FileLine> ();
         for (int i = 0; i < mergeItems.size(); i++) {
            lines.addAll(mergeItems.get(i).getRightVersion());
         }
         rightFile = new ParsedFile(lines);
      }
      return rightFile;
   }

   public ArrayList<MergeResultItem> getMergeItems(){
      return mergeItems;
   }

   public String getDefaultMergedResult(){      
      StringBuffer buf = new StringBuffer();
      for(int i=0;i<mergeItems.size();i++){
         if (i>0){
            buf.append(eol);
         }
         MergeResultItem item = mergeItems.get(i);         
         MergeResultItem.Type type = item.getType();
         String text = "";
         boolean defaultLeft = item.getDefaultVersion()==MergeResultItem.DefaultVersion.LEFT;
         String leftText = getText(item.getLeftVersion());
         String rightText = getText(item.getRightVersion());
         switch(type){
         case NO_CONFLICT:
            text = defaultLeft?leftText:rightText;
            break;
         case CONFLICT:
            text = "<<CONFLICT>>";
            break;
         case WARNING_ORDER:
            text = leftText + eol + rightText;
            break;
         case WARNING_DELETE:
            text = defaultLeft?leftText:rightText;
            break;
         }       
         buf.append(text);
      }
      return buf.toString();
   }
   
   public boolean isConflict(){
      boolean result = false;
      for(int i=0;!result && i<mergeItems.size();i++){
         MergeResultItem item = mergeItems.get(i);         
         if (item.getType()==MergeResultItem.Type.CONFLICT){
            result = true;
         }
      }
      return result;
   }
   
   public boolean isWarning(){
      boolean result = false;
      for(int i=0;!result && i<mergeItems.size();i++){
         MergeResultItem item = mergeItems.get(i);         
         if (item.getType()==MergeResultItem.Type.WARNING_DELETE ||
            item.getType()==MergeResultItem.Type.WARNING_ORDER){
            result = true;
         }
      }
      return result;
   }

   private String getText(ArrayList<FileLine> lines){
      StringBuffer buf = new StringBuffer();
      for(int i=0;i<lines.size();i++){
         if (i>0){
            buf.append(eol);
         }
         buf.append(lines.get(i).getContent());
      }
      return buf.toString();
   }
}

Back to top
View user's profile Send private message Send e-mail
spampete
Site Admin


Joined: 04 May 2007
Posts: 89

PostPosted: Thu Nov 06, 2008 12:39 pm    Post subject: Reply with quote

ok, the helper seems to be working correctly. Just as a little side effect, it will insert empty lines on deletion on one side.

diff uses Myers' min set of differences, whereas merge uses an algorithm from my own, based on Myers' diff computed with both versions and common ancestor, and then on what follows:

- a different modification at the same place in the common ancestor is a conflict
- a different insertion at the same place is a warning, since merge cannot decide the insertion order
- a deletion only on one side is a warning since the other version can rely on what the other deleted. Be default, it is removed from the default merge result, but you get a warning

I will release a new version very soon containing this merge helper. Let me know if it works fine for you.
Back to top
View user's profile Send private message Send e-mail
jpletard



Joined: 06 Nov 2008
Posts: 4

PostPosted: Fri Nov 07, 2008 11:18 am    Post subject: Reply with quote

Thank you Pierre for this new usefull method. It's seems to be what I need.
I will tell you the eventual evolutions and the achievement of our project.
I keep in mind the donation ask Wink
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    qarks.com Forum Index -> JDiff All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group