Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 73a2f1ae89c8f5c9a5b0a00922ab8acf8a93d01b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*******************************************************************************
 * Copyright (C) 2011, 2012 Dariusz Luksza <dariusz@luksza.org> and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.egit.ui.internal.actions;

import static org.eclipse.egit.core.synchronize.dto.GitSynchronizeData.BRANCH_NAME_PATTERN;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_BRANCH_SECTION;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MERGE;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REMOTE;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import static org.eclipse.jgit.lib.Constants.R_REMOTES;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.internal.synchronize.GitModelSynchronize;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;

/**
 * An action that launch synchronization with selected repository
 */
public class SynchronizeWorkspaceActionHandler extends RepositoryActionHandler {

	@Override
	public boolean isEnabled() {
		return true;
	}

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		IResource[] resources = getSelectedResources(event);
		Map<Repository, Set<IResource>> containerMap = mapContainerResources(resources);

		if (containerMap.isEmpty())
			return null;

		boolean launchFetch = Activator.getDefault().getPreferenceStore()
				.getBoolean(UIPreferences.SYNC_VIEW_FETCH_BEFORE_LAUNCH);
		GitSynchronizeDataSet gsdSet = new GitSynchronizeDataSet();
		for (Entry<Repository, Set<IResource>> entry : containerMap.entrySet())
			try {
				Repository repo = entry.getKey();
				String dstRef = getDstRef(repo, launchFetch);
				GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, dstRef, true);
				Set<IResource> containers = entry.getValue();
				if (!containers.isEmpty())
					data.setIncludedResources(containers);

				gsdSet.add(data);
			} catch (IOException e) {
				Activator.handleError(e.getMessage(), e, true);
			}

		GitModelSynchronize.launch(gsdSet, getSelectedResources(event));

		return null;
	}

	private Map<Repository, Set<IResource>> mapContainerResources(
			IResource[] resources) {
		Map<Repository, Set<IResource>> result = new HashMap<>();

		for (IResource resource : resources) {
			RepositoryMapping rm = RepositoryMapping.getMapping(resource);
			if (rm == null)
				continue; // Linked resources may not be in a repo
			if (resource instanceof IProject)
				result.put(rm.getRepository(), new HashSet<IResource>());
			else if (resource instanceof IContainer) {
				Set<IResource> containers = result.get(rm.getRepository());
				if (containers == null) {
					containers = new HashSet<>();
					result.put(rm.getRepository(), containers);
					containers.add(resource);
				} else if (containers.size() > 0)
					containers.add(resource);
			}
		}

		return result;
	}

	private String getDstRef(Repository repo, boolean launchFetch) {
		if (launchFetch) {
			String realName = getRealBranchName(repo);
			String name = BRANCH_NAME_PATTERN.matcher(realName).replaceAll(""); //$NON-NLS-1$
			StoredConfig config = repo.getConfig();
			String remote = config.getString(CONFIG_BRANCH_SECTION, name,
					CONFIG_KEY_REMOTE);
			String merge = config.getString(CONFIG_BRANCH_SECTION, name,
					CONFIG_KEY_MERGE);
			if (remote == null || merge == null)
				return HEAD;

			String mergeBranchName = merge.replace(R_HEADS, ""); //$NON-NLS-1$
			return R_REMOTES + remote + "/" + mergeBranchName; //$NON-NLS-1$
		} else
			return HEAD;
	}

	private String getRealBranchName(Repository repo) {
		Ref ref;

		try {
			ref = repo.exactRef(HEAD);
		} catch (IOException e) {
			ref = null;
		}

		if (ref != null && ref.isSymbolic())
			return ref.getTarget().getName();
		else
			return HEAD;
	}

}

Back to the top