Skip to content

Commit 707ad35

Browse files
CopilotByron
andcommitted
Add demonstration example for raw commit methods
Co-authored-by: Byron <[email protected]>
1 parent 3c403e2 commit 707ad35

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

gix/examples/raw-commit-demo.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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

Comments
 (0)