Skip to content

Commit bc5198b

Browse files
committed
Update git-sheets to integrate with Git for auto-commit functionality
Add auto-commit support to snapshot creation, improve error handling, and refactor code structure including moving hash computation into core module. Also update documentation with workflow script example and refine .gitignore rules. - Added Git integration for auto-commit functionality in snapshot creation - Improved error handling with new GitError variant - Refactored code structure by moving hash computation to core module - Updated documentation with workflow script example - Refined .gitignore rules to better preserve snapshots while ignoring config files
1 parent 8d1d3f5 commit bc5198b

File tree

11 files changed

+248
-332
lines changed

11 files changed

+248
-332
lines changed

.gitignore

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,17 @@
1-
# Test data (generated during testing)
2-
*.csv
3-
!examples/*.csv # Keep example CSVs if you add them later
1+
# git-sheets: Ignore configuration files but preserve snapshots
42

5-
# Generated snapshots and diffs
6-
snapshots/*.toml
7-
diffs/*.json
3+
# Configuration files
4+
*.toml
5+
*.json
86

9-
# But keep the directories themselves
10-
!snapshots/.gitkeep
11-
!diffs/.gitkeep
12-
13-
# OS files
7+
# Temporary files
148
.DS_Store
15-
Thumbs.db
9+
*.tmp
10+
11+
# Log files
12+
*.log
1613

17-
# Editor
18-
.vscode/
19-
.idea/
20-
*.swp
21-
*.swo
14+
# Backup files
2215
*~
2316

24-
# Rust
2517
target/
26-
Cargo.lock # For libraries, keep it; for binaries, optional
27-
**/*.rs.bk
28-
*.pdb
29-
.aider*

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ Amount = "ghi789..."
257257
- Use `--commit` flag for auto-commit
258258
- Or commit manually with `git commit`
259259

260+
### Workflow Scripts
261+
262+
There's a sample workflow script in `scripts/sheets-session.nu` that demonstrates how to use git-sheets in a typical Excel workflow.
263+
260264
---
261265

262266
## Roadmap

