Add a merge command to the jgit API
[jgit.git] / org.eclipse.jgit.test / tst / org / eclipse / jgit / api / MergeCommandTest.java
blobc965c67664603e8e549a88e7ee8f06b9d6d0217b
1 /*
2 * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
3 * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>
4 * and other copyright owners as documented in the project's IP log.
6 * This program and the accompanying materials are made available
7 * under the terms of the Eclipse Distribution License v1.0 which
8 * accompanies this distribution, is reproduced below, and is
9 * available at http://www.eclipse.org/org/documents/edl-v10.php
11 * All rights reserved.
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
15 * conditions are met:
17 * - Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials provided
23 * with the distribution.
25 * - Neither the name of the Eclipse Foundation, Inc. nor the
26 * names of its contributors may be used to endorse or promote
27 * products derived from this software without specific prior
28 * written permission.
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
31 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
32 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
35 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
37 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
39 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
42 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 package org.eclipse.jgit.api;
46 import java.io.File;
47 import java.io.IOException;
49 import org.eclipse.jgit.errors.CheckoutConflictException;
50 import org.eclipse.jgit.errors.CorruptObjectException;
51 import org.eclipse.jgit.lib.Constants;
52 import org.eclipse.jgit.lib.GitIndex;
53 import org.eclipse.jgit.lib.ObjectId;
54 import org.eclipse.jgit.lib.RefUpdate;
55 import org.eclipse.jgit.lib.RepositoryTestCase;
56 import org.eclipse.jgit.lib.WorkDirCheckout;
57 import org.eclipse.jgit.lib.GitIndex.Entry;
58 import org.eclipse.jgit.revwalk.RevCommit;
60 public class MergeCommandTest extends RepositoryTestCase {
62 public void testMergeInItself() throws Exception {
63 Git git = new Git(db);
64 git.commit().setMessage("initial commit").call();
66 MergeResult result = git.merge().include(db.getRef(Constants.HEAD)).call();
67 assertEquals(MergeResult.MergeStatus.ALREADY_UP_TO_DATE, result.getMergeStatus());
70 public void testAlreadyUpToDate() throws Exception {
71 Git git = new Git(db);
72 RevCommit first = git.commit().setMessage("initial commit").call();
73 createBranch(first, "refs/heads/branch1");
75 RevCommit second = git.commit().setMessage("second commit").call();
76 MergeResult result = git.merge().include(db.getRef("refs/heads/branch1")).call();
77 assertEquals(MergeResult.MergeStatus.ALREADY_UP_TO_DATE, result.getMergeStatus());
78 assertEquals(second, result.getNewHead());
82 public void testFastForward() throws Exception {
83 Git git = new Git(db);
84 RevCommit first = git.commit().setMessage("initial commit").call();
85 createBranch(first, "refs/heads/branch1");
87 RevCommit second = git.commit().setMessage("second commit").call();
89 checkoutBranch("refs/heads/branch1");
91 MergeResult result = git.merge().include(db.getRef(Constants.MASTER)).call();
93 assertEquals(MergeResult.MergeStatus.FAST_FORWARD, result.getMergeStatus());
94 assertEquals(second, result.getNewHead());
97 public void testFastForwardWithFiles() throws Exception {
98 Git git = new Git(db);
100 addNewFileToIndex("file1");
101 RevCommit first = git.commit().setMessage("initial commit").call();
103 assertTrue(new File(db.getWorkDir(), "file1").exists());
104 createBranch(first, "refs/heads/branch1");
106 addNewFileToIndex("file2");
107 RevCommit second = git.commit().setMessage("second commit").call();
108 assertTrue(new File(db.getWorkDir(), "file2").exists());
110 checkoutBranch("refs/heads/branch1");
111 assertFalse(new File(db.getWorkDir(), "file2").exists());
113 MergeResult result = git.merge().include(db.getRef(Constants.MASTER)).call();
115 assertTrue(new File(db.getWorkDir(), "file1").exists());
116 assertTrue(new File(db.getWorkDir(), "file2").exists());
117 assertEquals(MergeResult.MergeStatus.FAST_FORWARD, result.getMergeStatus());
118 assertEquals(second, result.getNewHead());
121 public void testMultipleHeads() throws Exception {
122 Git git = new Git(db);
124 addNewFileToIndex("file1");
125 RevCommit first = git.commit().setMessage("initial commit").call();
126 createBranch(first, "refs/heads/branch1");
128 addNewFileToIndex("file2");
129 RevCommit second = git.commit().setMessage("second commit").call();
131 addNewFileToIndex("file3");
132 git.commit().setMessage("third commit").call();
134 checkoutBranch("refs/heads/branch1");
135 assertFalse(new File(db.getWorkDir(), "file2").exists());
136 assertFalse(new File(db.getWorkDir(), "file3").exists());
138 MergeCommand merge = git.merge();
139 merge.include(second.getId());
140 merge.include(db.getRef(Constants.MASTER));
141 try {
142 merge.call();
143 fail("Expected exception not thrown when merging multiple heads");
144 } catch (InvalidMergeHeadsException e) {
148 private void createBranch(ObjectId objectId, String branchName) throws IOException {
149 RefUpdate updateRef = db.updateRef(branchName);
150 updateRef.setNewObjectId(objectId);
151 updateRef.update();
154 private void checkoutBranch(String branchName) throws Exception {
155 File workDir = db.getWorkDir();
156 if (workDir != null) {
157 WorkDirCheckout workDirCheckout = new WorkDirCheckout(db,
158 workDir, db.mapCommit(Constants.HEAD).getTree(),
159 db.getIndex(), db.mapCommit(branchName).getTree());
160 workDirCheckout.setFailOnConflict(true);
161 try {
162 workDirCheckout.checkout();
163 } catch (CheckoutConflictException e) {
164 throw new JGitInternalException(
165 "Couldn't check out because of conflicts", e);
169 // update the HEAD
170 RefUpdate refUpdate = db.updateRef(Constants.HEAD);
171 refUpdate.link(branchName);
174 private void addNewFileToIndex(String filename) throws IOException,
175 CorruptObjectException {
176 File writeTrashFile = writeTrashFile(filename, filename);
178 GitIndex index = db.getIndex();
179 Entry entry = index.add(db.getWorkDir(), writeTrashFile);
180 entry.update(writeTrashFile);
181 index.write();