Skip to content

Commit

Permalink
Version control improvements
Browse files Browse the repository at this point in the history
- Show current branch
- Enable branch switching
- Use a client-side proxy for the server-side state to prevent excessive client-server network requests
  • Loading branch information
jcheng5 committed Aug 24, 2011
1 parent 03c36a2 commit 7740d1f
Show file tree
Hide file tree
Showing 21 changed files with 585 additions and 141 deletions.
101 changes: 101 additions & 0 deletions src/cpp/session/modules/SessionSourceControl.cpp
Expand Up @@ -18,6 +18,7 @@
#include <boost/foreach.hpp>
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <boost/regex.hpp>

#include <core/json/JsonRpc.hpp>
Expand Down Expand Up @@ -114,6 +115,19 @@ class VCSImpl : boost::noncopyable
return Success();
}

virtual core::Error listBranches(std::vector<std::string>* pBranches,
boost::optional<size_t>* pActiveBranchIndex,
std::string* pStdErr)
{
return Success();
}

virtual core::Error checkout(const std::string& id,
std::string* pStdErr)
{
return Success();
}

core::Error runCommand(const std::string& command,
const std::vector<std::string>& args,
std::vector<std::string>* pOutputLines=NULL)
Expand Down Expand Up @@ -364,6 +378,43 @@ class GitVCSImpl : public VCSImpl
return doSimpleCmd("reset", args, filePaths, pStdErr);
}

core::Error listBranches(std::vector<std::string>* pBranches,
boost::optional<size_t>* pActiveBranchIndex,
std::string* pStdErr)
{
std::vector<std::string> args;
args.push_back("branch");
Error error = runCommand("git", args, pBranches);
if (error)
return error;

for (std::vector<std::string>::iterator it = pBranches->begin();
it != pBranches->end();
it++)
{
if (*it == "")
{
pBranches->resize(it - pBranches->begin());
break;
}

if (it->substr(0, 2) == "* ")
*pActiveBranchIndex = it - pBranches->begin();
*it = it->substr(2);
}

return Success();
}

core::Error checkout(const std::string& id,
std::string* pStdErr)
{
std::vector<std::string> args;
args.push_back("checkout");
args.push_back(id);
return runCommand("git", args);
}

