Skip to content

Commit 43bb61a

Browse files
author
Peer Allan
committed
Adds Rugged::Remote#prune
1 parent 98d554a commit 43bb61a

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

ext/rugged/rugged_remote.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,19 @@ void rugged_remote_init_callbacks_and_payload_from_options(
181181
}
182182
}
183183

184+
static int parse_prune_type(VALUE rb_prune_type)
185+
{
186+
if (rb_prune_type == Qtrue) {
187+
return GIT_FETCH_PRUNE;
188+
} else if (rb_prune_type == Qfalse) {
189+
return GIT_FETCH_NO_PRUNE;
190+
} else if (rb_prune_type == Qnil) {
191+
return GIT_FETCH_PRUNE_UNSPECIFIED;
192+
} else {
193+
rb_raise(rb_eTypeError, "wrong argument type for :prune (expected true, false or nil)");
194+
}
195+
}
196+
184197
static void rb_git_remote__free(git_remote *remote)
185198
{
186199
git_remote_free(remote);
@@ -502,6 +515,10 @@ static VALUE rb_git_remote_check_connection(int argc, VALUE *argv, VALUE self)
502515
* :message ::
503516
* The message to insert into the reflogs. Defaults to "fetch".
504517
*
518+
* :prune ::
519+
* Specifies the prune mode for the fetch. +true+ remove any remote-tracking references that
520+
* no longer exist, +false+ do not prune, +nil+ use configured settings Defaults to "nil".
521+
*
505522
* Example:
506523
*
507524
* remote = Rugged::Remote.lookup(@repo, 'origin')
@@ -536,6 +553,10 @@ static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
536553
VALUE rb_val = rb_hash_aref(rb_options, CSTR2SYM("message"));
537554
if (!NIL_P(rb_val))
538555
log_message = StringValueCStr(rb_val);
556+
557+
VALUE rb_prune_type = rb_hash_aref(rb_options, CSTR2SYM("prune"));
558+
if (!NIL_P(rb_prune_type))
559+
opts.prune = parse_prune_type(rb_prune_type);
539560
}
540561

541562
error = git_remote_fetch(remote, &refspecs, &opts, log_message);
@@ -620,6 +641,49 @@ static VALUE rb_git_remote_push(int argc, VALUE *argv, VALUE self)
620641
return payload.result;
621642
}
622643

644+
/*
645+
* call-seq:
646+
* remote.prune(options = {}) -> nil
647+
*
648+
* Prune tracking refs that are no longer present on remote
649+
*
650+
* Returns nil
651+
*
652+
* The following options can be passed in the +options+ Hash:
653+
*
654+
* :credentials ::
655+
* The credentials to use for the fetch operation. Can be either an instance of one
656+
* of the Rugged::Credentials types, or a proc returning one of the former.
657+
* The proc will be called with the +url+, the +username+ from the url (if applicable) and
658+
* a list of applicable credential types.
659+
*
660+
* Example:
661+
*
662+
* remote = Rugged::Remote.lookup(@repo, 'origin')
663+
* remote.prune()
664+
*
665+
*/
666+
static VALUE rb_git_remote_prune(int argc, VALUE *argv, VALUE self)
667+
{
668+
VALUE rb_options;
669+
git_remote *remote;
670+
git_fetch_options opts = GIT_FETCH_OPTIONS_INIT;
671+
struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
672+
int error;
673+
674+
Data_Get_Struct(self, git_remote, remote);
675+
rb_scan_args(argc, argv, ":", &rb_options);
676+
rugged_remote_init_callbacks_and_payload_from_options(rb_options, &opts.callbacks, &payload);
677+
678+
if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH, &opts.callbacks)) ||
679+
(error = git_remote_prune(remote, &opts.callbacks)))
680+
git_remote_disconnect(remote);
681+
682+
rugged_exception_check(error);
683+
684+
return Qnil;
685+
}
686+
623687
void Init_rugged_remote(void)
624688
{
625689
rb_cRuggedRemote = rb_define_class_under(rb_mRugged, "Remote", rb_cObject);
@@ -634,4 +698,5 @@ void Init_rugged_remote(void)
634698
rb_define_method(rb_cRuggedRemote, "check_connection", rb_git_remote_check_connection, -1);
635699
rb_define_method(rb_cRuggedRemote, "fetch", rb_git_remote_fetch, -1);
636700
rb_define_method(rb_cRuggedRemote, "push", rb_git_remote_push, -1);
701+
rb_define_method(rb_cRuggedRemote, "prune", rb_git_remote_prune, -1);
637702
}

test/remote_test.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,56 @@ def test_push_non_forward_forced_raise_no_error
168168

169169
assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @remote_repo.ref("refs/heads/master").target_id
170170
end
171+
172+
end
173+
174+
class RemotePruneTest < Rugged::TestCase
175+
def setup
176+
@remote_repo = FixtureRepo.from_libgit2("testrepo.git")
177+
# We can only push to bare repos
178+
@remote_repo.config['core.bare'] = 'true'
179+
180+
@repo = FixtureRepo.clone(@remote_repo)
181+
@repo.references.create("refs/heads/unit_test", "8496071c1b46c854b31185ea97743be6a8774479")
182+
183+
@remote = @repo.remotes['origin']
184+
185+
@remote.push(["refs/heads/unit_test"])
186+
@remote_repo.references.delete("refs/heads/unit_test")
187+
end
188+
189+
def test_remote_prune
190+
assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @repo.ref("refs/remotes/origin/unit_test").target_id
191+
assert_equal nil, @remote.prune
192+
assert_nil @repo.ref("refs/remotes/origin/unit_test")
193+
end
194+
195+
def test_fetch_prune_is_forced
196+
assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @repo.ref("refs/remotes/origin/unit_test").target_id
197+
@remote.fetch(prune: true)
198+
assert_nil @repo.ref("refs/remotes/origin/unit_test")
199+
end
200+
201+
def test_fetch_prune_is_not_forced
202+
@remote.fetch(prune: false)
203+
assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @repo.ref("refs/remotes/origin/unit_test").target_id
204+
end
205+
206+
def test_fetch_prune_nil
207+
@remote.fetch(prune: nil)
208+
assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @repo.ref("refs/remotes/origin/unit_test").target_id
209+
end
210+
211+
def test_fetch_prune_nil
212+
@remote.fetch(prune: nil)
213+
assert_equal "8496071c1b46c854b31185ea97743be6a8774479", @repo.ref("refs/remotes/origin/unit_test").target_id
214+
end
215+
216+
def test_fetch_prune_with_invalid_argument_raises
217+
assert_raises TypeError do
218+
@remote.fetch(prune: 'INVALID')
219+
end
220+
end
171221
end
172222

173223
class RemoteWriteTest < Rugged::TestCase

0 commit comments

Comments
 (0)