3
3
#include "builtin.h"
4
4
#include "config.h"
5
5
#include "gettext.h"
6
+ #include "hex.h"
7
+ #include "odb.h"
6
8
#include "revision.h"
7
9
#include "reachable.h"
8
10
#include "wildmatch.h"
17
19
#define BUILTIN_REFLOG_LIST_USAGE \
18
20
N_("git reflog list")
19
21
20
- #define BUILTIN_REFLOG_EXPIRE_USAGE \
21
- N_("git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n" \
22
- " [--rewrite] [--updateref] [--stale-fix]\n" \
23
- " [--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...]")
22
+ #define BUILTIN_REFLOG_EXISTS_USAGE \
23
+ N_("git reflog exists <ref>")
24
+
25
+ #define BUILTIN_REFLOG_WRITE_USAGE \
26
+ N_("git reflog write <ref> <old-oid> <new-oid> <message>")
24
27
25
28
#define BUILTIN_REFLOG_DELETE_USAGE \
26
29
N_("git reflog delete [--rewrite] [--updateref]\n" \
27
30
" [--dry-run | -n] [--verbose] <ref>@{<specifier>}...")
28
31
29
- #define BUILTIN_REFLOG_EXISTS_USAGE \
30
- N_("git reflog exists <ref>")
31
-
32
32
#define BUILTIN_REFLOG_DROP_USAGE \
33
33
N_("git reflog drop [--all [--single-worktree] | <refs>...]")
34
34
35
+ #define BUILTIN_REFLOG_EXPIRE_USAGE \
36
+ N_("git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n" \
37
+ " [--rewrite] [--updateref] [--stale-fix]\n" \
38
+ " [--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...]")
39
+
35
40
static const char * const reflog_show_usage [] = {
36
41
BUILTIN_REFLOG_SHOW_USAGE ,
37
42
NULL ,
@@ -42,33 +47,39 @@ static const char *const reflog_list_usage[] = {
42
47
NULL ,
43
48
};
44
49
45
- static const char * const reflog_expire_usage [] = {
46
- BUILTIN_REFLOG_EXPIRE_USAGE ,
47
- NULL
50
+ static const char * const reflog_exists_usage [] = {
51
+ BUILTIN_REFLOG_EXISTS_USAGE ,
52
+ NULL ,
53
+ };
54
+
55
+ static const char * const reflog_write_usage [] = {
56
+ BUILTIN_REFLOG_WRITE_USAGE ,
57
+ NULL ,
48
58
};
49
59
50
60
static const char * const reflog_delete_usage [] = {
51
61
BUILTIN_REFLOG_DELETE_USAGE ,
52
62
NULL
53
63
};
54
64
55
- static const char * const reflog_exists_usage [] = {
56
- BUILTIN_REFLOG_EXISTS_USAGE ,
57
- NULL ,
58
- };
59
-
60
65
static const char * const reflog_drop_usage [] = {
61
66
BUILTIN_REFLOG_DROP_USAGE ,
62
67
NULL ,
63
68
};
64
69
70
+ static const char * const reflog_expire_usage [] = {
71
+ BUILTIN_REFLOG_EXPIRE_USAGE ,
72
+ NULL
73
+ };
74
+
65
75
static const char * const reflog_usage [] = {
66
76
BUILTIN_REFLOG_SHOW_USAGE ,
67
77
BUILTIN_REFLOG_LIST_USAGE ,
68
- BUILTIN_REFLOG_EXPIRE_USAGE ,
78
+ BUILTIN_REFLOG_EXISTS_USAGE ,
79
+ BUILTIN_REFLOG_WRITE_USAGE ,
69
80
BUILTIN_REFLOG_DELETE_USAGE ,
70
81
BUILTIN_REFLOG_DROP_USAGE ,
71
- BUILTIN_REFLOG_EXISTS_USAGE ,
82
+ BUILTIN_REFLOG_EXPIRE_USAGE ,
72
83
NULL
73
84
};
74
85
@@ -395,6 +406,59 @@ static int cmd_reflog_drop(int argc, const char **argv, const char *prefix,
395
406
return ret ;
396
407
}
397
408
409
+ static int cmd_reflog_write (int argc , const char * * argv , const char * prefix ,
410
+ struct repository * repo )
411
+ {
412
+ const struct option options [] = {
413
+ OPT_END ()
414
+ };
415
+ struct object_id old_oid , new_oid ;
416
+ struct strbuf err = STRBUF_INIT ;
417
+ struct ref_transaction * tx ;
418
+ const char * ref , * message ;
419
+ int ret ;
420
+
421
+ argc = parse_options (argc , argv , prefix , options , reflog_write_usage , 0 );
422
+ if (argc != 4 )
423
+ usage_with_options (reflog_write_usage , options );
424
+
425
+ ref = argv [0 ];
426
+ if (!is_root_ref (ref ) && check_refname_format (ref , 0 ))
427
+ die (_ ("invalid reference name: %s" ), ref );
428
+
429
+ ret = get_oid_hex_algop (argv [1 ], & old_oid , repo -> hash_algo );
430
+ if (ret )
431
+ die (_ ("invalid old object ID: '%s'" ), argv [1 ]);
432
+ if (!is_null_oid (& old_oid ) && !odb_has_object (repo -> objects , & old_oid , 0 ))
433
+ die (_ ("old object '%s' does not exist" ), argv [1 ]);
434
+
435
+ ret = get_oid_hex_algop (argv [2 ], & new_oid , repo -> hash_algo );
436
+ if (ret )
437
+ die (_ ("invalid new object ID: '%s'" ), argv [2 ]);
438
+ if (!is_null_oid (& new_oid ) && !odb_has_object (repo -> objects , & new_oid , 0 ))
439
+ die (_ ("new object '%s' does not exist" ), argv [2 ]);
440
+
441
+ message = argv [3 ];
442
+
443
+ tx = ref_store_transaction_begin (get_main_ref_store (repo ), 0 , & err );
444
+ if (!tx )
445
+ die (_ ("cannot start transaction: %s" ), err .buf );
446
+
447
+ ret = ref_transaction_update_reflog (tx , ref , & new_oid , & old_oid ,
448
+ git_committer_info (0 ),
449
+ message , 0 , & err );
450
+ if (ret )
451
+ die (_ ("cannot queue reflog update: %s" ), err .buf );
452
+
453
+ ret = ref_transaction_commit (tx , & err );
454
+ if (ret )
455
+ die (_ ("cannot commit reflog update: %s" ), err .buf );
456
+
457
+ ref_transaction_free (tx );
458
+ strbuf_release (& err );
459
+ return 0 ;
460
+ }
461
+
398
462
/*
399
463
* main "reflog"
400
464
*/
@@ -407,10 +471,11 @@ int cmd_reflog(int argc,
407
471
struct option options [] = {
408
472
OPT_SUBCOMMAND ("show" , & fn , cmd_reflog_show ),
409
473
OPT_SUBCOMMAND ("list" , & fn , cmd_reflog_list ),
410
- OPT_SUBCOMMAND ("expire" , & fn , cmd_reflog_expire ),
411
- OPT_SUBCOMMAND ("delete" , & fn , cmd_reflog_delete ),
412
474
OPT_SUBCOMMAND ("exists" , & fn , cmd_reflog_exists ),
475
+ OPT_SUBCOMMAND ("write" , & fn , cmd_reflog_write ),
476
+ OPT_SUBCOMMAND ("delete" , & fn , cmd_reflog_delete ),
413
477
OPT_SUBCOMMAND ("drop" , & fn , cmd_reflog_drop ),
478
+ OPT_SUBCOMMAND ("expire" , & fn , cmd_reflog_expire ),
414
479
OPT_END ()
415
480
};
416
481
0 commit comments