Program: 91313
Project: 91313
Buggy source:
/** 
 * Processes one path and tries to merge. This method will do all do all trivial (not content) merges and will also detect if a merge will fail. The merge will fail when one of the following is true <ul> <li>the index entry does not match the entry in ours. When merging one branch into the current HEAD, ours will point to HEAD and theirs will point to the other branch. It is assumed that the index matches the HEAD because it will only not match HEAD if it was populated before the merge operation. But the merge commit should not accidentally contain modifications done before the merge. Check the <a href= "http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html#_3_way_merge" >git read-tree</a> documentation for further explanations.</li> <li>A conflict was detected and the working-tree file is dirty. When a conflict is detected the content-merge algorithm will try to write a merged version into the working-tree. If the file is dirty we would override unsaved data.</li>
 * @param base the common base for ours and theirs
 * @param ours the ours side of the merge. When merging a branch into the HEAD ours will point to HEAD
 * @param theirs the theirs side of the merge. When merging a branch into the current HEAD theirs will point to the branch which is merged into HEAD.
 * @param index the index entry
 * @param work the file in the working tree
 * @return <code>false</code> if the merge will fail because the index entrydidn't match ours or the working-dir file was dirty and a conflict occurred
 * @throws MissingObjectException
 * @throws IncorrectObjectTypeException
 * @throws CorruptObjectException
 * @throws IOException
 */
private boolean processEntry(CanonicalTreeParser base,CanonicalTreeParser ours,CanonicalTreeParser theirs,DirCacheBuildIterator index,WorkingTreeIterator work) throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, IOException {
  enterSubtree=true;
  final int modeO=tw.getRawMode(T_OURS);
  final int modeT=tw.getRawMode(T_THEIRS);
  final int modeB=tw.getRawMode(T_BASE);
  if (modeO == 0 && modeT == 0 && modeB == 0)   return true;
  if (isIndexDirty())   return false;
  DirCacheEntry ourDce=null;
  if (index == null || index.getDirCacheEntry() == null) {
    if (nonTree(modeO)) {
      ourDce=new DirCacheEntry(tw.getRawPath());
      ourDce.setObjectId(tw.getObjectId(T_OURS));
      ourDce.setFileMode(tw.getFileMode(T_OURS));
    }
  }
 else {
    ourDce=index.getDirCacheEntry();
  }
  if (nonTree(modeO) && nonTree(modeT) && tw.idEqual(T_OURS,T_THEIRS)) {
    if (modeO == modeT) {
      keep(ourDce);
      return true;
    }
 else {
      int newMode=mergeFileModes(modeB,modeO,modeT);
      if (newMode != FileMode.MISSING.getBits()) {
        if (newMode == modeO)         keep(ourDce);
 else {
          if (isWorktreeDirty(work))           return false;
          DirCacheEntry e=add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_0,0,0);
          toBeCheckedOut.put(tw.getPathString(),e);
        }
        return true;
      }
 else {
        add(tw.getRawPath(),base,DirCacheEntry.STAGE_1,0,0);
        add(tw.getRawPath(),ours,DirCacheEntry.STAGE_2,0,0);
        add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_3,0,0);
        unmergedPaths.add(tw.getPathString());
        mergeResults.put(tw.getPathString(),new MergeResult<RawText>(Collections.<RawText>emptyList()));
      }
      return true;
    }
  }
  if (nonTree(modeO) && modeB == modeT && tw.idEqual(T_BASE,T_THEIRS)) {
    keep(ourDce);
    return true;
  }
  if (modeB == modeO && tw.idEqual(T_BASE,T_OURS)) {
    if (isWorktreeDirty(work))     return false;
    if (nonTree(modeT)) {
      DirCacheEntry e=add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_0,0,0);
      if (e != null)       toBeCheckedOut.put(tw.getPathString(),e);
      return true;
    }
 else     if (modeT == 0 && modeB != 0) {
      toBeDeleted.add(tw.getPathString());
      return true;
    }
  }
  if (tw.isSubtree()) {
    if (nonTree(modeO) && !nonTree(modeT)) {
      if (nonTree(modeB))       add(tw.getRawPath(),base,DirCacheEntry.STAGE_1,0,0);
      add(tw.getRawPath(),ours,DirCacheEntry.STAGE_2,0,0);
      unmergedPaths.add(tw.getPathString());
      enterSubtree=false;
      return true;
    }
    if (nonTree(modeT) && !nonTree(modeO)) {
      if (nonTree(modeB))       add(tw.getRawPath(),base,DirCacheEntry.STAGE_1,0,0);
      add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_3,0,0);
      unmergedPaths.add(tw.getPathString());
      enterSubtree=false;
      return true;
    }
    if (!nonTree(modeO))     return true;
  }
  if (nonTree(modeO) && nonTree(modeT)) {
    if (isWorktreeDirty(work))     return false;
    MergeResult<RawText> result=contentMerge(base,ours,theirs);
    File of=writeMergedFile(result);
    updateIndex(base,ours,theirs,result,of);
    if (result.containsConflicts())     unmergedPaths.add(tw.getPathString());
    modifiedFiles.add(tw.getPathString());
  }
 else   if (modeO != modeT) {
    if (((modeO != 0 && !tw.idEqual(T_BASE,T_OURS)) || (modeT != 0 && !tw.idEqual(T_BASE,T_THEIRS)))) {
      add(tw.getRawPath(),base,DirCacheEntry.STAGE_1,0,0);
      add(tw.getRawPath(),ours,DirCacheEntry.STAGE_2,0,0);
      DirCacheEntry e=add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_3,0,0);
      if (modeO == 0) {
        if (isWorktreeDirty(work))         return false;
        if (nonTree(modeT)) {
          if (e != null)           toBeCheckedOut.put(tw.getPathString(),e);
        }
      }
      unmergedPaths.add(tw.getPathString());
      mergeResults.put(tw.getPathString(),contentMerge(base,ours,theirs));
    }
  }
  return true;
}

