Skip to content

Commit 6aa6def

Browse files
Add Rugged::Configuration#transaction.
1 parent 0aa47f1 commit 6aa6def

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

ext/rugged/rugged_config.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,47 @@ static VALUE rb_git_config_snapshot(VALUE self)
328328
return rugged_config_new(rb_obj_class(self), Qnil, snapshot);
329329
}
330330

331+
/*
332+
* call-seq:
333+
* config.transaction { |config| }
334+
*
335+
* Perform configuration changes in a transaction.
336+
*
337+
* Locks the configuration, executes the given block and stores
338+
* any changes that were made to the configuration. If the block
339+
* throws an exception, all changes are rolled back automatically.
340+
*
341+
* During the execution of the block, configuration changes don't
342+
* get stored to disk immediately, so reading from the configuration
343+
* will continue to return the values that were stored in the configuration
344+
* when the transaction was started.
345+
*/
346+
static VALUE rb_git_config_transaction(VALUE self)
347+
{
348+
git_config *config;
349+
git_transaction *tx;
350+
VALUE rb_result;
351+
int error = 0, exception = 0;
352+
353+
Data_Get_Struct(self, git_config, config);
354+
355+
git_config_lock(&tx, config);
356+
357+
rb_result = rb_protect(rb_yield, self, &exception);
358+
359+
if (!exception)
360+
error = git_transaction_commit(tx);
361+
362+
git_transaction_free(tx);
363+
364+
if (exception)
365+
rb_jump_tag(exception);
366+
else if (error)
367+
rugged_exception_check(error);
368+
369+
return rb_result;
370+
}
371+
331372
void Init_rugged_config(void)
332373
{
333374
/*
@@ -353,4 +394,5 @@ void Init_rugged_config(void)
353394
rb_define_method(rb_cRuggedConfig, "to_hash", rb_git_config_to_hash, 0);
354395

355396
rb_define_method(rb_cRuggedConfig, "snapshot", rb_git_config_snapshot, 0);
397+
rb_define_method(rb_cRuggedConfig, "transaction", rb_git_config_transaction, 0);
356398
}

test/config_test.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,29 @@ def test_snapshot
3535
assert_equal '5', snapshot['old.value']
3636
assert_nil snapshot['new.value']
3737
end
38+
39+
def test_transaction
40+
config = Rugged::Config.new(File.join(@repo.path, 'config'))
41+
config['section.name'] = 'value'
42+
43+
config2 = Rugged::Config.new(File.join(@repo.path, 'config'))
44+
45+
config.transaction do
46+
config['section.name'] = 'other value'
47+
config['section2.name3'] = 'more value'
48+
49+
assert_equal 'value', config2['section.name']
50+
assert_nil config2['section2.name3']
51+
52+
assert_equal 'value', config['section.name']
53+
assert_nil config['section2.name3']
54+
end
55+
56+
assert_equal 'other value', config['section.name']
57+
assert_equal 'more value', config['section2.name3']
58+
assert_equal 'other value', config2['section.name']
59+
assert_equal 'more value', config2['section2.name3']
60+
end
3861
end
3962

4063
class ConfigWriteTest < Rugged::TestCase

0 commit comments

Comments
 (0)