Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 75 additions & 40 deletions ide/git/src/org/netbeans/modules/git/ui/fetch/PullAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.netbeans.modules.git.ui.actions.ActionProgressSupport;
import org.netbeans.modules.git.ui.actions.GitAction;
import org.netbeans.modules.git.ui.actions.SingleRepositoryAction;
import org.netbeans.modules.git.ui.branch.SetTrackingAction;
import org.netbeans.modules.git.ui.merge.MergeRevisionAction;
import org.netbeans.modules.git.ui.output.OutputLogger;
import org.netbeans.modules.git.ui.rebase.RebaseAction;
Expand All @@ -65,6 +66,7 @@
import org.openide.awt.ActionRegistration;
import org.openide.awt.Mnemonics;
import org.openide.util.NbBundle;
import org.openide.util.actions.SystemAction;

/**
*
Expand Down Expand Up @@ -107,6 +109,10 @@ public void run () {
}

private void pull (final File repository) {
pull(repository, null);
}

public void pull (final File repository, final GitBranch branchToSelect) {
RepositoryInfo info = RepositoryInfo.getInstance(repository);
try {
info.refreshRemotes();
Expand All @@ -117,7 +123,7 @@ private void pull (final File repository) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run () {
PullWizard wiz = new PullWizard(repository, remotes);
PullWizard wiz = new PullWizard(repository, remotes, branchToSelect);
if (wiz.show()) {
Utils.logVCSExternalRepository("GIT", wiz.getFetchUri()); //NOI18N
pull(repository, wiz.getFetchUri(), wiz.getFetchRefSpecs(), wiz.getBranchToMerge(), wiz.getRemoteToPersist());
Expand All @@ -144,6 +150,7 @@ private static class GitProgressSupportImpl extends GitProgressSupport {
private final String branchToMerge;
private final String target;
private final String remoteNameToUpdate;
private boolean pullSuccessful = false;

public GitProgressSupportImpl (List<String> fetchRefSpecs, String branchToMerge, String target, String remoteNameToUpdate) {
this.fetchRefSpecs = fetchRefSpecs;
Expand Down Expand Up @@ -182,55 +189,71 @@ protected void perform () {
return;
}
}
GitUtils.runWithoutIndexing(new Callable<Void>() {
@Override
public Void call () throws Exception {
for (String branch : toDelete) {
client.deleteBranch(branch, true, getProgressMonitor());
getLogger().outputLine(Bundle.MSG_PullAction_branchDeleted(branch));
}
setDisplayName(Bundle.MSG_PullAction_fetching());
Map<String, GitTransportUpdate> fetchResult = FetchAction.fetchRepeatedly(
client, getProgressMonitor(), target, fetchRefSpecs);
if (isCanceled()) {
return null;
GitUtils.runWithoutIndexing(() -> {
for (String branch : toDelete) {
client.deleteBranch(branch, true, getProgressMonitor());
getLogger().outputLine(Bundle.MSG_PullAction_branchDeleted(branch));
}
setDisplayName(Bundle.MSG_PullAction_fetching());
Map<String, GitTransportUpdate> fetchResult = FetchAction.fetchRepeatedly(
client, getProgressMonitor(), target, fetchRefSpecs);
if (isCanceled()) {
return null;
}
FetchUtils.log(repository, fetchResult, getLogger());
if (!isCanceled()) {
setDisplayName(Bundle.MSG_PullAction_progress_syncBranches());
FetchUtils.syncTrackingBranches(repository, fetchResult, GitProgressSupportImpl.this, GitProgressSupportImpl.this.getProgress(), false);
}
if (isCanceled() || branchToMerge == null) {
return null;
}
new BranchSynchronizer(branchToMerge, repository, new BranchSynchronizer.GitProgressSupportDelegate() {

@Override
public GitClient getClient () throws GitException {
return client;
}
FetchUtils.log(repository, fetchResult, getLogger());
if (!isCanceled()) {
setDisplayName(Bundle.MSG_PullAction_progress_syncBranches());
FetchUtils.syncTrackingBranches(repository, fetchResult, GitProgressSupportImpl.this, GitProgressSupportImpl.this.getProgress(), false);

@Override
public OutputLogger getLogger () {
return GitProgressSupportImpl.this.getLogger();
}
if (isCanceled() || branchToMerge == null) {
return null;

@Override
public ProgressDelegate getProgress () {
return GitProgressSupportImpl.this.getProgress();
}
new BranchSynchronizer(branchToMerge, repository, new BranchSynchronizer.GitProgressSupportDelegate() {

@Override
public GitClient getClient () throws GitException {
return client;
}

@Override
public OutputLogger getLogger () {
return GitProgressSupportImpl.this.getLogger();
}

@Override
public ProgressDelegate getProgress () {
return GitProgressSupportImpl.this.getProgress();
}

}).execute();
return null;

}).execute();

if (!isCanceled()) {
pullSuccessful = true;
}
}, repository);

return null;
}, repository);
} catch (GitException ex) {
setError(true);
GitClientExceptionHandler.notifyException(ex, true);
} finally {
setDisplayName(NbBundle.getMessage(GitAction.class, "LBL_Progress.RefreshingStatuses")); //NOI18N
Git.getInstance().getFileStatusCache().refreshAllRoots(Collections.<File, Collection<File>>singletonMap(repository, Git.getInstance().getSeenRoots(repository)));
GitUtils.headChanged(repository);

// Check if tracking should be set up after successful pull
if (pullSuccessful && branchToMerge != null) {
RepositoryInfo info = RepositoryInfo.getInstance(repository);
info.refresh();
GitBranch activeBranch = info.getActiveBranch();
if (activeBranch != null && activeBranch.getTrackedBranch() == null) {
// branchToMerge is the remote branch name (e.g., "origin/master")
if (shallSetupTracking(activeBranch, branchToMerge)) {
SystemAction.get(SetTrackingAction.class).setupTrackedBranchImmediately(
repository, activeBranch.getName(), branchToMerge);
}
}
}
}
}
}
Expand Down Expand Up @@ -378,5 +401,17 @@ public ActionProgress call () throws GitException {
}
}
}


@NbBundle.Messages({
"LBL_Pull.setupTracking=Set Up Remote Tracking?",
"# {0} - remote branch name", "# {1} - branch name", "MSG_Pull.setupTracking=Pulled from \"{0}\".\n"
+ "Do you want to set up branch \"{1}\" to track the remote branch?"
})
private static boolean shallSetupTracking (GitBranch branch, String remoteBranchName) {
return NotifyDescriptor.YES_OPTION == DialogDisplayer.getDefault().notify(new NotifyDescriptor.Confirmation(
Bundle.MSG_Pull_setupTracking(remoteBranchName, branch.getName()),
Bundle.LBL_Pull_setupTracking(),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.QUESTION_MESSAGE));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ public void setRemote (GitRemoteConfig remote) {
}

public void fillRemoteBranches (final Map<String, GitBranch> branches) {
fillRemoteBranches(Collections.<String,GitBranch>emptyMap(), Collections.<String,GitBranch>emptyMap());
fillRemoteBranches(branches, null);
}

public void fillRemoteBranches (final Map<String, GitBranch> branches, final GitBranch branchToSelect) {
fillRemoteBranchesInternal(Collections.<String,GitBranch>emptyMap(), Collections.<String,GitBranch>emptyMap(), null);
new GitProgressSupport.NoOutputLogging() {
@Override
protected void perform () {
Expand All @@ -140,14 +144,14 @@ protected void perform () {
EventQueue.invokeLater(new Runnable () {
@Override
public void run () {
fillRemoteBranches(branches, localBranches);
fillRemoteBranchesInternal(branches, localBranches, branchToSelect);
}
});
}
}.start(Git.getInstance().getRequestProcessor(repository), repository, NbBundle.getMessage(PullBranchesStep.class, "MSG_FetchBranchesPanel.loadingLocalBranches")); //NOI18N
}

private void fillRemoteBranches (Map<String, GitBranch> branches, Map<String, GitBranch> localBranches) {
private void fillRemoteBranchesInternal (Map<String, GitBranch> branches, Map<String, GitBranch> localBranches, GitBranch branchToSelect) {
List<BranchMapping> l = new ArrayList<BranchMapping>(branches.size());
Set<String> displayedBranches = new HashSet<String>(localBranches.size());
for (GitBranch branch : localBranches.values()) {
Expand All @@ -163,9 +167,14 @@ private void fillRemoteBranches (Map<String, GitBranch> branches, Map<String, Gi
GitBranch localBranch = localBranches.get(branchName);
boolean preselected = localBranch != null && (!localBranch.getId().equals(branch.getId()) // is a modification
// or is the tracked branch - should be offered primarily
|| currentBranch != null
&& currentBranch.getTrackedBranch() != null
|| currentBranch != null
&& currentBranch.getTrackedBranch() != null
&& currentBranch.getTrackedBranch().getName().equals(localBranch.getName()));

if (branchToSelect != null && branch.getName().equals(branchToSelect.getName())) {
preselected = true;
}

l.add(new BranchMapping(branch.getName(), branch.getId(), localBranch, remote, preselected));
}
for (GitBranch branch : localBranches.values()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,23 @@ protected void perform () {
Logger.getLogger(FetchFromUpstreamAction.class.getName()).log(Level.INFO, null, ex);
}
String errorLabel = Bundle.LBL_Pull_pullFromUpstreamFailed();
GitBranch trackedBranch = GitUtils.getTrackedBranch(info, errorLabel);
GitBranch activeBranch = info.getActiveBranch();
if (activeBranch == null) {
return;
}
GitBranch trackedBranch = GitUtils.getTrackedBranch(info, null);

// If no tracked branch and multiple remotes, use full pull UI
if (trackedBranch == null && info.getRemotes().size() > 1) {
SystemAction.get(PullAction.class).pull(repository, activeBranch);
return;
}

if (trackedBranch == null) {
return;
}
GitRemoteConfig cfg = FetchUtils.getRemoteConfigForActiveBranch(trackedBranch, info, errorLabel);

GitRemoteConfig cfg = FetchUtils.getRemoteConfigForActiveBranch(trackedBranch, info, errorLabel);
if (cfg == null) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,16 @@ class PullWizard implements ChangeListener {
private PanelsIterator wizardIterator;
private WizardDescriptor wizardDescriptor;
private final File repository;
private final GitBranch branchToSelect;

public PullWizard (File repository, Map<String, GitRemoteConfig> remotes) {
this(repository, remotes, null);
}

public PullWizard (File repository, Map<String, GitRemoteConfig> remotes, GitBranch branchToSelect) {
this.repository = repository;
this.remotes = remotes;
this.branchToSelect = branchToSelect;
}

boolean show () {
Expand Down Expand Up @@ -154,7 +160,7 @@ public synchronized void nextPanel () {
Map<String, GitBranch> remoteBranches = selectUriStep.getRemoteBranches();
pullBranchesStep.setRemote(remote);
if (remoteBranches != null) {
pullBranchesStep.fillRemoteBranches(remoteBranches);
pullBranchesStep.fillRemoteBranches(remoteBranches, branchToSelect);
}
selectUriStep.storeURI();
}
Expand Down
34 changes: 22 additions & 12 deletions ide/git/src/org/netbeans/modules/git/ui/push/PushAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,13 @@ public void push (final File repository, GitRemoteConfig remote, Collection<Push
}

public void push (final File repository) {
push(repository, null);
}

public void push (final File repository, final GitBranch branchToSelect) {
if (EventQueue.isDispatchThread()) {
Utils.post(new Runnable () {
@Override
public void run () {
push(repository);
}
Utils.post(() -> {
push(repository, branchToSelect);
});
return;
}
Expand All @@ -140,7 +141,7 @@ public void run () {
EventQueue.invokeLater(new Runnable() {
@Override
public void run () {
PushWizard wiz = new PushWizard(repository, remotes);
PushWizard wiz = new PushWizard(repository, remotes, branchToSelect);
if (wiz.show()) {
Utils.logVCSExternalRepository("GIT", wiz.getPushUri()); //NOI18N
push(repository, wiz.getPushUri(), wiz.getPushMappings(), wiz.getFetchRefSpecs(), wiz.getRemoteName());
Expand Down Expand Up @@ -325,12 +326,7 @@ protected void logUpdates (File repository, Map<String, GitTransportUpdate> upda
logger.outputLine(Bundle.MSG_PushAction_updates_addBranch(update.getLocalName(),
update.getNewObjectId(), update.getResult()));
if (!remote && update.getNewObjectId() != null) {
int pos = update.getLocalName().indexOf('/');
if (pos >= 0 && update.getLocalName().substring(pos + 1).equals(currBranch.getName())) {
if (shallSetupTracking(currBranch, update.getLocalName())) {
SystemAction.get(SetTrackingAction.class).setupTrackedBranchImmediately(repository, currBranch.getName(), update.getLocalName());
}
}
callSetTrackingAction(update, currBranch, repository);
}
} else {
logger.outputLine(Bundle.MSG_PushAction_updates_updateBranch(update.getRemoteName(),
Expand All @@ -344,6 +340,11 @@ protected void logUpdates (File repository, Map<String, GitTransportUpdate> upda
update.getOldObjectId(), update.getNewObjectId(), logger);
}
}

// Check if tracking should be set up for updated branches without tracking
if (!remote && update.getNewObjectId() != null && currBranch.getTrackedBranch() == null) {
callSetTrackingAction(update, currBranch, repository);
}
}
} else {
//tag deleting or updating
Expand All @@ -364,6 +365,15 @@ protected void logUpdates (File repository, Map<String, GitTransportUpdate> upda
}
}
}

private void callSetTrackingAction(GitTransportUpdate update, GitBranch currBranch, File repository1) {
int pos = update.getLocalName().indexOf('/');
if (pos >= 0 && update.getLocalName().substring(pos + 1).equals(currBranch.getName())) {
if (shallSetupTracking(currBranch, update.getLocalName())) {
SystemAction.get(SetTrackingAction.class).setupTrackedBranchImmediately(repository1, currBranch.getName(), update.getLocalName());
}
}
}

private void logTrackingUpdate (GitBranch b) {
if (b != null && b.getTrackedBranch() != null) {
Expand Down
17 changes: 17 additions & 0 deletions ide/git/src/org/netbeans/modules/git/ui/push/PushBranchesStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ public HelpCtx getHelp() {
*/
public void fillRemoteBranches (final GitRemoteConfig cfg, final Map<String, GitBranch> branches,
final Map<String, String> tags) {
fillRemoteBranches(cfg, branches, tags, null);
}

/**
*
* @param cfg configuration of the remote repository including URLs of remote
* @param branches list of all branches in the remote repo
* @param tags list of all tags in the remote repo
* @param branchToSelect branch that should be preselected in the list
*/
public void fillRemoteBranches (final GitRemoteConfig cfg, final Map<String, GitBranch> branches,
final Map<String, String> tags, final GitBranch branchToSelect) {
fillLocalObjects(Collections.<PushMapping>emptyList());
new GitProgressSupport.NoOutputLogging() {
@Override
Expand Down Expand Up @@ -162,6 +174,11 @@ protected void perform () {
}
boolean preselected = !conflicted && updateNeeded;

// If a specific branch should be selected, override preselection
if (branchToSelect != null && branch.getName().equals(branchToSelect.getName())) {
preselected = true;
}

//add current branch in the list for update or for adding
l.add(new PushMapping.PushBranchMapping(remoteBranch == null ? null : remoteBranch.getName(),
remoteBranch == null ? null : remoteBranch.getId(),
Expand Down
Loading
Loading