Fixed version (ground truth):
/** 
 * Processes one path and tries to merge. This method will do all do all trivial (not content) merges and will also detect if a merge will fail. The merge will fail when one of the following is true <ul> <li>the index entry does not match the entry in ours. When merging one branch into the current HEAD, ours will point to HEAD and theirs will point to the other branch. It is assumed that the index matches the HEAD because it will only not match HEAD if it was populated before the merge operation. But the merge commit should not accidentally contain modifications done before the merge. Check the <a href= "http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html#_3_way_merge" >git read-tree</a> documentation for further explanations.</li> <li>A conflict was detected and the working-tree file is dirty. When a conflict is detected the content-merge algorithm will try to write a merged version into the working-tree. If the file is dirty we would override unsaved data.</li>
 * @param base the common base for ours and theirs
 * @param ours the ours side of the merge. When merging a branch into the HEAD ours will point to HEAD
 * @param theirs the theirs side of the merge. When merging a branch into the current HEAD theirs will point to the branch which is merged into HEAD.
 * @param index the index entry
 * @param work the file in the working tree
 * @return <code>false</code> if the merge will fail because the index entrydidn't match ours or the working-dir file was dirty and a conflict occurred
 * @throws MissingObjectException
 * @throws IncorrectObjectTypeException
 * @throws CorruptObjectException
 * @throws IOException
 */
