View Javadoc
1   /*
2    * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>,
3    * Copyright (C) 2010-2012, Matthias Sohn <matthias.sohn@sap.com>
4    * Copyright (C) 2012, Research In Motion Limited
5    * and other copyright owners as documented in the project's IP log.
6    *
7    * This program and the accompanying materials are made available
8    * under the terms of the Eclipse Distribution License v1.0 which
9    * accompanies this distribution, is reproduced below, and is
10   * available at http://www.eclipse.org/org/documents/edl-v10.php
11   *
12   * All rights reserved.
13   *
14   * Redistribution and use in source and binary forms, with or
15   * without modification, are permitted provided that the following
16   * conditions are met:
17   *
18   * - Redistributions of source code must retain the above copyright
19   *   notice, this list of conditions and the following disclaimer.
20   *
21   * - Redistributions in binary form must reproduce the above
22   *   copyright notice, this list of conditions and the following
23   *   disclaimer in the documentation and/or other materials provided
24   *   with the distribution.
25   *
26   * - Neither the name of the Eclipse Foundation, Inc. nor the
27   *   names of its contributors may be used to endorse or promote
28   *   products derived from this software without specific prior
29   *   written permission.
30   *
31   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
32   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
33   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
36   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
40   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
43   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44   */
45  package org.eclipse.jgit.merge;
46  
47  import static org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm.HISTOGRAM;
48  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_DIFF_SECTION;
49  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_ALGORITHM;
50  import static org.eclipse.jgit.lib.Constants.CHARACTER_ENCODING;
51  import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
52  
53  import java.io.BufferedOutputStream;
54  import java.io.File;
55  import java.io.FileInputStream;
56  import java.io.FileNotFoundException;
57  import java.io.FileOutputStream;
58  import java.io.IOException;
59  import java.io.InputStream;
60  import java.io.OutputStream;
61  import java.util.ArrayList;
62  import java.util.Arrays;
63  import java.util.Collections;
64  import java.util.HashMap;
65  import java.util.Iterator;
66  import java.util.LinkedList;
67  import java.util.List;
68  import java.util.Map;
69  
70  import org.eclipse.jgit.diff.DiffAlgorithm;
71  import org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm;
72  import org.eclipse.jgit.diff.RawText;
73  import org.eclipse.jgit.diff.RawTextComparator;
74  import org.eclipse.jgit.diff.Sequence;
75  import org.eclipse.jgit.dircache.DirCache;
76  import org.eclipse.jgit.dircache.DirCacheBuildIterator;
77  import org.eclipse.jgit.dircache.DirCacheBuilder;
78  import org.eclipse.jgit.dircache.DirCacheCheckout;
79  import org.eclipse.jgit.dircache.DirCacheEntry;
80  import org.eclipse.jgit.errors.CorruptObjectException;
81  import org.eclipse.jgit.errors.IncorrectObjectTypeException;
82  import org.eclipse.jgit.errors.IndexWriteException;
83  import org.eclipse.jgit.errors.MissingObjectException;
84  import org.eclipse.jgit.errors.NoWorkTreeException;
85  import org.eclipse.jgit.lib.Config;
86  import org.eclipse.jgit.lib.FileMode;
87  import org.eclipse.jgit.lib.ObjectId;
88  import org.eclipse.jgit.lib.ObjectInserter;
89  import org.eclipse.jgit.lib.ObjectReader;
90  import org.eclipse.jgit.lib.Repository;
91  import org.eclipse.jgit.revwalk.RevTree;
92  import org.eclipse.jgit.treewalk.AbstractTreeIterator;
93  import org.eclipse.jgit.treewalk.CanonicalTreeParser;
94  import org.eclipse.jgit.treewalk.NameConflictTreeWalk;
95  import org.eclipse.jgit.treewalk.TreeWalk;
96  import org.eclipse.jgit.treewalk.WorkingTreeIterator;
97  import org.eclipse.jgit.treewalk.filter.TreeFilter;
98  import org.eclipse.jgit.util.FS;
99  import org.eclipse.jgit.util.TemporaryBuffer;
100 
101 /**
102  * A three-way merger performing a content-merge if necessary
103  */
104 public class ResolveMerger extends ThreeWayMerger {
105 	/**
106 	 * If the merge fails (means: not stopped because of unresolved conflicts)
107 	 * this enum is used to explain why it failed
108 	 */
109 	public enum MergeFailureReason {
110 		/** the merge failed because of a dirty index */
111 		DIRTY_INDEX,
112 		/** the merge failed because of a dirty workingtree */
113 		DIRTY_WORKTREE,
114 		/** the merge failed because of a file could not be deleted */
115 		COULD_NOT_DELETE
116 	}
117 
118 	/**
119 	 * The tree walk which we'll iterate over to merge entries.
120 	 *
121 	 * @since 3.4
122 	 */
123 	protected NameConflictTreeWalk tw;
124 
125 	/**
126 	 * string versions of a list of commit SHA1s
127 	 *
128 	 * @since 3.0
129 	 */
130 	protected String commitNames[];
131 
132 	/**
133 	 * Index of the base tree within the {@link #tw tree walk}.
134 	 *
135 	 * @since 3.4
136 	 */
137 	protected static final int T_BASE = 0;
138 
139 	/**
140 	 * Index of our tree in withthe {@link #tw tree walk}.
141 	 *
142 	 * @since 3.4
143 	 */
144 	protected static final int T_OURS = 1;
145 
146 	/**
147 	 * Index of their tree within the {@link #tw tree walk}.
148 	 *
149 	 * @since 3.4
150 	 */
151 	protected static final int T_THEIRS = 2;
152 
153 	/**
154 	 * Index of the index tree within the {@link #tw tree walk}.
155 	 *
156 	 * @since 3.4
157 	 */
158 	protected static final int T_INDEX = 3;
159 
160 	/**
161 	 * Index of the working directory tree within the {@link #tw tree walk}.
162 	 *
163 	 * @since 3.4
164 	 */
165 	protected static final int T_FILE = 4;
166 
167 	/**
168 	 * Builder to update the cache during this merge.
169 	 *
170 	 * @since 3.4
171 	 */
172 	protected DirCacheBuilder builder;
173 
174 	/**
175 	 * merge result as tree
176 	 *
177 	 * @since 3.0
178 	 */
179 	protected ObjectId resultTree;
180 
181 	/**
182 	 * Paths that could not be merged by this merger because of an unsolvable
183 	 * conflict.
184 	 *
185 	 * @since 3.4
186 	 */
187 	protected List<String> unmergedPaths = new ArrayList<>();
188 
189 	/**
190 	 * Files modified during this merge operation.
191 	 *
192 	 * @since 3.4
193 	 */
194 	protected List<String> modifiedFiles = new LinkedList<>();
195 
196 	/**
197 	 * If the merger has nothing to do for a file but check it out at the end of
198 	 * the operation, it can be added here.
199 	 *
200 	 * @since 3.4
201 	 */
202 	protected Map<String, DirCacheEntry> toBeCheckedOut = new HashMap<>();
203 
204 	/**
205 	 * Paths in this list will be deleted from the local copy at the end of the
206 	 * operation.
207 	 *
208 	 * @since 3.4
209 	 */
210 	protected List<String> toBeDeleted = new ArrayList<>();
211 
212 	/**
213 	 * Low-level textual merge results. Will be passed on to the callers in case
214 	 * of conflicts.
215 	 *
216 	 * @since 3.4
217 	 */
218 	protected Map<String, MergeResult<? extends Sequence>> mergeResults = new HashMap<>();
219 
220 	/**
221 	 * Paths for which the merge failed altogether.
222 	 *
223 	 * @since 3.4
224 	 */
225 	protected Map<String, MergeFailureReason> failingPaths = new HashMap<>();
226 
227 	/**
228 	 * Updated as we merge entries of the tree walk. Tells us whether we should
229 	 * recurse into the entry if it is a subtree.
230 	 *
231 	 * @since 3.4
232 	 */
233 	protected boolean enterSubtree;
234 
235 	/**
236 	 * Set to true if this merge should work in-memory. The repos dircache and
237 	 * workingtree are not touched by this method. Eventually needed files are
238 	 * created as temporary files and a new empty, in-memory dircache will be
239 	 * used instead the repo's one. Often used for bare repos where the repo
240 	 * doesn't even have a workingtree and dircache.
241 	 * @since 3.0
242 	 */
243 	protected boolean inCore;
244 
245 	/**
246 	 * Set to true if this merger should use the default dircache of the
247 	 * repository and should handle locking and unlocking of the dircache. If
248 	 * this merger should work in-core or if an explicit dircache was specified
249 	 * during construction then this field is set to false.
250 	 * @since 3.0
251 	 */
252 	protected boolean implicitDirCache;
253 
254 	/**
255 	 * Directory cache
256 	 * @since 3.0
257 	 */
258 	protected DirCache dircache;
259 
260 	/**
261 	 * The iterator to access the working tree. If set to <code>null</code> this
262 	 * merger will not touch the working tree.
263 	 * @since 3.0
264 	 */
265 	protected WorkingTreeIterator workingTreeIterator;
266 
267 	/**
268 	 * our merge algorithm
269 	 * @since 3.0
270 	 */
271 	protected MergeAlgorithm mergeAlgorithm;
272 
273 	private static MergeAlgorithm getMergeAlgorithm(Config config) {
274 		SupportedAlgorithm diffAlg = config.getEnum(
275 				CONFIG_DIFF_SECTION, null, CONFIG_KEY_ALGORITHM,
276 				HISTOGRAM);
277 		return new MergeAlgorithm(DiffAlgorithm.getAlgorithm(diffAlg));
278 	}
279 
280 	private static String[] defaultCommitNames() {
281 		return new String[] { "BASE", "OURS", "THEIRS" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
282 	}
283 
284 	/**
285 	 * @param local
286 	 * @param inCore
287 	 */
288 	protected ResolveMerger(Repository local, boolean inCore) {
289 		super(local);
290 		mergeAlgorithm = getMergeAlgorithm(local.getConfig());
291 		commitNames = defaultCommitNames();
292 		this.inCore = inCore;
293 
294 		if (inCore) {
295 			implicitDirCache = false;
296 			dircache = DirCache.newInCore();
297 		} else {
298 			implicitDirCache = true;
299 		}
300 	}
301 
302 	/**
303 	 * @param local
304 	 */
305 	protected ResolveMerger(Repository local) {
306 		this(local, false);
307 	}
308 
309 	/**
310 	 * @param inserter
311 	 * @param config
312 	 * @since 4.8
313 	 */
314 	protected ResolveMerger(ObjectInserter inserter, Config config) {
315 		super(inserter);
316 		mergeAlgorithm = getMergeAlgorithm(config);
317 		commitNames = defaultCommitNames();
318 		inCore = true;
319 		implicitDirCache = false;
320 		dircache = DirCache.newInCore();
321 	}
322 
323 	@Override
324 	protected boolean mergeImpl() throws IOException {
325 		if (implicitDirCache)
326 			dircache = nonNullRepo().lockDirCache();
327 
328 		try {
329 			return mergeTrees(mergeBase(), sourceTrees[0], sourceTrees[1],
330 					false);
331 		} finally {
332 			if (implicitDirCache)
333 				dircache.unlock();
334 		}
335 	}
336 
337 	private void checkout() throws NoWorkTreeException, IOException {
338 		// Iterate in reverse so that "folder/file" is deleted before
339 		// "folder". Otherwise this could result in a failing path because
340 		// of a non-empty directory, for which delete() would fail.
341 		for (int i = toBeDeleted.size() - 1; i >= 0; i--) {
342 			String fileName = toBeDeleted.get(i);
343 			File f = new File(nonNullRepo().getWorkTree(), fileName);
344 			if (!f.delete())
345 				if (!f.isDirectory())
346 					failingPaths.put(fileName,
347 							MergeFailureReason.COULD_NOT_DELETE);
348 			modifiedFiles.add(fileName);
349 		}
350 		for (Map.Entry<String, DirCacheEntry> entry : toBeCheckedOut
351 				.entrySet()) {
352 			DirCacheCheckout.checkoutEntry(db, entry.getValue(), reader);
353 			modifiedFiles.add(entry.getKey());
354 		}
355 	}
356 
357 	/**
358 	 * Reverts the worktree after an unsuccessful merge. We know that for all
359 	 * modified files the old content was in the old index and the index
360 	 * contained only stage 0. In case if inCore operation just clear the
361 	 * history of modified files.
362 	 *
363 	 * @throws IOException
364 	 * @throws CorruptObjectException
365 	 * @throws NoWorkTreeException
366 	 * @since 3.4
367 	 */
368 	protected void cleanUp() throws NoWorkTreeException,
369 			CorruptObjectException,
370 			IOException {
371 		if (inCore) {
372 			modifiedFiles.clear();
373 			return;
374 		}
375 
376 		DirCache dc = nonNullRepo().readDirCache();
377 		Iterator<String> mpathsIt=modifiedFiles.iterator();
378 		while(mpathsIt.hasNext()) {
379 			String mpath=mpathsIt.next();
380 			DirCacheEntry entry = dc.getEntry(mpath);
381 			if (entry != null)
382 				DirCacheCheckout.checkoutEntry(db, entry, reader);
383 			mpathsIt.remove();
384 		}
385 	}
386 
387 	/**
388 	 * adds a new path with the specified stage to the index builder
389 	 *
390 	 * @param path
391 	 * @param p
392 	 * @param stage
393 	 * @param lastMod
394 	 * @param len
395 	 * @return the entry which was added to the index
396 	 */
397 	private DirCacheEntry add(byte[] path, CanonicalTreeParser p, int stage,
398 			long lastMod, long len) {
399 		if (p != null && !p.getEntryFileMode().equals(FileMode.TREE)) {
400 			DirCacheEntry e = new DirCacheEntry(path, stage);
401 			e.setFileMode(p.getEntryFileMode());
402 			e.setObjectId(p.getEntryObjectId());
403 			e.setLastModified(lastMod);
404 			e.setLength(len);
405 			builder.add(e);
406 			return e;
407 		}
408 		return null;
409 	}
410 
411 	/**
412 	 * adds a entry to the index builder which is a copy of the specified
413 	 * DirCacheEntry
414 	 *
415 	 * @param e
416 	 *            the entry which should be copied
417 	 *
418 	 * @return the entry which was added to the index
419 	 */
420 	private DirCacheEntry keep(DirCacheEntry e) {
421 		DirCacheEntry newEntry = new DirCacheEntry(e.getPathString(),
422 				e.getStage());
423 		newEntry.setFileMode(e.getFileMode());
424 		newEntry.setObjectId(e.getObjectId());
425 		newEntry.setLastModified(e.getLastModified());
426 		newEntry.setLength(e.getLength());
427 		builder.add(newEntry);
428 		return newEntry;
429 	}
430 
431 	/**
432 	 * Processes one path and tries to merge. This method will do all do all
433 	 * trivial (not content) merges and will also detect if a merge will fail.
434 	 * The merge will fail when one of the following is true
435 	 * <ul>
436 	 * <li>the index entry does not match the entry in ours. When merging one
437 	 * branch into the current HEAD, ours will point to HEAD and theirs will
438 	 * point to the other branch. It is assumed that the index matches the HEAD
439 	 * because it will only not match HEAD if it was populated before the merge
440 	 * operation. But the merge commit should not accidentally contain
441 	 * modifications done before the merge. Check the <a href=
442 	 * "http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html#_3_way_merge"
443 	 * >git read-tree</a> documentation for further explanations.</li>
444 	 * <li>A conflict was detected and the working-tree file is dirty. When a
445 	 * conflict is detected the content-merge algorithm will try to write a
446 	 * merged version into the working-tree. If the file is dirty we would
447 	 * override unsaved data.</li>
448 	 * </ul>
449 	 *
450 	 * @param base
451 	 *            the common base for ours and theirs
452 	 * @param ours
453 	 *            the ours side of the merge. When merging a branch into the
454 	 *            HEAD ours will point to HEAD
455 	 * @param theirs
456 	 *            the theirs side of the merge. When merging a branch into the
457 	 *            current HEAD theirs will point to the branch which is merged
458 	 *            into HEAD.
459 	 * @param index
460 	 *            the index entry
461 	 * @param work
462 	 *            the file in the working tree
463 	 * @param ignoreConflicts
464 	 *            see
465 	 *            {@link ResolveMerger#mergeTrees(AbstractTreeIterator, RevTree, RevTree, boolean)}
466 	 * @return <code>false</code> if the merge will fail because the index entry
467 	 *         didn't match ours or the working-dir file was dirty and a
468 	 *         conflict occurred
469 	 * @throws MissingObjectException
470 	 * @throws IncorrectObjectTypeException
471 	 * @throws CorruptObjectException
472 	 * @throws IOException
473 	 * @since 3.5
474 	 */
475 	protected boolean processEntry(CanonicalTreeParser base,
476 			CanonicalTreeParser ours, CanonicalTreeParser theirs,
477 			DirCacheBuildIterator index, WorkingTreeIterator work,
478 			boolean ignoreConflicts)
479 			throws MissingObjectException, IncorrectObjectTypeException,
480 			CorruptObjectException, IOException {
481 		enterSubtree = true;
482 		final int modeO = tw.getRawMode(T_OURS);
483 		final int modeT = tw.getRawMode(T_THEIRS);
484 		final int modeB = tw.getRawMode(T_BASE);
485 
486 		if (modeO == 0 && modeT == 0 && modeB == 0)
487 			// File is either untracked or new, staged but uncommitted
488 			return true;
489 
490 		if (isIndexDirty())
491 			return false;
492 
493 		DirCacheEntry ourDce = null;
494 
495 		if (index == null || index.getDirCacheEntry() == null) {
496 			// create a fake DCE, but only if ours is valid. ours is kept only
497 			// in case it is valid, so a null ourDce is ok in all other cases.
498 			if (nonTree(modeO)) {
499 				ourDce = new DirCacheEntry(tw.getRawPath());
500 				ourDce.setObjectId(tw.getObjectId(T_OURS));
501 				ourDce.setFileMode(tw.getFileMode(T_OURS));
502 			}
503 		} else {
504 			ourDce = index.getDirCacheEntry();
505 		}
506 
507 		if (nonTree(modeO) && nonTree(modeT) && tw.idEqual(T_OURS, T_THEIRS)) {
508 			// OURS and THEIRS have equal content. Check the file mode
509 			if (modeO == modeT) {
510 				// content and mode of OURS and THEIRS are equal: it doesn't
511 				// matter which one we choose. OURS is chosen. Since the index
512 				// is clean (the index matches already OURS) we can keep the existing one
513 				keep(ourDce);
514 				// no checkout needed!
515 				return true;
516 			} else {
517 				// same content but different mode on OURS and THEIRS.
518 				// Try to merge the mode and report an error if this is
519 				// not possible.
520 				int newMode = mergeFileModes(modeB, modeO, modeT);
521 				if (newMode != FileMode.MISSING.getBits()) {
522 					if (newMode == modeO)
523 						// ours version is preferred
524 						keep(ourDce);
525 					else {
526 						// the preferred version THEIRS has a different mode
527 						// than ours. Check it out!
528 						if (isWorktreeDirty(work, ourDce))
529 							return false;
530 						// we know about length and lastMod only after we have written the new content.
531 						// This will happen later. Set these values to 0 for know.
532 						DirCacheEntry e = add(tw.getRawPath(), theirs,
533 								DirCacheEntry.STAGE_0, 0, 0);
534 						toBeCheckedOut.put(tw.getPathString(), e);
535 					}
536 					return true;
537 				} else {
538 					// FileModes are not mergeable. We found a conflict on modes.
539 					// For conflicting entries we don't know lastModified and length.
540 					add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
541 					add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0);
542 					add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0);
543 					unmergedPaths.add(tw.getPathString());
544 					mergeResults.put(
545 							tw.getPathString(),
546 							new MergeResult<>(Collections
547 									.<RawText> emptyList()));
548 				}
549 				return true;
550 			}
551 		}
552 
553 		if (modeB == modeT && tw.idEqual(T_BASE, T_THEIRS)) {
554 			// THEIRS was not changed compared to BASE. All changes must be in
555 			// OURS. OURS is chosen. We can keep the existing entry.
556 			if (ourDce != null)
557 				keep(ourDce);
558 			// no checkout needed!
559 			return true;
560 		}
561 
562 		if (modeB == modeO && tw.idEqual(T_BASE, T_OURS)) {
563 			// OURS was not changed compared to BASE. All changes must be in
564 			// THEIRS. THEIRS is chosen.
565 
566 			// Check worktree before checking out THEIRS
567 			if (isWorktreeDirty(work, ourDce))
568 				return false;
569 			if (nonTree(modeT)) {
570 				// we know about length and lastMod only after we have written
571 				// the new content.
572 				// This will happen later. Set these values to 0 for know.
573 				DirCacheEntry e = add(tw.getRawPath(), theirs,
574 						DirCacheEntry.STAGE_0, 0, 0);
575 				if (e != null)
576 					toBeCheckedOut.put(tw.getPathString(), e);
577 				return true;
578 			} else {
579 				// we want THEIRS ... but THEIRS contains a folder or the
580 				// deletion of the path. Delete what's in the workingtree (the
581 				// workingtree is clean) but do not complain if the file is
582 				// already deleted locally. This complements the test in
583 				// isWorktreeDirty() for the same case.
584 				if (tw.getTreeCount() > T_FILE && tw.getRawMode(T_FILE) == 0)
585 					return true;
586 				toBeDeleted.add(tw.getPathString());
587 				return true;
588 			}
589 		}
590 
591 		if (tw.isSubtree()) {
592 			// file/folder conflicts: here I want to detect only file/folder
593 			// conflict between ours and theirs. file/folder conflicts between
594 			// base/index/workingTree and something else are not relevant or
595 			// detected later
596 			if (nonTree(modeO) && !nonTree(modeT)) {
597 				if (nonTree(modeB))
598 					add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
599 				add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0);
600 				unmergedPaths.add(tw.getPathString());
601 				enterSubtree = false;
602 				return true;
603 			}
604 			if (nonTree(modeT) && !nonTree(modeO)) {
605 				if (nonTree(modeB))
606 					add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
607 				add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0);
608 				unmergedPaths.add(tw.getPathString());
609 				enterSubtree = false;
610 				return true;
611 			}
612 
613 			// ours and theirs are both folders or both files (and treewalk
614 			// tells us we are in a subtree because of index or working-dir).
615 			// If they are both folders no content-merge is required - we can
616 			// return here.
617 			if (!nonTree(modeO))
618 				return true;
619 
620 			// ours and theirs are both files, just fall out of the if block
621 			// and do the content merge
622 		}
623 
624 		if (nonTree(modeO) && nonTree(modeT)) {
625 			// Check worktree before modifying files
626 			if (isWorktreeDirty(work, ourDce))
627 				return false;
628 
629 			// Don't attempt to resolve submodule link conflicts
630 			if (isGitLink(modeO) || isGitLink(modeT)) {
631 				add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
632 				add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0);
633 				add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0);
634 				unmergedPaths.add(tw.getPathString());
635 				return true;
636 			}
637 
638 			MergeResult<RawText> result = contentMerge(base, ours, theirs);
639 			if (ignoreConflicts)
640 				result.setContainsConflicts(false);
641 			updateIndex(base, ours, theirs, result);
642 			if (result.containsConflicts() && !ignoreConflicts)
643 				unmergedPaths.add(tw.getPathString());
644 			modifiedFiles.add(tw.getPathString());
645 		} else if (modeO != modeT) {
646 			// OURS or THEIRS has been deleted
647 			if (((modeO != 0 && !tw.idEqual(T_BASE, T_OURS)) || (modeT != 0 && !tw
648 					.idEqual(T_BASE, T_THEIRS)))) {
649 
650 				add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
651 				add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0);
652 				DirCacheEntry e = add(tw.getRawPath(), theirs,
653 						DirCacheEntry.STAGE_3, 0, 0);
654 
655 				// OURS was deleted checkout THEIRS
656 				if (modeO == 0) {
657 					// Check worktree before checking out THEIRS
658 					if (isWorktreeDirty(work, ourDce))
659 						return false;
660 					if (nonTree(modeT)) {
661 						if (e != null)
662 							toBeCheckedOut.put(tw.getPathString(), e);
663 					}
664 				}
665 
666 				unmergedPaths.add(tw.getPathString());
667 
668 				// generate a MergeResult for the deleted file
669 				mergeResults.put(tw.getPathString(),
670 						contentMerge(base, ours, theirs));
671 			}
672 		}
673 		return true;
674 	}
675 
676 	/**
677 	 * Does the content merge. The three texts base, ours and theirs are
678 	 * specified with {@link CanonicalTreeParser}. If any of the parsers is
679 	 * specified as <code>null</code> then an empty text will be used instead.
680 	 *
681 	 * @param base
682 	 * @param ours
683 	 * @param theirs
684 	 *
685 	 * @return the result of the content merge
686 	 * @throws IOException
687 	 */
688 	private MergeResult<RawText> contentMerge(CanonicalTreeParser base,
689 			CanonicalTreeParser ours, CanonicalTreeParser theirs)
690 			throws IOException {
691 		RawText baseText = base == null ? RawText.EMPTY_TEXT : getRawText(
692 				base.getEntryObjectId(), reader);
693 		RawText ourText = ours == null ? RawText.EMPTY_TEXT : getRawText(
694 				ours.getEntryObjectId(), reader);
695 		RawText theirsText = theirs == null ? RawText.EMPTY_TEXT : getRawText(
696 				theirs.getEntryObjectId(), reader);
697 		return (mergeAlgorithm.merge(RawTextComparator.DEFAULT, baseText,
698 				ourText, theirsText));
699 	}
700 
701 	private boolean isIndexDirty() {
702 		if (inCore)
703 			return false;
704 
705 		final int modeI = tw.getRawMode(T_INDEX);
706 		final int modeO = tw.getRawMode(T_OURS);
707 
708 		// Index entry has to match ours to be considered clean
709 		final boolean isDirty = nonTree(modeI)
710 				&& !(modeO == modeI && tw.idEqual(T_INDEX, T_OURS));
711 		if (isDirty)
712 			failingPaths
713 					.put(tw.getPathString(), MergeFailureReason.DIRTY_INDEX);
714 		return isDirty;
715 	}
716 
717 	private boolean isWorktreeDirty(WorkingTreeIterator work,
718 			DirCacheEntry ourDce) throws IOException {
719 		if (work == null)
720 			return false;
721 
722 		final int modeF = tw.getRawMode(T_FILE);
723 		final int modeO = tw.getRawMode(T_OURS);
724 
725 		// Worktree entry has to match ours to be considered clean
726 		boolean isDirty;
727 		if (ourDce != null)
728 			isDirty = work.isModified(ourDce, true, reader);
729 		else {
730 			isDirty = work.isModeDifferent(modeO);
731 			if (!isDirty && nonTree(modeF))
732 				isDirty = !tw.idEqual(T_FILE, T_OURS);
733 		}
734 
735 		// Ignore existing empty directories
736 		if (isDirty && modeF == FileMode.TYPE_TREE
737 				&& modeO == FileMode.TYPE_MISSING)
738 			isDirty = false;
739 		if (isDirty)
740 			failingPaths.put(tw.getPathString(),
741 					MergeFailureReason.DIRTY_WORKTREE);
742 		return isDirty;
743 	}
744 
745 	/**
746 	 * Updates the index after a content merge has happened. If no conflict has
747 	 * occurred this includes persisting the merged content to the object
748 	 * database. In case of conflicts this method takes care to write the
749 	 * correct stages to the index.
750 	 *
751 	 * @param base
752 	 * @param ours
753 	 * @param theirs
754 	 * @param result
755 	 * @throws FileNotFoundException
756 	 * @throws IOException
757 	 */
758 	private void updateIndex(CanonicalTreeParser base,
759 			CanonicalTreeParser ours, CanonicalTreeParser theirs,
760 			MergeResult<RawText> result) throws FileNotFoundException,
761 			IOException {
762 		File mergedFile = !inCore ? writeMergedFile(result) : null;
763 		if (result.containsConflicts()) {
764 			// A conflict occurred, the file will contain conflict markers
765 			// the index will be populated with the three stages and the
766 			// workdir (if used) contains the halfway merged content.
767 			add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
768 			add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0);
769 			add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0);
770 			mergeResults.put(tw.getPathString(), result);
771 			return;
772 		}
773 
774 		// No conflict occurred, the file will contain fully merged content.
775 		// The index will be populated with the new merged version.
776 		DirCacheEntry dce = new DirCacheEntry(tw.getPathString());
777 
778 		// Set the mode for the new content. Fall back to REGULAR_FILE if
779 		// we can't merge modes of OURS and THEIRS.
780 		int newMode = mergeFileModes(
781 				tw.getRawMode(0),
782 				tw.getRawMode(1),
783 				tw.getRawMode(2));
784 		dce.setFileMode(newMode == FileMode.MISSING.getBits()
785 				? FileMode.REGULAR_FILE
786 				: FileMode.fromBits(newMode));
787 		if (mergedFile != null) {
788 			long len = mergedFile.length();
789 			dce.setLastModified(FS.DETECTED.lastModified(mergedFile));
790 			dce.setLength((int) len);
791 			InputStream is = new FileInputStream(mergedFile);
792 			try {
793 				dce.setObjectId(getObjectInserter().insert(OBJ_BLOB, len, is));
794 			} finally {
795 				is.close();
796 			}
797 		} else
798 			dce.setObjectId(insertMergeResult(result));
799 		builder.add(dce);
800 	}
801 
802 	/**
803 	 * Writes merged file content to the working tree.
804 	 *
805 	 * @param result
806 	 *            the result of the content merge
807 	 * @return the working tree file to which the merged content was written.
808 	 * @throws FileNotFoundException
809 	 * @throws IOException
810 	 */
811 	private File writeMergedFile(MergeResult<RawText> result)
812 			throws FileNotFoundException, IOException {
813 		File workTree = nonNullRepo().getWorkTree();
814 		FS fs = nonNullRepo().getFS();
815 		File of = new File(workTree, tw.getPathString());
816 		File parentFolder = of.getParentFile();
817 		if (!fs.exists(parentFolder))
818 			parentFolder.mkdirs();
819 		try (OutputStream os = new BufferedOutputStream(
820 				new FileOutputStream(of))) {
821 			new MergeFormatter().formatMerge(os, result,
822 					Arrays.asList(commitNames), CHARACTER_ENCODING);
823 		}
824 		return of;
825 	}
826 
827 	private ObjectId insertMergeResult(MergeResult<RawText> result)
828 			throws IOException {
829 		TemporaryBuffer.LocalFile buf = new TemporaryBuffer.LocalFile(
830 				db != null ? nonNullRepo().getDirectory() : null, 10 << 20);
831 		try {
832 			new MergeFormatter().formatMerge(buf, result,
833 					Arrays.asList(commitNames), CHARACTER_ENCODING);
834 			buf.close();
835 			try (InputStream in = buf.openInputStream()) {
836 				return getObjectInserter().insert(OBJ_BLOB, buf.length(), in);
837 			}
838 		} finally {
839 			buf.destroy();
840 		}
841 	}
842 
843 	/**
844 	 * Try to merge filemodes. If only ours or theirs have changed the mode
845 	 * (compared to base) we choose that one. If ours and theirs have equal
846 	 * modes return that one. If also that is not the case the modes are not
847 	 * mergeable. Return {@link FileMode#MISSING} int that case.
848 	 *
849 	 * @param modeB
850 	 *            filemode found in BASE
851 	 * @param modeO
852 	 *            filemode found in OURS
853 	 * @param modeT
854 	 *            filemode found in THEIRS
855 	 *
856 	 * @return the merged filemode or {@link FileMode#MISSING} in case of a
857 	 *         conflict
858 	 */
859 	private int mergeFileModes(int modeB, int modeO, int modeT) {
860 		if (modeO == modeT)
861 			return modeO;
862 		if (modeB == modeO)
863 			// Base equal to Ours -> chooses Theirs if that is not missing
864 			return (modeT == FileMode.MISSING.getBits()) ? modeO : modeT;
865 		if (modeB == modeT)
866 			// Base equal to Theirs -> chooses Ours if that is not missing
867 			return (modeO == FileMode.MISSING.getBits()) ? modeT : modeO;
868 		return FileMode.MISSING.getBits();
869 	}
870 
871 	private static RawText getRawText(ObjectId id, ObjectReader reader)
872 			throws IOException {
873 		if (id.equals(ObjectId.zeroId()))
874 			return new RawText(new byte[] {});
875 		return new RawText(reader.open(id, OBJ_BLOB).getCachedBytes());
876 	}
877 
878 	private static boolean nonTree(final int mode) {
879 		return mode != 0 && !FileMode.TREE.equals(mode);
880 	}
881 
882 	private static boolean isGitLink(final int mode) {
883 		return FileMode.GITLINK.equals(mode);
884 	}
885 
886 	@Override
887 	public ObjectId getResultTreeId() {
888 		return (resultTree == null) ? null : resultTree.toObjectId();
889 	}
890 
891 	/**
892 	 * @param commitNames
893 	 *            the names of the commits as they would appear in conflict
894 	 *            markers
895 	 */
896 	public void setCommitNames(String[] commitNames) {
897 		this.commitNames = commitNames;
898 	}
899 
900 	/**
901 	 * @return the names of the commits as they would appear in conflict
902 	 *         markers.
903 	 */
904 	public String[] getCommitNames() {
905 		return commitNames;
906 	}
907 
908 	/**
909 	 * @return the paths with conflicts. This is a subset of the files listed
910 	 *         by {@link #getModifiedFiles()}
911 	 */
912 	public List<String> getUnmergedPaths() {
913 		return unmergedPaths;
914 	}
915 
916 	/**
917 	 * @return the paths of files which have been modified by this merge. A
918 	 *         file will be modified if a content-merge works on this path or if
919 	 *         the merge algorithm decides to take the theirs-version. This is a
920 	 *         superset of the files listed by {@link #getUnmergedPaths()}.
921 	 */
922 	public List<String> getModifiedFiles() {
923 		return modifiedFiles;
924 	}
925 
926 	/**
927 	 * @return a map which maps the paths of files which have to be checked out
928 	 *         because the merge created new fully-merged content for this file
929 	 *         into the index. This means: the merge wrote a new stage 0 entry
930 	 *         for this path.
931 	 */
932 	public Map<String, DirCacheEntry> getToBeCheckedOut() {
933 		return toBeCheckedOut;
934 	}
935 
936 	/**
937 	 * @return the mergeResults
938 	 */
939 	public Map<String, MergeResult<? extends Sequence>> getMergeResults() {
940 		return mergeResults;
941 	}
942 
943 	/**
944 	 * @return lists paths causing this merge to fail (not stopped because of a
945 	 *         conflict). <code>null</code> is returned if this merge didn't
946 	 *         fail.
947 	 */
948 	public Map<String, MergeFailureReason> getFailingPaths() {
949 		return (failingPaths.size() == 0) ? null : failingPaths;
950 	}
951 
952 	/**
953 	 * Returns whether this merge failed (i.e. not stopped because of a
954 	 * conflict)
955 	 *
956 	 * @return <code>true</code> if a failure occurred, <code>false</code>
957 	 *         otherwise
958 	 */
959 	public boolean failed() {
960 		return failingPaths.size() > 0;
961 	}
962 
963 	/**
964 	 * Sets the DirCache which shall be used by this merger. If the DirCache is
965 	 * not set explicitly and if this merger doesn't work in-core, this merger
966 	 * will implicitly get and lock a default DirCache. If the DirCache is
967 	 * explicitly set the caller is responsible to lock it in advance. Finally
968 	 * the merger will call {@link DirCache#commit()} which requires that the
969 	 * DirCache is locked. If the {@link #mergeImpl()} returns without throwing
970 	 * an exception the lock will be released. In case of exceptions the caller
971 	 * is responsible to release the lock.
972 	 *
973 	 * @param dc
974 	 *            the DirCache to set
975 	 */
976 	public void setDirCache(DirCache dc) {
977 		this.dircache = dc;
978 		implicitDirCache = false;
979 	}
980 
981 	/**
982 	 * Sets the WorkingTreeIterator to be used by this merger. If no
983 	 * WorkingTreeIterator is set this merger will ignore the working tree and
984 	 * fail if a content merge is necessary.
985 	 * <p>
986 	 * TODO: enhance WorkingTreeIterator to support write operations. Then this
987 	 * merger will be able to merge with a different working tree abstraction.
988 	 *
989 	 * @param workingTreeIterator
990 	 *            the workingTreeIt to set
991 	 */
992 	public void setWorkingTreeIterator(WorkingTreeIterator workingTreeIterator) {
993 		this.workingTreeIterator = workingTreeIterator;
994 	}
995 
996 
997 	/**
998 	 * The resolve conflict way of three way merging
999 	 *
1000 	 * @param baseTree
1001 	 * @param headTree
1002 	 * @param mergeTree
1003 	 * @param ignoreConflicts
1004 	 *            Controls what to do in case a content-merge is done and a
1005 	 *            conflict is detected. The default setting for this should be
1006 	 *            <code>false</code>. In this case the working tree file is
1007 	 *            filled with new content (containing conflict markers) and the
1008 	 *            index is filled with multiple stages containing BASE, OURS and
1009 	 *            THEIRS content. Having such non-0 stages is the sign to git
1010 	 *            tools that there are still conflicts for that path.
1011 	 *            <p>
1012 	 *            If <code>true</code> is specified the behavior is different.
1013 	 *            In case a conflict is detected the working tree file is again
1014 	 *            filled with new content (containing conflict markers). But
1015 	 *            also stage 0 of the index is filled with that content. No
1016 	 *            other stages are filled. Means: there is no conflict on that
1017 	 *            path but the new content (including conflict markers) is
1018 	 *            stored as successful merge result. This is needed in the
1019 	 *            context of {@link RecursiveMerger} where when determining
1020 	 *            merge bases we don't want to deal with content-merge
1021 	 *            conflicts.
1022 	 * @return whether the trees merged cleanly
1023 	 * @throws IOException
1024 	 * @since 3.5
1025 	 */
1026 	protected boolean mergeTrees(AbstractTreeIterator baseTree,
1027 			RevTree headTree, RevTree mergeTree, boolean ignoreConflicts)
1028 			throws IOException {
1029 
1030 		builder = dircache.builder();
1031 		DirCacheBuildIterator buildIt = new DirCacheBuildIterator(builder);
1032 
1033 		tw = new NameConflictTreeWalk(db, reader);
1034 		tw.addTree(baseTree);
1035 		tw.addTree(headTree);
1036 		tw.addTree(mergeTree);
1037 		int dciPos = tw.addTree(buildIt);
1038 		if (workingTreeIterator != null) {
1039 			tw.addTree(workingTreeIterator);
1040 			workingTreeIterator.setDirCacheIterator(tw, dciPos);
1041 		} else {
1042 			tw.setFilter(TreeFilter.ANY_DIFF);
1043 		}
1044 
1045 		if (!mergeTreeWalk(tw, ignoreConflicts)) {
1046 			return false;
1047 		}
1048 
1049 		if (!inCore) {
1050 			// No problem found. The only thing left to be done is to
1051 			// checkout all files from "theirs" which have been selected to
1052 			// go into the new index.
1053 			checkout();
1054 
1055 			// All content-merges are successfully done. If we can now write the
1056 			// new index we are on quite safe ground. Even if the checkout of
1057 			// files coming from "theirs" fails the user can work around such
1058 			// failures by checking out the index again.
1059 			if (!builder.commit()) {
1060 				cleanUp();
1061 				throw new IndexWriteException();
1062 			}
1063 			builder = null;
1064 
1065 		} else {
1066 			builder.finish();
1067 			builder = null;
1068 		}
1069 
1070 		if (getUnmergedPaths().isEmpty() && !failed()) {
1071 			resultTree = dircache.writeTree(getObjectInserter());
1072 			return true;
1073 		} else {
1074 			resultTree = null;
1075 			return false;
1076 		}
1077 	}
1078 
1079 	/**
1080 	 * Process the given TreeWalk's entries.
1081 	 *
1082 	 * @param treeWalk
1083 	 *            The walk to iterate over.
1084 	 * @param ignoreConflicts
1085 	 *            see
1086 	 *            {@link ResolveMerger#mergeTrees(AbstractTreeIterator, RevTree, RevTree, boolean)}
1087 	 * @return Whether the trees merged cleanly.
1088 	 * @throws IOException
1089 	 * @since 3.5
1090 	 */
1091 	protected boolean mergeTreeWalk(TreeWalk treeWalk, boolean ignoreConflicts)
1092 			throws IOException {
1093 		boolean hasWorkingTreeIterator = tw.getTreeCount() > T_FILE;
1094 		while (treeWalk.next()) {
1095 			if (!processEntry(
1096 					treeWalk.getTree(T_BASE, CanonicalTreeParser.class),
1097 					treeWalk.getTree(T_OURS, CanonicalTreeParser.class),
1098 					treeWalk.getTree(T_THEIRS, CanonicalTreeParser.class),
1099 					treeWalk.getTree(T_INDEX, DirCacheBuildIterator.class),
1100 					hasWorkingTreeIterator ? treeWalk.getTree(T_FILE,
1101 							WorkingTreeIterator.class) : null, ignoreConflicts)) {
1102 				cleanUp();
1103 				return false;
1104 			}
1105 			if (treeWalk.isSubtree() && enterSubtree)
1106 				treeWalk.enterSubtree();
1107 		}
1108 		return true;
1109 	}
1110 }