Skip to content

Commit

Permalink
#5662: Implement fast-forward to upstream.
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Jul 17, 2021
1 parent f51e893 commit 496cbe9
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
6 changes: 6 additions & 0 deletions plugins/vcs/Algorithm.h
Expand Up @@ -135,6 +135,12 @@ inline void syncWithRemote(const std::shared_ptr<Repository>& repository)
repository->pushToTrackedRemote();
return;
}

if (status.strategy == RequiredMergeStrategy::FastForward)
{
repository->fastForwardToTrackedRemote();
return;
}

if (!repository->isReadyForMerge())
{
Expand Down
15 changes: 15 additions & 0 deletions plugins/vcs/Reference.h
Expand Up @@ -3,6 +3,7 @@
#include <string>
#include <memory>
#include <git2.h>
#include "GitException.h"

namespace vcs
{
Expand Down Expand Up @@ -62,6 +63,20 @@ class Reference final
return upstream != nullptr ? std::make_shared<Reference>(upstream) : Ptr();
}

// Create a new reference with the same name as the given reference but a
// different OID target. The new reference will be written to disk, overwriting the given reference.
void setTarget(git_oid* oid)
{
git_reference* newTargetRef;
auto error = git_reference_set_target(&newTargetRef, _reference, oid, "Reference set to new target by DarkRadiant");
GitException::ThrowOnError(error);

// Swap the wrapped reference pointer, release the old one
git_reference_free(_reference);

_reference = newTargetRef;
}

~Reference()
{
git_reference_free(_reference);
Expand Down
39 changes: 39 additions & 0 deletions plugins/vcs/Repository.cpp
Expand Up @@ -150,6 +150,45 @@ void Repository::pushToTrackedRemote()
remote->push(*getHead()); // getHead will succeed because getTrackedRemote did
}

void Repository::fastForwardToTrackedRemote()
{
auto head = getHead();
if (!head) throw GitException("Could not retrieve HEAD reference from repository");

auto upstream = head->getUpstream();
if (!upstream) throw GitException("No tracked remote branch configured");

// Lookup the target object
git_oid targetOid;
git_reference_name_to_id(&targetOid, _repository, upstream->getName().c_str());

git_object* target;
auto error = git_object_lookup(&target, _repository, &targetOid, GIT_OBJECT_COMMIT);
GitException::ThrowOnError(error);

rMessage() << "Fast-fowarding " << head->getName() << " to upstream " << upstream->getName() << std::endl;

try
{
// Checkout the result so the workdir is in the expected state
git_checkout_options checkoutOptions = GIT_CHECKOUT_OPTIONS_INIT;
checkoutOptions.checkout_strategy = GIT_CHECKOUT_SAFE;

error = git_checkout_tree(_repository, target, &checkoutOptions);
GitException::ThrowOnError(error);

// Move the target reference to the target OID
head->setTarget(&targetOid);

rMessage() << "Fast-foward done, " << head->getName() << " is now at " << Reference::OidToString(&targetOid) << std::endl;
}
catch (const GitException& ex)
{
git_object_free(target);
throw ex;
}
}

RefSyncStatus Repository::getSyncStatusOfBranch(const Reference& reference)
{
RefSyncStatus status;
Expand Down
3 changes: 3 additions & 0 deletions plugins/vcs/Repository.h
Expand Up @@ -51,6 +51,9 @@ class Repository final
// Performs a fetch from the remote the current branch is tracking
void fetchFromTrackedRemote();

// Fast-forwards the current head to the tracked remote branch
void fastForwardToTrackedRemote();

// Pushes the current head to its tracked remote branch
void pushToTrackedRemote();

Expand Down
3 changes: 2 additions & 1 deletion plugins/vcs/ui/VcsStatus.cpp
Expand Up @@ -18,6 +18,7 @@
#include "../GitModule.h"
#include "../Diff.h"
#include "../GitException.h"
#include "../Algorithm.h"

namespace vcs
{
Expand Down Expand Up @@ -232,7 +233,7 @@ void VcsStatus::performSync(std::shared_ptr<git::Repository> repository)
{
try
{
repository->pushToTrackedRemote();
syncWithRemote(repository);
setRemoteStatus(git::analyseRemoteStatus(repository));
}
catch (git::GitException& ex)
Expand Down

0 comments on commit 496cbe9

Please sign in to comment.