@@ -11,13 +11,15 @@ Rustic Git provides a simple, ergonomic interface for common Git operations. It
1111- ✅ Repository initialization and opening
1212- ✅ ** Enhanced file status checking** with separate staged/unstaged tracking
1313- ✅ ** Precise Git state representation** using IndexStatus and WorktreeStatus enums
14- - ✅ File staging (add files, add all, add updates)
14+ - ✅ File staging (add files, add all, add updates)
1515- ✅ Commit creation with hash return
16+ - ✅ ** Complete branch operations** with type-safe Branch API
17+ - ✅ ** Branch management** (create, delete, checkout, list)
1618- ✅ Type-safe error handling with custom GitError enum
1719- ✅ Universal ` Hash ` type for Git objects
18- - ✅ ** Immutable collections** (Box<[ FileEntry ] >) for memory efficiency
20+ - ✅ ** Immutable collections** (Box<[ T ] >) for memory efficiency
1921- ✅ ** Const enum conversions** with zero runtime cost
20- - ✅ Comprehensive test coverage (80 + tests)
22+ - ✅ Comprehensive test coverage (90 + tests)
2123
2224## Installation
2325
@@ -47,7 +49,7 @@ fn main() -> Result<()> {
4749 let staged_count = status . staged_files (). count ();
4850 let unstaged_count = status . unstaged_files (). count ();
4951 let untracked_count = status . untracked_entries (). count ();
50-
52+
5153 println! (" Repository status:" );
5254 println! (" Staged: {} files" , staged_count );
5355 println! (" Unstaged: {} files" , unstaged_count );
@@ -69,6 +71,14 @@ fn main() -> Result<()> {
6971 let hash = repo . commit (" Add new features" )? ;
7072 println! (" Created commit: {}" , hash . short ());
7173
74+ // Branch operations
75+ let branches = repo . branches ()? ;
76+ println! (" Current branch: {:?}" , repo . current_branch ()? . map (| b | b . name));
77+
78+ // Create and switch to new branch
79+ let feature_branch = repo . checkout_new (" feature/new-api" , None )? ;
80+ println! (" Created and switched to: {}" , feature_branch . name);
81+
7282 Ok (())
7383}
7484```
@@ -128,8 +138,8 @@ let modified_in_worktree: Vec<_> = status
128138
129139// Work with all file entries directly
130140for entry in status . entries () {
131- println! (" [{}][{}] {}" ,
132- entry . index_status. to_char (),
141+ println! (" [{}][{}] {}" ,
142+ entry . index_status. to_char (),
133143 entry . worktree_status. to_char (),
134144 entry . path. display ()
135145 );
@@ -247,6 +257,165 @@ let hash = repo.commit_with_author(
247257)? ;
248258```
249259
260+ ### Branch Operations
261+
262+ #### ` Repository::branches() -> Result<BranchList> `
263+
264+ List all branches in the repository.
265+
266+ ``` rust
267+ let branches = repo . branches ()? ;
268+
269+ // Check total count
270+ println! (" Total branches: {}" , branches . len ());
271+ println! (" Local branches: {}" , branches . local_count ());
272+ println! (" Remote branches: {}" , branches . remote_count ());
273+
274+ // Iterate over all branches
275+ for branch in branches . iter () {
276+ let marker = if branch . is_current { " *" } else { " " };
277+ println! (" {}{} ({})" , marker , branch . name, branch . commit_hash. short ());
278+ }
279+
280+ // Filter by type
281+ let local_branches : Vec <_ > = branches . local (). collect ();
282+ let remote_branches : Vec <_ > = branches . remote (). collect ();
283+ ```
284+
285+ #### ` Repository::current_branch() -> Result<Option<Branch>> `
286+
287+ Get the currently checked out branch.
288+
289+ ``` rust
290+ if let Some (current ) = repo . current_branch ()? {
291+ println! (" On branch: {}" , current . name);
292+ println! (" Last commit: {}" , current . commit_hash. short ());
293+ if let Some (upstream ) = & current . upstream {
294+ println! (" Tracking: {}" , upstream );
295+ }
296+ }
297+ ```
298+
299+ #### ` Repository::create_branch(name, start_point) -> Result<Branch> `
300+
301+ Create a new branch.
302+
303+ ``` rust
304+ // Create branch from current HEAD
305+ let branch = repo . create_branch (" feature/new-api" , None )? ;
306+
307+ // Create branch from specific commit/branch
308+ let branch = repo . create_branch (" hotfix/bug-123" , Some (" main" ))? ;
309+ let branch = repo . create_branch (" release/v1.0" , Some (" develop" ))? ;
310+ ```
311+
312+ #### ` Repository::checkout(branch) -> Result<()> `
313+
314+ Switch to an existing branch.
315+
316+ ``` rust
317+ let branches = repo . branches ()? ;
318+ if let Some (branch ) = branches . find (" develop" ) {
319+ repo . checkout (& branch )? ;
320+ println! (" Switched to: {}" , branch . name);
321+ }
322+ ```
323+
324+ #### ` Repository::checkout_new(name, start_point) -> Result<Branch> `
325+
326+ Create a new branch and switch to it immediately.
327+
328+ ``` rust
329+ // Create and checkout new branch from current HEAD
330+ let branch = repo . checkout_new (" feature/auth" , None )? ;
331+
332+ // Create and checkout from specific starting point
333+ let branch = repo . checkout_new (" feature/api" , Some (" develop" ))? ;
334+ println! (" Created and switched to: {}" , branch . name);
335+ ```
336+
337+ #### ` Repository::delete_branch(branch, force) -> Result<()> `
338+
339+ Delete a branch.
340+
341+ ``` rust
342+ let branches = repo . branches ()? ;
343+ if let Some (branch ) = branches . find (" old-feature" ) {
344+ // Safe delete (fails if unmerged)
345+ repo . delete_branch (& branch , false )? ;
346+
347+ // Force delete
348+ // repo.delete_branch(&branch, true)?;
349+ }
350+ ```
351+
352+ #### Branch Types
353+
354+ The branch API uses structured types for type safety:
355+
356+ ``` rust
357+ // Branch represents a single branch
358+ pub struct Branch {
359+ pub name : String ,
360+ pub branch_type : BranchType ,
361+ pub is_current : bool ,
362+ pub commit_hash : Hash ,
363+ pub upstream : Option <String >,
364+ }
365+
366+ // Branch type enumeration
367+ pub enum BranchType {
368+ Local , // Local branch
369+ RemoteTracking , // Remote-tracking branch
370+ }
371+
372+ // BranchList contains all branches with efficient methods
373+ pub struct BranchList {
374+ // Methods:
375+ // - iter() -> iterator over all branches
376+ // - local() -> iterator over local branches
377+ // - remote() -> iterator over remote branches
378+ // - current() -> get current branch
379+ // - find(name) -> find branch by exact name
380+ // - find_by_short_name(name) -> find by short name
381+ // - len(), is_empty() -> collection info
382+ }
383+ ```
384+
385+ #### Branch Search and Filtering
386+
387+ ``` rust
388+ let branches = repo . branches ()? ;
389+
390+ // Find specific branches
391+ if let Some (main ) = branches . find (" main" ) {
392+ println! (" Found main branch: {}" , main . commit_hash. short ());
393+ }
394+
395+ // Find by short name (useful for remote branches)
396+ if let Some (feature ) = branches . find_by_short_name (" feature" ) {
397+ println! (" Found feature branch: {}" , feature . name);
398+ }
399+
400+ // Filter by type
401+ println! (" Local branches:" );
402+ for branch in branches . local () {
403+ println! (" - {}" , branch . name);
404+ }
405+
406+ if branches . remote_count () > 0 {
407+ println! (" Remote branches:" );
408+ for branch in branches . remote () {
409+ println! (" - {}" , branch . name);
410+ }
411+ }
412+
413+ // Get current branch
414+ if let Some (current ) = branches . current () {
415+ println! (" Currently on: {}" , current . name);
416+ }
417+ ```
418+
250419### Hash Type
251420
252421The ` Hash ` type represents Git object hashes (commits, trees, blobs, etc.).
@@ -297,10 +466,10 @@ fn main() -> rustic_git::Result<()> {
297466 let status = repo . status ()? ;
298467 let untracked_count = status . untracked_entries (). count ();
299468 println! (" Found {} untracked files" , untracked_count );
300-
469+
301470 // Display detailed status
302471 for entry in status . entries () {
303- println! (" [{}][{}] {}" ,
472+ println! (" [{}][{}] {}" ,
304473 entry . index_status. to_char (),
305474 entry . worktree_status. to_char (),
306475 entry . path. display ()
@@ -314,7 +483,7 @@ fn main() -> rustic_git::Result<()> {
314483 let status = repo . status ()? ;
315484 let staged_files : Vec <_ > = status . staged_files (). collect ();
316485 println! (" Staged {} files" , staged_files . len ());
317-
486+
318487 // Show specifically added files
319488 let added_files : Vec <_ > = status
320489 . files_with_index_status (IndexStatus :: Added )
@@ -325,10 +494,41 @@ fn main() -> rustic_git::Result<()> {
325494 let hash = repo . commit (" Initial commit with project structure" )? ;
326495 println! (" Created commit: {}" , hash . short ());
327496
497+ // Branch operations workflow
498+ let branches = repo . branches ()? ;
499+ println! (" Current branch: {:?}" , repo . current_branch ()? . map (| b | b . name));
500+
501+ // Create a feature branch
502+ let feature_branch = repo . checkout_new (" feature/user-auth" , None )? ;
503+ println! (" Created and switched to: {}" , feature_branch . name);
504+
505+ // Make changes on the feature branch
506+ fs :: write (" ./my-project/src/auth.rs" , " pub fn authenticate() { /* TODO */ }" )? ;
507+ repo . add (& [" src/auth.rs" ])? ;
508+ let feature_commit = repo . commit (" Add authentication module" )? ;
509+ println! (" Feature commit: {}" , feature_commit . short ());
510+
511+ // Switch back to main and create another branch
512+ if let Some (main_branch ) = branches . find (" main" ) {
513+ repo . checkout (& main_branch )? ;
514+ println! (" Switched back to main" );
515+ }
516+
517+ let doc_branch = repo . create_branch (" docs/api" , None )? ;
518+ println! (" Created documentation branch: {}" , doc_branch . name);
519+
520+ // List all branches
521+ let final_branches = repo . branches ()? ;
522+ println! (" \ n Final branch summary:" );
523+ for branch in final_branches . iter () {
524+ let marker = if branch . is_current { " *" } else { " " };
525+ println! (" {}{} ({})" , marker , branch . name, branch . commit_hash. short ());
526+ }
527+
328528 // Verify clean state
329529 let status = repo . status ()? ;
330530 assert! (status . is_clean ());
331- println! (" Repository is now clean!" );
531+ println! (" Repository is clean!" );
332532
333533 Ok (())
334534}
@@ -356,6 +556,9 @@ cargo run --example staging_operations
356556# Commit workflows and Hash type usage
357557cargo run --example commit_workflows
358558
559+ # Branch operations (create, delete, checkout, list)
560+ cargo run --example branch_operations
561+
359562# Error handling patterns and recovery strategies
360563cargo run --example error_handling
361564```
@@ -367,6 +570,7 @@ cargo run --example error_handling
367570- ** ` status_checking.rs ` ** - Comprehensive demonstration of GitStatus and FileStatus usage with all query methods and filtering capabilities
368571- ** ` staging_operations.rs ` ** - Shows all staging methods (add, add_all, add_update) with before/after status comparisons
369572- ** ` commit_workflows.rs ` ** - Demonstrates commit operations and Hash type methods, including custom authors and hash management
573+ - ** ` branch_operations.rs ` ** - Complete branch management demonstration: create, checkout, delete branches, and BranchList filtering
370574- ** ` error_handling.rs ` ** - Comprehensive error handling patterns showing GitError variants, recovery strategies, and best practices
371575
372576All examples use temporary directories in ` /tmp/ ` and include automatic cleanup for safe execution.
@@ -425,6 +629,7 @@ cargo run --example repository_operations
425629cargo run --example status_checking
426630cargo run --example staging_operations
427631cargo run --example commit_workflows
632+ cargo run --example branch_operations
428633cargo run --example error_handling
429634```
430635
@@ -442,12 +647,11 @@ cargo run --example error_handling
442647Future planned features:
443648- [ ] Commit history and log operations
444649- [ ] Diff operations
445- - [ ] Branch operations
446650- [ ] Remote operations (clone, push, pull)
447651- [ ] Merge and rebase operations
448652- [ ] Tag operations
449653- [ ] Stash operations
450654
451655## Version
452656
453- Current version: 0.1.0 - Basic git workflow (init, status, add, commit)
657+ Current version: 0.1.0 - Basic git workflow with branch operations (init, status, add, commit, branch )
0 commit comments