Re: [PATCH v20 39/48] refs.c: make delete_ref use a transaction

2014-07-14 Thread Ronnie Sahlberg
On Tue, Jul 8, 2014 at 6:52 AM, Michael Haggerty  wrote:
> On 06/20/2014 04:43 PM, Ronnie Sahlberg wrote:
>> Change delete_ref to use a ref transaction for the deletion. At the same time
>> since we no longer have any callers of repack_without_ref we can now delete
>> this function.
>>
>> Change delete_ref to return 0 on success and 1 on failure instead of the
>> previous 0 on success either 1 or -1 on failure.
>>
>> Reviewed-by: Jonathan Nieder 
>> Signed-off-by: Ronnie Sahlberg 
>> ---
>>  refs.c | 34 +-
>>  1 file changed, 13 insertions(+), 21 deletions(-)
>>
>> diff --git a/refs.c b/refs.c
>> index 3d070d5..92a06d4 100644
>> --- a/refs.c
>> +++ b/refs.c
>> @@ -2544,11 +2544,6 @@ int repack_without_refs(const char **refnames, int n, 
>> struct strbuf *err)
>>   return ret;
>>  }
>>
>> -static int repack_without_ref(const char *refname)
>> -{
>> - return repack_without_refs(&refname, 1, NULL);
>> -}
>> -
>>  static int delete_ref_loose(struct ref_lock *lock, int flag)
>>  {
>>   if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) {
>> @@ -2566,24 +2561,21 @@ static int delete_ref_loose(struct ref_lock *lock, 
>> int flag)
>>
>>  int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
>>  {
>> - struct ref_lock *lock;
>> - int ret = 0, flag = 0;
>> + struct ref_transaction *transaction;
>> + struct strbuf err = STRBUF_INIT;
>>
>> - lock = lock_ref_sha1_basic(refname, sha1, delopt, &flag);
>
> The old code checked that the old value of refname was sha1, regardless
> of whether sha1 was null_sha1.  Presumably callers never set sha1 to
> null_sha1...

They sometimes do.

>
>> - if (!lock)
>> + transaction = ref_transaction_begin(&err);
>> + if (!transaction ||
>> + ref_transaction_delete(transaction, refname, sha1, delopt,
>> +sha1 && !is_null_sha1(sha1), &err) ||
>
> ...But the new code explicitly skips the check if sha1 is null_sha1.
> This shouldn't make a practical difference, because presumably callers
> never set sha1 to null_sha1.

There are actually a few cases where callers do call delete_ref() with
sha1 == null_sha1.
For example fast-import.c:update_branch() will do this is the ref can
not be resolved.
It can also happen in builtin/update-ref.c where we are passing user
supplied data into the call to delete_ref.

So I think the current behaviour should be ok.

There are a few options we could do:
We could change the semantics for ref_transaction_update|delete and
start allowing
   have_old==1
   old_sha1==null_sha1
and have this behave the same way as
   have_old==0
but I think that would be horrible I think.

We could also change all callers to delete_ref() to be careful to only
specify a sha1 IFF it is not null_sha1
but that would just mean we require all callers to do this type of check.
But that would also be fragile since if/when we get new callers to
delete_ref we risk breaking delete_ref if we are not careful.


I think the least bad option is to just have this check in
delete_ref() as now and have the semantics for delete_ref be that if
sha1 is either NULL or null_sha1 then it means we don't care what the
old value is.



regards
ronnie sahlberg
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v20 39/48] refs.c: make delete_ref use a transaction

2014-07-08 Thread Michael Haggerty
On 06/20/2014 04:43 PM, Ronnie Sahlberg wrote:
> Change delete_ref to use a ref transaction for the deletion. At the same time
> since we no longer have any callers of repack_without_ref we can now delete
> this function.
> 
> Change delete_ref to return 0 on success and 1 on failure instead of the
> previous 0 on success either 1 or -1 on failure.
> 
> Reviewed-by: Jonathan Nieder 
> Signed-off-by: Ronnie Sahlberg 
> ---
>  refs.c | 34 +-
>  1 file changed, 13 insertions(+), 21 deletions(-)
> 
> diff --git a/refs.c b/refs.c
> index 3d070d5..92a06d4 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -2544,11 +2544,6 @@ int repack_without_refs(const char **refnames, int n, 
> struct strbuf *err)
>   return ret;
>  }
>  
> -static int repack_without_ref(const char *refname)
> -{
> - return repack_without_refs(&refname, 1, NULL);
> -}
> -
>  static int delete_ref_loose(struct ref_lock *lock, int flag)
>  {
>   if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) {
> @@ -2566,24 +2561,21 @@ static int delete_ref_loose(struct ref_lock *lock, 
> int flag)
>  
>  int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
>  {
> - struct ref_lock *lock;
> - int ret = 0, flag = 0;
> + struct ref_transaction *transaction;
> + struct strbuf err = STRBUF_INIT;
>  
> - lock = lock_ref_sha1_basic(refname, sha1, delopt, &flag);

The old code checked that the old value of refname was sha1, regardless
of whether sha1 was null_sha1.  Presumably callers never set sha1 to
null_sha1...

> - if (!lock)
> + transaction = ref_transaction_begin(&err);
> + if (!transaction ||
> + ref_transaction_delete(transaction, refname, sha1, delopt,
> +sha1 && !is_null_sha1(sha1), &err) ||

...But the new code explicitly skips the check if sha1 is null_sha1.
This shouldn't make a practical difference, because presumably callers
never set sha1 to null_sha1.  But given that the new policy elsewhere
for "delete" updates is that it is an error for old_sha1 to equal
null_sha1, it seems to me that this extra check shouldn't be here.  So I
think this should be changed to

ref_transaction_delete(transaction, refname, sha1, delopt,
   !!sha1, &err) ||


> [...]

Michael

-- 
Michael Haggerty
mhag...@alum.mit.edu

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v20 39/48] refs.c: make delete_ref use a transaction

2014-06-20 Thread Ronnie Sahlberg
Change delete_ref to use a ref transaction for the deletion. At the same time
since we no longer have any callers of repack_without_ref we can now delete
this function.

Change delete_ref to return 0 on success and 1 on failure instead of the
previous 0 on success either 1 or -1 on failure.

Reviewed-by: Jonathan Nieder 
Signed-off-by: Ronnie Sahlberg 
---
 refs.c | 34 +-
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/refs.c b/refs.c
index 3d070d5..92a06d4 100644
--- a/refs.c
+++ b/refs.c
@@ -2544,11 +2544,6 @@ int repack_without_refs(const char **refnames, int n, 
struct strbuf *err)
return ret;
 }
 
-static int repack_without_ref(const char *refname)
-{
-   return repack_without_refs(&refname, 1, NULL);
-}
-
 static int delete_ref_loose(struct ref_lock *lock, int flag)
 {
if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) {
@@ -2566,24 +2561,21 @@ static int delete_ref_loose(struct ref_lock *lock, int 
flag)
 
 int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
 {
-   struct ref_lock *lock;
-   int ret = 0, flag = 0;
+   struct ref_transaction *transaction;
+   struct strbuf err = STRBUF_INIT;
 
-   lock = lock_ref_sha1_basic(refname, sha1, delopt, &flag);
-   if (!lock)
+   transaction = ref_transaction_begin(&err);
+   if (!transaction ||
+   ref_transaction_delete(transaction, refname, sha1, delopt,
+  sha1 && !is_null_sha1(sha1), &err) ||
+   ref_transaction_commit(transaction, NULL, &err)) {
+   error("%s", err.buf);
+   ref_transaction_free(transaction);
+   strbuf_release(&err);
return 1;
-   ret |= delete_ref_loose(lock, flag);
-
-   /* removing the loose one could have resurrected an earlier
-* packed one.  Also, if it was not loose we need to repack
-* without it.
-*/
-   ret |= repack_without_ref(lock->ref_name);
-
-   unlink_or_warn(git_path("logs/%s", lock->ref_name));
-   clear_loose_ref_cache(&ref_cache);
-   unlock_ref(lock);
-   return ret;
+   }
+   ref_transaction_free(transaction);
+   return 0;
 }
 
 /*
-- 
2.0.0.420.g181e020.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html