55#include "config.h"
66#include "gettext.h"
77#include "hash.h"
8+ #include "hex.h"
89#include "refs.h"
910#include "object-name.h"
1011#include "parse-options.h"
1314static const char * const git_update_ref_usage [] = {
1415 N_ ("git update-ref [<options>] -d <refname> [<old-oid>]" ),
1516 N_ ("git update-ref [<options>] <refname> <new-oid> [<old-oid>]" ),
16- N_ ("git update-ref [<options>] --stdin [-z]" ),
17+ N_ ("git update-ref [<options>] --stdin [-z] [--allow-partial] " ),
1718 NULL
1819};
1920
@@ -565,6 +566,49 @@ static void parse_cmd_abort(struct ref_transaction *transaction,
565566 report_ok ("abort" );
566567}
567568
569+ static void print_rejected_refs (const char * refname ,
570+ const struct object_id * old_oid ,
571+ const struct object_id * new_oid ,
572+ const char * old_target ,
573+ const char * new_target ,
574+ enum ref_transaction_error err ,
575+ void * cb_data UNUSED )
576+ {
577+ struct strbuf sb = STRBUF_INIT ;
578+ const char * reason = "" ;
579+
580+ switch (err ) {
581+ case REF_TRANSACTION_ERROR_NAME_CONFLICT :
582+ reason = "refname conflict" ;
583+ break ;
584+ case REF_TRANSACTION_ERROR_CREATE_EXISTS :
585+ reason = "reference already exists" ;
586+ break ;
587+ case REF_TRANSACTION_ERROR_NONEXISTENT_REF :
588+ reason = "reference does not exist" ;
589+ break ;
590+ case REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE :
591+ reason = "incorrect old value provided" ;
592+ break ;
593+ case REF_TRANSACTION_ERROR_INVALID_NEW_VALUE :
594+ reason = "invalid new value provided" ;
595+ break ;
596+ case REF_TRANSACTION_ERROR_EXPECTED_SYMREF :
597+ reason = "expected symref but found regular ref" ;
598+ break ;
599+ default :
600+ reason = "unkown failure" ;
601+ }
602+
603+ strbuf_addf (& sb , "rejected %s %s %s %s\n" , refname ,
604+ new_oid ? oid_to_hex (new_oid ) : new_target ,
605+ old_oid ? oid_to_hex (old_oid ) : old_target ,
606+ reason );
607+
608+ fwrite (sb .buf , sb .len , 1 , stdout );
609+ strbuf_release (& sb );
610+ }
611+
568612static void parse_cmd_commit (struct ref_transaction * transaction ,
569613 const char * next , const char * end UNUSED )
570614{
@@ -573,6 +617,10 @@ static void parse_cmd_commit(struct ref_transaction *transaction,
573617 die ("commit: extra input: %s" , next );
574618 if (ref_transaction_commit (transaction , & error ))
575619 die ("commit: %s" , error .buf );
620+
621+ ref_transaction_for_each_rejected_update (transaction ,
622+ print_rejected_refs , NULL );
623+
576624 report_ok ("commit" );
577625 ref_transaction_free (transaction );
578626}
@@ -609,15 +657,15 @@ static const struct parse_cmd {
609657 { "commit" , parse_cmd_commit , 0 , UPDATE_REFS_CLOSED },
610658};
611659
612- static void update_refs_stdin (void )
660+ static void update_refs_stdin (unsigned int flags )
613661{
614662 struct strbuf input = STRBUF_INIT , err = STRBUF_INIT ;
615663 enum update_refs_state state = UPDATE_REFS_OPEN ;
616664 struct ref_transaction * transaction ;
617665 int i , j ;
618666
619667 transaction = ref_store_transaction_begin (get_main_ref_store (the_repository ),
620- 0 , & err );
668+ flags , & err );
621669 if (!transaction )
622670 die ("%s" , err .buf );
623671
@@ -685,7 +733,7 @@ static void update_refs_stdin(void)
685733 */
686734 state = cmd -> state ;
687735 transaction = ref_store_transaction_begin (get_main_ref_store (the_repository ),
688- 0 , & err );
736+ flags , & err );
689737 if (!transaction )
690738 die ("%s" , err .buf );
691739
@@ -701,6 +749,8 @@ static void update_refs_stdin(void)
701749 /* Commit by default if no transaction was requested. */
702750 if (ref_transaction_commit (transaction , & err ))
703751 die ("%s" , err .buf );
752+ ref_transaction_for_each_rejected_update (transaction ,
753+ print_rejected_refs , NULL );
704754 ref_transaction_free (transaction );
705755 break ;
706756 case UPDATE_REFS_STARTED :
@@ -727,6 +777,8 @@ int cmd_update_ref(int argc,
727777 struct object_id oid , oldoid ;
728778 int delete = 0 , no_deref = 0 , read_stdin = 0 , end_null = 0 ;
729779 int create_reflog = 0 ;
780+ unsigned int flags = 0 ;
781+
730782 struct option options [] = {
731783 OPT_STRING ( 'm' , NULL , & msg , N_ ("reason" ), N_ ("reason of the update" )),
732784 OPT_BOOL ('d' , NULL , & delete , N_ ("delete the reference" )),
@@ -735,6 +787,8 @@ int cmd_update_ref(int argc,
735787 OPT_BOOL ('z' , NULL , & end_null , N_ ("stdin has NUL-terminated arguments" )),
736788 OPT_BOOL ( 0 , "stdin" , & read_stdin , N_ ("read updates from stdin" )),
737789 OPT_BOOL ( 0 , "create-reflog" , & create_reflog , N_ ("create a reflog" )),
790+ OPT_BIT ('0' , "allow-partial" , & flags , N_ ("allow partial transactions" ),
791+ REF_TRANSACTION_ALLOW_PARTIAL ),
738792 OPT_END (),
739793 };
740794
@@ -756,9 +810,10 @@ int cmd_update_ref(int argc,
756810 usage_with_options (git_update_ref_usage , options );
757811 if (end_null )
758812 line_termination = '\0' ;
759- update_refs_stdin ();
813+ update_refs_stdin (flags );
760814 return 0 ;
761- }
815+ } else if (flags & REF_TRANSACTION_ALLOW_PARTIAL )
816+ die ("--allow-partial can only be used with --stdin" );
762817
763818 if (end_null )
764819 usage_with_options (git_update_ref_usage , options );
0 commit comments