private boolean processEntry(CanonicalTreeParser base,CanonicalTreeParser ours,CanonicalTreeParser theirs,DirCacheBuildIterator index,WorkingTreeIterator work) throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, IOException {
  enterSubtree=true;
  final int modeO=tw.getRawMode(T_OURS);
  final int modeT=tw.getRawMode(T_THEIRS);
  final int modeB=tw.getRawMode(T_BASE);
  if (modeO == 0 && modeT == 0 && modeB == 0)   return true;
  if (isIndexDirty())   return false;
  DirCacheEntry ourDce=null;
  if (index == null || index.getDirCacheEntry() == null) {
    if (nonTree(modeO)) {
      ourDce=new DirCacheEntry(tw.getRawPath());
      ourDce.setObjectId(tw.getObjectId(T_OURS));
      ourDce.setFileMode(tw.getFileMode(T_OURS));
    }
  }
 else {
    ourDce=index.getDirCacheEntry();
  }
  if (nonTree(modeO) && nonTree(modeT) && tw.idEqual(T_OURS,T_THEIRS)) {
    if (modeO == modeT) {
      keep(ourDce);
      return true;
    }
 else {
      int newMode=mergeFileModes(modeB,modeO,modeT);
      if (newMode != FileMode.MISSING.getBits()) {
        if (newMode == modeO)         keep(ourDce);
 else {
          if (isWorktreeDirty(work))           return false;
          DirCacheEntry e=add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_0,0,0);
          toBeCheckedOut.put(tw.getPathString(),e);
        }
        return true;
      }
 else {
        add(tw.getRawPath(),base,DirCacheEntry.STAGE_1,0,0);
        add(tw.getRawPath(),ours,DirCacheEntry.STAGE_2,0,0);
        add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_3,0,0);
        unmergedPaths.add(tw.getPathString());
        mergeResults.put(tw.getPathString(),new MergeResult<RawText>(Collections.<RawText>emptyList()));
      }
      return true;
    }
  }
  if (nonTree(modeO) && modeB == modeT && tw.idEqual(T_BASE,T_THEIRS)) {
    keep(ourDce);
    return true;
  }
  if (modeB == modeO && tw.idEqual(T_BASE,T_OURS)) {
    if (isWorktreeDirty(work))     return false;
    if (nonTree(modeT)) {
      DirCacheEntry e=add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_0,0,0);
      if (e != null)       toBeCheckedOut.put(tw.getPathString(),e);
      return true;
    }
 else     if (modeT == 0 && modeB != 0) {
      toBeDeleted.add(tw.getPathString());
      return true;
    }
  }
  if (tw.isSubtree()) {
    if (nonTree(modeO) && !nonTree(modeT)) {
      if (nonTree(modeB))       add(tw.getRawPath(),base,DirCacheEntry.STAGE_1,0,0);
      add(tw.getRawPath(),ours,DirCacheEntry.STAGE_2,0,0);
      unmergedPaths.add(tw.getPathString());
      enterSubtree=false;
      return true;
    }
    if (nonTree(modeT) && !nonTree(modeO)) {
      if (nonTree(modeB))       add(tw.getRawPath(),base,DirCacheEntry.STAGE_1,0,0);
      add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_3,0,0);
      unmergedPaths.add(tw.getPathString());
      enterSubtree=false;
      return true;
    }
    if (!nonTree(modeO))     return true;
  }
  if (nonTree(modeO) && nonTree(modeT)) {
    if (isWorktreeDirty(work))     return false;
    if (isGitLink(modeO) || isGitLink(modeT)) {
      add(tw.getRawPath(),base,DirCacheEntry.STAGE_1,0,0);
      add(tw.getRawPath(),ours,DirCacheEntry.STAGE_2,0,0);
      add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_3,0,0);
      unmergedPaths.add(tw.getPathString());
      return true;
    }
    MergeResult<RawText> result=contentMerge(base,ours,theirs);
    File of=writeMergedFile(result);
    updateIndex(base,ours,theirs,result,of);
    if (result.containsConflicts())     unmergedPaths.add(tw.getPathString());
    modifiedFiles.add(tw.getPathString());
  }
 else   if (modeO != modeT) {
    if (((modeO != 0 && !tw.idEqual(T_BASE,T_OURS)) || (modeT != 0 && !tw.idEqual(T_BASE,T_THEIRS)))) {
      add(tw.getRawPath(),base,DirCacheEntry.STAGE_1,0,0);
      add(tw.getRawPath(),ours,DirCacheEntry.STAGE_2,0,0);
      DirCacheEntry e=add(tw.getRawPath(),theirs,DirCacheEntry.STAGE_3,0,0);
      if (modeO == 0) {
        if (isWorktreeDirty(work))         return false;
        if (nonTree(modeT)) {
          if (e != null)           toBeCheckedOut.put(tw.getPathString(),e);
        }
      }
      unmergedPaths.add(tw.getPathString());
      mergeResults.put(tw.getPathString(),contentMerge(base,ours,theirs));
    }
  }
  return true;
}