reset_operations/
reset_operations.rs1use rustic_git::{Repository, ResetMode, Result};
2use std::{env, fs};
3
4fn main() -> Result<()> {
14 println!("=== Reset Operations Demo ===\n");
15
16 let temp_dir = env::temp_dir().join("rustic_git_reset_demo");
18
19 if temp_dir.exists() {
21 fs::remove_dir_all(&temp_dir)?;
22 }
23
24 println!("Working in temporary directory: {:?}\n", temp_dir);
25
26 let repo = Repository::init(&temp_dir, false)?;
28
29 repo.config().set_user("Example User", "example@test.com")?;
31
32 demonstrate_reset_modes(&repo, &temp_dir)?;
33 demonstrate_file_resets(&repo, &temp_dir)?;
34 demonstrate_error_handling(&repo)?;
35
36 println!("\n=== Reset Operations Demo Complete ===");
37
38 fs::remove_dir_all(&temp_dir)?;
40 Ok(())
41}
42
43fn demonstrate_reset_modes(repo: &Repository, temp_dir: &std::path::Path) -> Result<()> {
44 println!("--- Demonstrating Reset Modes ---\n");
45
46 println!("1. Creating initial commits...");
48
49 let file1_path = temp_dir.join("file1.txt");
51 fs::write(&file1_path, "Initial content")?;
52 repo.add(&["file1.txt"])?;
53 let first_commit = repo.commit("Initial commit")?;
54 println!(" Created first commit: {}", first_commit);
55
56 let file2_path = temp_dir.join("file2.txt");
58 fs::write(&file2_path, "Second file content")?;
59 repo.add(&["file2.txt"])?;
60 let second_commit = repo.commit("Add file2.txt")?;
61 println!(" Created second commit: {}", second_commit);
62
63 fs::write(&file1_path, "Modified content")?;
65 repo.add(&["file1.txt"])?;
66 let third_commit = repo.commit("Modify file1.txt")?;
67 println!(" Created third commit: {}", third_commit);
68
69 println!("\n2. Current repository state:");
71 show_repo_state(repo)?;
72
73 println!("\n3. Performing soft reset to second commit...");
75 repo.reset_soft(&second_commit.to_string())?;
76
77 println!(" After soft reset:");
78 show_repo_state(repo)?;
79 println!(" Note: Changes are still staged, working directory unchanged");
80
81 repo.reset_hard(&third_commit.to_string())?;
83
84 println!("\n4. Performing mixed reset to second commit...");
86 repo.reset_mixed(&second_commit.to_string())?;
87
88 println!(" After mixed reset:");
89 show_repo_state(repo)?;
90 println!(" Note: Changes are unstaged but preserved in working directory");
91
92 repo.reset_hard(&third_commit.to_string())?;
94
95 println!("\n5. Performing hard reset to first commit...");
97 repo.reset_hard(&first_commit.to_string())?;
98
99 println!(" After hard reset:");
100 show_repo_state(repo)?;
101 println!(" Note: All changes discarded, working directory matches commit");
102
103 println!("\n6. Using reset_with_mode for explicit control...");
105
106 fs::write(&file2_path, "Recreated second file")?;
108 repo.add(&["file2.txt"])?;
109 let _new_commit = repo.commit("Recreate file2.txt")?;
110
111 repo.reset_with_mode(&first_commit.to_string(), ResetMode::Mixed)?;
112 println!(" Used ResetMode::Mixed explicitly");
113 show_repo_state(repo)?;
114
115 Ok(())
116}
117
118fn demonstrate_file_resets(repo: &Repository, temp_dir: &std::path::Path) -> Result<()> {
119 println!("\n--- Demonstrating File-Specific Resets ---\n");
120
121 println!("1. Creating and staging multiple files...");
123
124 let file_a = temp_dir.join("fileA.txt");
125 let file_b = temp_dir.join("fileB.txt");
126
127 fs::write(&file_a, "Content A")?;
128 fs::write(&file_b, "Content B")?;
129
130 repo.add(&["fileA.txt", "fileB.txt"])?;
131 println!(" Staged fileA.txt and fileB.txt");
132
133 show_repo_state(repo)?;
134
135 println!("\n2. Resetting single file (fileA.txt)...");
137 repo.reset_file("fileA.txt")?;
138
139 println!(" After resetting fileA.txt:");
140 show_repo_state(repo)?;
141 println!(" Note: fileA.txt is unstaged, fileB.txt remains staged");
142
143 println!("\n3. Performing mixed reset to HEAD (unstage all)...");
145 repo.reset_mixed("HEAD")?;
146
147 println!(" After reset HEAD:");
148 show_repo_state(repo)?;
149 println!(" Note: All staged changes are now unstaged");
150
151 Ok(())
152}
153
154fn demonstrate_error_handling(repo: &Repository) -> Result<()> {
155 println!("\n--- Demonstrating Error Handling ---\n");
156
157 println!("1. Attempting reset to invalid commit hash...");
159 match repo.reset_mixed("invalid_commit_hash") {
160 Ok(_) => println!(" Unexpected success!"),
161 Err(e) => println!(" Expected error: {}", e),
162 }
163
164 println!("\n2. Attempting reset to non-existent reference...");
166 match repo.reset_soft("nonexistent-branch") {
167 Ok(_) => println!(" Unexpected success!"),
168 Err(e) => println!(" Expected error: {}", e),
169 }
170
171 println!("\n Error handling works correctly!");
172 Ok(())
173}
174
175fn show_repo_state(repo: &Repository) -> Result<()> {
176 let status = repo.status()?;
177
178 let staged_count = status.staged_files().count();
179 let unstaged_count = status.unstaged_files().count();
180 let untracked_count = status.untracked_entries().count();
181
182 println!(" Repository state:");
183 println!(" - Staged files: {}", staged_count);
184 println!(" - Modified files: {}", unstaged_count);
185 println!(" - Untracked files: {}", untracked_count);
186
187 if staged_count > 0 {
188 println!(" - Staged:");
189 for file in status.staged_files().take(5) {
190 println!(" * {}", file.path.display());
191 }
192 }
193
194 if unstaged_count > 0 {
195 println!(" - Modified:");
196 for file in status.unstaged_files().take(5) {
197 println!(" * {}", file.path.display());
198 }
199 }
200
201 if untracked_count > 0 {
202 println!(" - Untracked:");
203 for file in status.untracked_entries().take(5) {
204 println!(" * {}", file.path.display());
205 }
206 }
207
208 Ok(())
209}