core::Error commit(const std::string& message, bool amend, bool signOff)
{
FilePath tempFile = module_context::tempFile("gitmsg", "txt");
Expand Down Expand Up @@ -763,6 +814,54 @@ Error vcsUnstage(const json::JsonRpcRequest& request,
return s_pVcsImpl_->unstage(resolveAliasedPaths(paths), NULL);
}

Error vcsListBranches(const json::JsonRpcRequest& request,
json::JsonRpcResponse* pResponse)
{
std::vector<std::string> branches;
boost::optional<size_t> activeIndex;
std::string stderr;
Error error = s_pVcsImpl_->listBranches(&branches, &activeIndex, &stderr);
if (error)
return error;

json::Array jsonBranches;
for (std::vector<std::string>::const_iterator it = branches.begin();
it != branches.end();
it++)
{
jsonBranches.push_back(*it);
}

json::Object result;
result["branches"] = jsonBranches;
result["activeIndex"] =
activeIndex
? json::Value(static_cast<boost::uint64_t>(activeIndex.get()))
: json::Value();

pResponse->setResult(result);

return Success();
}

Error vcsCheckout(const json::JsonRpcRequest& request,
json::JsonRpcResponse* pResponse)
{
RefreshOnExit refreshOnExit;

std::string id;
Error error = json::readParams(request.params, &id);
if (error)
return error;

std::string stderr;
error = s_pVcsImpl_->checkout(id, &stderr);
if (error)
return error;

return Success();
}

Error vcsFullStatus(const json::JsonRpcRequest&,
json::JsonRpcResponse* pResponse)
{
Expand Down Expand Up @@ -989,6 +1088,8 @@ core::Error initialize()
(bind(registerRpcMethod, "vcs_revert", vcsRevert))
(bind(registerRpcMethod, "vcs_stage", vcsStage))
(bind(registerRpcMethod, "vcs_unstage", vcsUnstage))
(bind(registerRpcMethod, "vcs_list_branches", vcsListBranches))
(bind(registerRpcMethod, "vcs_checkout", vcsCheckout))
(bind(registerRpcMethod, "vcs_full_status", vcsFullStatus))
(bind(registerRpcMethod, "vcs_commit_git", vcsCommitGit))
(bind(registerRpcMethod, "vcs_diff_file", vcsDiffFile))
Expand Down
62 changes: 62 additions & 0 deletions src/gwt/src/org/rstudio/core/client/WidgetHandlerRegistration.java
@@ -0,0 +1,62 @@
/*
* WidgetHandlerRegistration.java
*
* Copyright (C) 2009-11 by RStudio, Inc.
*
* This program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.core.client;

import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Widget;

/**
* Automatically registers and unregisters a handler as a widget
* becomes attached and detached from the DOM.
*
* To use, create a concrete subclass and override the doRegister
* method to do the actual addHandler call.
*/
public abstract class WidgetHandlerRegistration
{
public WidgetHandlerRegistration(Widget widget)
{
widget.addAttachHandler(new AttachEvent.Handler()
{
@Override
public void onAttachOrDetach(AttachEvent event)
{
unregister();
if (event.isAttached())
register();
}
});

if (widget.isAttached())
register();
}

public void register()
{
registration_ = doRegister();
}

protected abstract HandlerRegistration doRegister();

private void unregister()
{
if (registration_ != null)
{
registration_.removeHandler();
registration_ = null;
}
}

private HandlerRegistration registration_;
}
@@ -1,7 +1,7 @@
.container {
display: inline-block;
height: 20px;
margin-right: 12px;
margin-right: 3px;
}

.container td {
Expand Down
28 changes: 20 additions & 8 deletions src/gwt/src/org/rstudio/core/client/widget/ToolbarButton.java
Expand Up @@ -114,6 +114,7 @@ public ToolbarButton(String text,
private void addMenuHandlers(final ToolbarPopupMenu menu,
final boolean rightAlign)
{
menu_ = menu;
/*
* We want clicks on this button to toggle the visibility of the menu,
* as well as having the menu auto-hide itself as it normally does.
Expand Down Expand Up @@ -188,13 +189,7 @@ private ToolbarButton(String text,

this.setStylePrimaryName(styles_.toolbarButton());

if (!StringUtil.isNullOrEmpty(text))
label_.setInnerText(text);
else
{
label_.getStyle().setDisplay(Display.NONE);
addStyleName(styles_.noLabel());
}
setText(text);
if (leftImage != null)
leftImageWidget_ = new Image(leftImage);
else
Expand Down Expand Up @@ -299,19 +294,36 @@ protected Toolbar getParentToolbar()
return null;
}

public ToolbarPopupMenu getMenu()
{
return menu_;
}

public void setLeftImage(ImageResource imageResource)
{
leftImageWidget_.setResource(imageResource);
}

public void setText(String label)
{
label_.setInnerText(label);
if (!StringUtil.isNullOrEmpty(label))
{
label_.setInnerText(label);
label_.getStyle().setDisplay(Display.BLOCK);
removeStyleName(styles_.noLabel());
}
else
{
label_.getStyle().setDisplay(Display.NONE);
addStyleName(styles_.noLabel());
}
}

private boolean down_;

interface Binder extends UiBinder<Element, ToolbarButton> { }

private ToolbarPopupMenu menu_;
private static final Binder binder = GWT.create(Binder.class);

private static final ThemeStyles styles_ = ThemeResources.INSTANCE.themeStyles();
Expand Down
Expand Up @@ -25,4 +25,5 @@ public interface StandardIcons extends ClientBundle
ImageResource click_feedback();
ImageResource more_actions();
ImageResource import_dataset();
ImageResource empty_command();
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions src/gwt/src/org/rstudio/studio/client/common/vcs/BranchesInfo.java
@@ -0,0 +1,33 @@
/*
* BranchesInfo.java
*
* Copyright (C) 2009-11 by RStudio, Inc.
*
* This program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.studio.client.common.vcs;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayString;

public class BranchesInfo extends JavaScriptObject
{
protected BranchesInfo()
{
}

public native final String getActiveBranch() /*-{
if (this.activeIndex === null)
return null;
return this.branches[this.activeIndex];
}-*/;

public native final JsArrayString getBranches() /*-{
return this.branches;
}-*/;
}
Expand Up @@ -56,6 +56,10 @@ void vcsUnstage(ArrayList<String> paths,
void vcsFullStatus(
ServerRequestCallback<JsArray<StatusAndPath>> requestCallback);

void vcsListBranches(ServerRequestCallback<BranchesInfo> requestCallback);

void vcsCheckout(String id, ServerRequestCallback<Void> requestCallback);

void vcsCommitGit(String message,
boolean amend,
boolean signOff,
Expand Down
Expand Up @@ -33,6 +33,7 @@
import org.rstudio.studio.client.application.model.HttpLogEntry;
import org.rstudio.studio.client.common.codetools.Completions;
import org.rstudio.studio.client.common.mirrors.model.CRANMirror;
import org.rstudio.studio.client.common.vcs.BranchesInfo;
import org.rstudio.studio.client.common.vcs.ExecuteCommandResult;
import org.rstudio.studio.client.common.vcs.StatusAndPath;
import org.rstudio.studio.client.projects.model.RProjectConfig;
Expand Down Expand Up @@ -1213,6 +1214,19 @@ public void vcsFullStatus(ServerRequestCallback<JsArray<StatusAndPath>> requestC
sendRequest(RPC_SCOPE, VCS_FULL_STATUS, requestCallback);
}

@Override
public void vcsListBranches(ServerRequestCallback<BranchesInfo> requestCallback)
{
sendRequest(RPC_SCOPE, VCS_LIST_BRANCHES, requestCallback);
}

@Override
public void vcsCheckout(String id,
ServerRequestCallback<Void> requestCallback)
{
sendRequest(RPC_SCOPE, VCS_CHECKOUT, id, requestCallback);
}

public void vcsCommitGit(String message,
boolean amend,
boolean signOff,
Expand Down Expand Up @@ -1749,6 +1763,8 @@ private void disconnect()
private static final String VCS_STAGE = "vcs_stage";
private static final String VCS_UNSTAGE = "vcs_unstage";
private static final String VCS_FULL_STATUS = "vcs_full_status";
private static final String VCS_LIST_BRANCHES = "vcs_list_branches";
private static final String VCS_CHECKOUT = "vcs_checkout";
private static final String VCS_COMMIT_GIT = "vcs_commit_git";
private static final String VCS_DIFF_FILE = "vcs_diff_file";
private static final String VCS_APPLY_PATCH = "vcs_apply_patch";
Expand Down

0 comments on commit 7740d1f

Please sign in to comment.