1
+ // Demonstrates the difference between regular commit methods and raw commit methods
2
+ // Regular commits update references automatically, raw commits just create the object
3
+
4
+ use anyhow:: Context ;
5
+ use gix:: config:: tree:: { Author , Committer } ;
6
+
7
+ fn main ( ) -> anyhow:: Result < ( ) > {
8
+ let git_dir = std:: env:: args_os ( )
9
+ . nth ( 1 )
10
+ . context ( "First argument needs to be the directory to initialize the repository in" ) ?;
11
+ let mut repo = gix:: init_bare ( git_dir) ?;
12
+
13
+ println ! ( "Repo (bare): {}" , repo. git_dir( ) . display( ) ) ;
14
+
15
+ // Set up author/committer
16
+ let mut config = repo. config_snapshot_mut ( ) ;
17
+ config. set_raw_value ( & Author :: NAME , "Demo User" ) ?;
18
+ config
. set_raw_value ( & Author :: EMAIL , "[email protected] " ) ?
;
19
+ config. set_raw_value ( & Committer :: NAME , "Demo User" ) ?;
20
+ config
. set_raw_value ( & Committer :: EMAIL , "[email protected] " ) ?
;
21
+ let repo = config. commit_auto_rollback ( ) ?;
22
+
23
+ let empty_tree_id = repo. write_object ( & gix:: objs:: Tree :: empty ( ) ) ?. detach ( ) ;
24
+
25
+ println ! ( "\n === Demonstrating commit_raw ===" ) ;
26
+
27
+ // Create a raw commit - this doesn't update any references
28
+ let raw_commit = repo. commit_raw ( "Raw commit message" , empty_tree_id, gix:: commit:: NO_PARENT_IDS ) ?;
29
+
30
+ println ! ( "Created raw commit object (not yet written to database):" ) ;
31
+ println ! ( " Message: {}" , raw_commit. message) ;
32
+ println ! ( " Tree: {}" , raw_commit. tree) ;
33
+ println ! ( " Author: {:?}" , raw_commit. author. name) ;
34
+
35
+ // HEAD should still be unborn at this point
36
+ let head_before = match repo. head ( ) {
37
+ Ok ( _) => "exists" ,
38
+ Err ( _) => "unborn"
39
+ } ;
40
+ println ! ( "HEAD status before writing raw commit: {}" , head_before) ;
41
+
42
+ // Now write the commit object to the database
43
+ let raw_commit_id = repo. write_object ( & raw_commit) ?;
44
+ println ! ( "Raw commit written to database with ID: {}" , raw_commit_id) ;
45
+
46
+ // HEAD still shouldn't point to our commit since we didn't update references
47
+ let head_after = match repo. head ( ) {
48
+ Ok ( _) => "exists" ,
49
+ Err ( _) => "unborn"
50
+ } ;
51
+ println ! ( "HEAD status after writing raw commit: {}" , head_after) ;
52
+
53
+ println ! ( "\n === Demonstrating commit_as_raw ===" ) ;
54
+
55
+ // Create specific author/committer signatures
56
+ let committer = gix:: actor:: Signature {
57
+ name : "Committer Name" . into ( ) ,
58
+ email : "[email protected] " . into ( ) ,
59
+ time : gix_date:: Time :: now_local_or_utc ( ) ,
60
+ } ;
61
+ let author = gix:: actor:: Signature {
62
+ name : "Author Name" . into ( ) ,
63
+ email : "[email protected] " . into ( ) ,
64
+ time : gix_date:: Time :: now_local_or_utc ( ) ,
65
+ } ;
66
+
67
+ let raw_commit2 = repo. commit_as_raw (
68
+ committer. to_ref ( & mut Default :: default ( ) ) ,
69
+ author. to_ref ( & mut Default :: default ( ) ) ,
70
+ "Second raw commit with custom author/committer" ,
71
+ empty_tree_id,
72
+ [ raw_commit_id. detach ( ) ] ,
73
+ ) ?;
74
+
75
+ println ! ( "Created second raw commit with custom author/committer:" ) ;
76
+ println ! ( " Message: {}" , raw_commit2. message) ;
77
+ println ! ( " Author: {} <{}>" , raw_commit2. author. name, raw_commit2. author. email) ;
78
+ println ! ( " Committer: {} <{}>" , raw_commit2. committer. name, raw_commit2. committer. email) ;
79
+
80
+ let raw_commit_id2 = repo. write_object ( & raw_commit2) ?;
81
+ println ! ( "Second raw commit written with ID: {}" , raw_commit_id2) ;
82
+
83
+ println ! ( "\n === Comparing with regular commit ===" ) ;
84
+
85
+ // First, let's update HEAD to point to our second raw commit so we can demonstrate
86
+ // the difference. In practice, you might update references manually.
87
+ println ! ( "To demonstrate regular commit, we first need to set HEAD manually:" ) ;
88
+
89
+ // Use the regular commit method which updates HEAD automatically
90
+ // For the initial commit, we'll use no parents
91
+ let regular_commit_id = repo. commit ( "HEAD" , "Regular commit that updates HEAD" , empty_tree_id, gix:: commit:: NO_PARENT_IDS ) ?;
92
+ println ! ( "Regular commit created with ID: {}" , regular_commit_id) ;
93
+
94
+ // Now HEAD should point to our commit
95
+ let head_final = match repo. head ( ) {
96
+ Ok ( mut head) => {
97
+ match head. try_peel_to_id_in_place ( ) . unwrap_or ( None ) {
98
+ Some ( id) => format ! ( "points to {}" , id) ,
99
+ None => "exists but unborn" . to_string ( ) ,
100
+ }
101
+ }
102
+ Err ( _) => "unborn" . to_string ( )
103
+ } ;
104
+ println ! ( "HEAD status after regular commit: {}" , head_final) ;
105
+
106
+ println ! ( "\n === Summary ===" ) ;
107
+ println ! ( "Raw commits allow you to:" ) ;
108
+ println ! ( "1. Create commit objects without updating any references" ) ;
109
+ println ! ( "2. Write them to the database when you're ready" ) ;
110
+ println ! ( "3. Have full control over when and how references are updated" ) ;
111
+ println ! ( "4. Batch commit operations for better performance" ) ;
112
+
113
+ Ok ( ( ) )
114
+ }
0 commit comments