1 /*******************************************************************************
2 * Copyright (c) 2012-2013 University of Stuttgart.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * and the Apache License 2.0 which both accompany this distribution,
6 * and are available at http://www.eclipse.org/legal/epl-v10.html
7 * and http://www.apache.org/licenses/LICENSE-2.0
10 * Oliver Kopp - initial API and implementation
11 *******************************************************************************/
12 package org.eclipse.winery.repository.backend.filebased;
15 import java.io.FileInputStream;
16 import java.io.FileNotFoundException;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.util.Properties;
21 import org.eclipse.jgit.api.AddCommand;
22 import org.eclipse.jgit.api.CleanCommand;
23 import org.eclipse.jgit.api.CommitCommand;
24 import org.eclipse.jgit.api.FetchCommand;
25 import org.eclipse.jgit.api.Git;
26 import org.eclipse.jgit.api.PushCommand;
27 import org.eclipse.jgit.api.ResetCommand;
28 import org.eclipse.jgit.api.ResetCommand.ResetType;
29 import org.eclipse.jgit.api.errors.CheckoutConflictException;
30 import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
31 import org.eclipse.jgit.api.errors.GitAPIException;
32 import org.eclipse.jgit.api.errors.NoHeadException;
33 import org.eclipse.jgit.api.errors.NoMessageException;
34 import org.eclipse.jgit.api.errors.UnmergedPathsException;
35 import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
36 import org.eclipse.jgit.errors.NoWorkTreeException;
37 import org.eclipse.jgit.lib.Repository;
38 import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
39 import org.eclipse.jgit.transport.CredentialsProvider;
40 import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
41 import org.eclipse.winery.repository.Prefs;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
46 * Used for testing only.
48 * Allows to reset repository to a certain commit id
50 public class GitBasedRepository extends FilebasedRepository {
52 private static final Logger logger = LoggerFactory.getLogger(GitBasedRepository.class);
54 private final Repository gitRepo;
55 private final Git git;
56 private final CredentialsProvider cp;
58 public static final String PREFERENCE_GIT_USERNAME = "git.username";
59 public static final String PREFERENCE_GIT_PASSWORD = "git.password";
63 * @param repositoryLocation the location of the repository
64 * @throws IOException thrown if repository does not exist
66 public GitBasedRepository(String repositoryLocation) throws IOException {
67 super(repositoryLocation);
68 FileRepositoryBuilder builder = new FileRepositoryBuilder();
69 this.gitRepo = builder.setWorkTree(this.repositoryRoot.toFile()).setMustExist(true).build();
70 this.git = new Git(this.gitRepo);
72 this.cp = this.initializeCredentialsProvider();
76 * Reads the properties stored in ".winery" in the repository
78 private Properties dotWineryProperties() {
79 Properties p = new Properties();
80 File f = new File(this.repositoryRoot.toFile(), ".winery");
83 is = new FileInputStream(f);
84 } catch (FileNotFoundException e1) {
85 // .winery does not exist in the file-based repository
91 } catch (IOException e) {
92 GitBasedRepository.logger.debug(e.getMessage(), e);
99 * Uses git.username und git.password from .winery and winery.properties
101 * Considering .winery is useful if the same war file is used on a dev
102 * server and a stable server. The WAR file cannot contain the credentials
103 * if committing is only allowed on only one of these servers
105 private CredentialsProvider initializeCredentialsProvider() {
106 CredentialsProvider cp;
108 Properties wp = this.dotWineryProperties();
110 String gitUserName = wp.getProperty(GitBasedRepository.PREFERENCE_GIT_USERNAME);
111 if (gitUserName == null) {
112 gitUserName = Prefs.INSTANCE.getProperties().getProperty(GitBasedRepository.PREFERENCE_GIT_USERNAME);
115 String gitPassword = wp.getProperty(GitBasedRepository.PREFERENCE_GIT_PASSWORD);
116 if (gitPassword == null) {
117 gitPassword = Prefs.INSTANCE.getProperties().getProperty(GitBasedRepository.PREFERENCE_GIT_PASSWORD);
120 if (gitUserName == null) {
122 } else if (gitPassword == null) {
125 cp = new UsernamePasswordCredentialsProvider(gitUserName, gitPassword);
130 public void addCommitPush() throws NoHeadException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, GitAPIException {
131 AddCommand add = this.git.add();
132 add.addFilepattern(".");
135 CommitCommand commit = this.git.commit();
136 commit.setMessage("Commit through Winery");
139 PushCommand push = this.git.push();
140 if (this.cp != null) {
141 push.setCredentialsProvider(this.cp);
146 private void clean() throws NoWorkTreeException, GitAPIException {
147 GitBasedRepository.logger.trace("git clean");
148 // remove untracked files
149 CleanCommand clean = this.git.clean();
150 clean.setCleanDirectories(true);
154 public void cleanAndResetHard() throws NoWorkTreeException, GitAPIException {
155 // enable updating by resetting the content of the repository
158 // fetch the newest thing from upstream
159 GitBasedRepository.logger.trace("git fetch");
160 FetchCommand fetch = this.git.fetch();
161 if (this.cp != null) {
162 fetch.setCredentialsProvider(this.cp);
166 // after fetching, reset to the latest version
167 GitBasedRepository.logger.trace("git reset --hard");
168 ResetCommand reset = this.git.reset();
169 reset.setMode(ResetType.HARD);
173 public void setRevisionTo(String ref) throws CheckoutConflictException, GitAPIException {
176 // reset repository to the desired reference
177 ResetCommand reset = this.git.reset();
178 reset.setMode(ResetType.HARD);
184 * Returns true if authentification information (for instance, to push to
185 * upstream) is available
187 public boolean authenticationInfoAvailable() {
188 return this.cp != null;