src/cli/mod.rs

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,38 +19,7 @@ pub struct Cli {
1919
impl Cli {
2020
/// Execute the command
2121
pub fn execute(&self) -> Result<()> {
22-
match &self.command {
23-
Commands::Init { path } => {
24-
crate::cli::init_repository(&Path::new(path))?;
25-
}
26-
Commands::Snapshot {
27-
file,
28-
message,
29-
primary_key,
30-
auto_commit,
31-
} => {
32-
crate::cli::create_snapshot(
33-
&Path::new(file),
34-
message.clone(),
35-
primary_key.clone(),
36-
*auto_commit,
37-
)?;
38-
}
39-
Commands::Diff { from, to, format } => {
40-
let format_str = format.as_ref().map(|s| s.as_str()).unwrap_or("text");
41-
crate::cli::show_diff(&Path::new(from), &Path::new(to), format_str)?;
42-
}
43-
Commands::Verify { file } => {
44-
crate::cli::verify_snapshot(&Path::new(file))?;
45-
}
46-
Commands::Status => {
47-
crate::cli::show_status()?;
48-
}
49-
Commands::Log { limit } => {
50-
crate::cli::show_log(*limit)?;
51-
}
52-
}
53-
Ok(())
22+
run()
5423
}
5524
}
5625

@@ -178,8 +147,36 @@ fn create_snapshot(
178147
println!("Snapshot created: {}", snapshot.id);
179148

180149
if auto_commit {
181-
// Placeholder for git commit
182-
println!("Auto-commit would be performed here");
150+
// Perform actual git commit
151+
let repo_path = Path::new(".");
152+
match git2::Repository::open(repo_path) {
153+
Ok(repo) => {
154+
let mut index = repo.index()?;
155+
156+
// Add the snapshot file to the index
157+
index.add_path(&snapshot_path)?;
158+
index.write_tree()?;
159+
160+
// Create commit
161+
let tree_id = index.write_tree()?;
162+
let tree = repo.find_tree(tree_id)?;
163+
let author = git2::Signature::now("git-sheets", "git-sheets@localhost")?;
164+
let committer = author.clone();
165+
let commit_id = repo.commit(
166+
Some("HEAD"),
167+
&author,
168+
&committer,
169+
&format!("Snapshot: {}", snapshot.id),
170+
&tree,
171+
&[],
172+
)?;
173+
174+
println!("Auto-commit performed: {}", commit_id.to_string());
175+
}
176+
Err(_) => {
177+
eprintln!("Warning: Git repository not found, auto-commit skipped");
178+
}
179+
}
183180
}
184181

185182
Ok(())
@@ -319,6 +316,27 @@ fn show_status() -> Result<()> {
319316
println!("Snapshots directory: snapshots/");
320317
println!("Diffs directory: diffs/");
321318

319+
// Check if git repository exists
320+
// Check if git repository exists
321+
match git2::Repository::open(repo_path) {
322+
Ok(repo) => match repo.head() {
323+
Ok(head) => {
324+
println!(
325+
"Git HEAD: {}",
326+
head.target()
327+
.map(|oid| oid.to_string())
328+
.unwrap_or_else(|| "None".to_string())
329+
);
330+
}
331+
Err(_) => {
332+
println!("No Git HEAD");
333+
}
334+
},
335+
Err(_) => {
336+
println!("No Git repository found");
337+
}
338+
}
339+
322340
Ok(())
323341
}
324342

src/core/errors.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub enum GitSheetsError {
1818
TomlSerError(TomlSerError),
1919
/// CSV error
2020
CsvError(CsvError),
21+
/// Git error
22+
GitError(git2::Error),
2123
/// Dependency hash mismatch
2224
DependencyHashMismatch(String),
2325
/// Empty table encountered
@@ -43,6 +45,7 @@ impl PartialEq for GitSheetsError {
4345
(GitSheetsError::NoPrimaryKey, GitSheetsError::NoPrimaryKey) => true,
4446
(GitSheetsError::InvalidRowIndex(s1), GitSheetsError::InvalidRowIndex(s2)) => s1 == s2,
4547
(GitSheetsError::FileSystemError(s1), GitSheetsError::FileSystemError(s2)) => s1 == s2,
48+
(GitSheetsError::GitError(e1), GitSheetsError::GitError(e2)) => e1 == e2,
4649
_ => false,
4750
}
4851
}
@@ -55,6 +58,7 @@ impl fmt::Display for GitSheetsError {
5558
GitSheetsError::TomlError(e) => write!(f, "TOML Error: {}", e),
5659
GitSheetsError::TomlSerError(e) => write!(f, "TOML Serialization Error: {}", e),
5760
GitSheetsError::CsvError(e) => write!(f, "CSV Error: {}", e),
61+
GitSheetsError::GitError(e) => write!(f, "Git Error: {}", e),
5862
GitSheetsError::DependencyHashMismatch(msg) => {
5963
write!(f, "Dependency Hash Mismatch: {}", msg)
6064
}
@@ -73,6 +77,7 @@ impl std::error::Error for GitSheetsError {
7377
GitSheetsError::TomlError(e) => Some(e),
7478
GitSheetsError::TomlSerError(e) => Some(e),
7579
GitSheetsError::CsvError(e) => Some(e),
80+
GitSheetsError::GitError(e) => Some(e),
7681
GitSheetsError::DependencyHashMismatch(_) => None,
7782
GitSheetsError::EmptyTable => None,
7883
GitSheetsError::NoPrimaryKey => None,
@@ -106,5 +111,11 @@ impl From<CsvError> for GitSheetsError {
106111
}
107112
}
108113

114+
impl From<git2::Error> for GitSheetsError {
115+
fn from(error: git2::Error) -> Self {
116+
GitSheetsError::GitError(error)
117+
}
118+
}
119+
109120
/// Result type for git-sheets operations
110121
pub type Result<T> = std::result::Result<T, GitSheetsError>;

src/core/mod.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ use std::fs;
99
use std::io::Write;
1010
use std::path::{Path, PathBuf};
1111

12+
// Git integration
13+
use git2;
14+
1215
pub mod errors;
1316
pub use errors::{GitSheetsError, Result};
1417

@@ -115,11 +118,12 @@ impl Snapshot {
115118
/// Create a new snapshot from a table
116119
pub fn new(table: Table, message: Option<String>) -> Self {
117120
let hashes = TableHashes::compute(&table);
118-
let id = format!("{}-{}", Utc::now().timestamp(), &hashes.table_hash[..8]);
121+
let timestamp = Utc::now();
122+
let id = format!("{}-{}", timestamp.timestamp(), &hashes.table_hash[..8]);
119123

120124
Self {
121125
id,
122-
timestamp: Utc::now(),
126+
timestamp,
123127
message,
124128
table,
125129
hashes,
@@ -201,9 +205,8 @@ impl Table {
201205
rows.push(row);
202206
}
203207

204-
if rows.is_empty() {
205-
return Err(GitSheetsError::EmptyTable);
206-
}
208+
// Allow empty tables (headers but no data rows) - this is a valid state
209+
// that should be tracked as a snapshot
207210

208211
Ok(Self {
209212
headers,

0 commit comments

Comments
 (0)