1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.merge;
12
13 import java.io.IOException;
14
15 import org.eclipse.jgit.dircache.DirCache;
16 import org.eclipse.jgit.dircache.DirCacheBuilder;
17 import org.eclipse.jgit.dircache.DirCacheEntry;
18 import org.eclipse.jgit.errors.UnmergedPathException;
19 import org.eclipse.jgit.lib.Config;
20 import org.eclipse.jgit.lib.FileMode;
21 import org.eclipse.jgit.lib.ObjectId;
22 import org.eclipse.jgit.lib.ObjectInserter;
23 import org.eclipse.jgit.lib.Repository;
24 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
25 import org.eclipse.jgit.treewalk.NameConflictTreeWalk;
26
27
28
29
30
31
32
33
34
35
36
37
38 public class StrategySimpleTwoWayInCore extends ThreeWayMergeStrategy {
39
40
41
42 protected StrategySimpleTwoWayInCore() {
43
44 }
45
46
47 @Override
48 public String getName() {
49 return "simple-two-way-in-core";
50 }
51
52
53 @Override
54 public ThreeWayMerger newMerger(Repository db) {
55 return new InCoreMerger(db);
56 }
57
58
59 @Override
60 public ThreeWayMerger newMerger(Repository db, boolean inCore) {
61
62 return newMerger(db);
63 }
64
65
66 @Override
67 public ThreeWayMerger newMerger(ObjectInserter inserter, Config config) {
68 return new InCoreMerger(inserter);
69 }
70
71 private static class InCoreMerger extends ThreeWayMerger {
72 private static final int T_BASE = 0;
73
74 private static final int T_OURS = 1;
75
76 private static final int T_THEIRS = 2;
77
78 private final NameConflictTreeWalk tw;
79
80 private final DirCache cache;
81
82 private DirCacheBuilder builder;
83
84 private ObjectId resultTree;
85
86 InCoreMerger(Repository local) {
87 super(local);
88 tw = new NameConflictTreeWalk(local, reader);
89 cache = DirCache.newInCore();
90 }
91
92 InCoreMerger(ObjectInserter inserter) {
93 super(inserter);
94 tw = new NameConflictTreeWalk(null, reader);
95 cache = DirCache.newInCore();
96 }
97
98 @Override
99 protected boolean mergeImpl() throws IOException {
100 tw.addTree(mergeBase());
101 tw.addTree(sourceTrees[0]);
102 tw.addTree(sourceTrees[1]);
103
104 boolean hasConflict = false;
105 builder = cache.builder();
106 while (tw.next()) {
107 final int modeO = tw.getRawMode(T_OURS);
108 final int modeT = tw.getRawMode(T_THEIRS);
109 if (modeO == modeT && tw.idEqual(T_OURS, T_THEIRS)) {
110 add(T_OURS, DirCacheEntry.STAGE_0);
111 continue;
112 }
113
114 final int modeB = tw.getRawMode(T_BASE);
115 if (modeB == modeO && tw.idEqual(T_BASE, T_OURS))
116 add(T_THEIRS, DirCacheEntry.STAGE_0);
117 else if (modeB == modeT && tw.idEqual(T_BASE, T_THEIRS))
118 add(T_OURS, DirCacheEntry.STAGE_0);
119 else {
120 if (nonTree(modeB)) {
121 add(T_BASE, DirCacheEntry.STAGE_1);
122 hasConflict = true;
123 }
124 if (nonTree(modeO)) {
125 add(T_OURS, DirCacheEntry.STAGE_2);
126 hasConflict = true;
127 }
128 if (nonTree(modeT)) {
129 add(T_THEIRS, DirCacheEntry.STAGE_3);
130 hasConflict = true;
131 }
132 if (tw.isSubtree())
133 tw.enterSubtree();
134 }
135 }
136 builder.finish();
137 builder = null;
138
139 if (hasConflict)
140 return false;
141 try {
142 ObjectInserter odi = getObjectInserter();
143 resultTree = cache.writeTree(odi);
144 odi.flush();
145 return true;
146 } catch (UnmergedPathException upe) {
147 resultTree = null;
148 return false;
149 }
150 }
151
152 private static boolean nonTree(int mode) {
153 return mode != 0 && !FileMode.TREE.equals(mode);
154 }
155
156 private void add(int tree, int stage) throws IOException {
157 final AbstractTreeIterator i = getTree(tree);
158 if (i != null) {
159 if (FileMode.TREE.equals(tw.getRawMode(tree))) {
160 builder.addTree(tw.getRawPath(), stage, reader, tw
161 .getObjectId(tree));
162 } else {
163 final DirCacheEntry e;
164
165 e = new DirCacheEntry(tw.getRawPath(), stage);
166 e.setObjectIdFromRaw(i.idBuffer(), i.idOffset());
167 e.setFileMode(tw.getFileMode(tree));
168 builder.add(e);
169 }
170 }
171 }
172
173 private AbstractTreeIterator getTree(int tree) {
174 return tw.getTree(tree, AbstractTreeIterator.class);
175 }
176
177 @Override
178 public ObjectId getResultTreeId() {
179 return resultTree;
180 }
181 }
182
183 }