Skip to content

Commit 21791dd

Browse files
committed
feat: major improvements
1 parent 002a4fa commit 21791dd

File tree

15 files changed

+1172
-816
lines changed

15 files changed

+1172
-816
lines changed

Cargo.lock

Lines changed: 122 additions & 509 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "git-wippy"
33
description = "Git stash with super powers"
44
documentation = "https://github.com/mekwall/git-wippy"
5-
version = "0.1.0"
5+
version = "0.2.0"
66
edition = "2021"
77

88
[[bin]]
@@ -11,17 +11,19 @@ path = "src/main.rs"
1111
doc = false
1212

1313
[dependencies]
14-
clap = { version = "4.5", features = [] }
15-
tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "process"] }
16-
anyhow = "1.0"
17-
chrono = "0.4"
18-
dialoguer = "0.11"
14+
clap = { version = "4.5.3", features = [] }
15+
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread", "process"] }
16+
anyhow = "1.0.81"
17+
chrono = "0.4.35"
18+
dialoguer = "0.11.0"
19+
async-trait = "0.1.77"
20+
futures = "0.3.30"
1921

2022
[dev-dependencies]
21-
precious = "0.6.2"
22-
tokio-test = "0.4"
23-
assert_cmd = "2.0"
24-
tempfile = "3.2"
25-
mockall = "0.12"
26-
async-trait = "0.1"
27-
regex = "1.5"
23+
tokio-test = "0.4.3"
24+
assert_cmd = "2.0.14"
25+
tempfile = "3.10.1"
26+
mockall = "0.12.1"
27+
async-trait = "0.1.77"
28+
regex = "1.10.3"
29+
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread", "process", "fs"] }

README.md

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,36 @@
11
# git-wippy
22

3-
## Description
3+
A Git utility for managing work-in-progress changes across branches with super powers! 🦸‍♂️
44

5-
Git stash with super powers! A dev tool to simplify working with work in progress changes that acts as a sub command for git.
5+
## Features
66

7-
When saving your work it creates a temporary WIP branch (pushes to remote by default) that stores your changes and allows you to restore them later. It even keeps track of which branch you were working on and which files were staged and untracked.
7+
- 🔄 Save WIP changes to a dedicated branch
8+
- 📋 List all your WIP branches
9+
- ⚡ Restore WIP changes back to their original branches
10+
- 🔒 Thread-safe and async operations
11+
- 🌟 Maintains file states (staged, unstaged, untracked)
12+
- 🔍 Smart branch naming with username and timestamps
13+
- 🌐 Supports both local and remote operations
814

915
## Installation
1016

11-
Coming soon!
17+
- Coming soon!
18+
-
19+
- Download the latest binary for your platform under releases and put it in your executable paths.
1220

13-
Download the latest binary for your platform under releases and put it in your executable paths.
21+
* ```bash
22+
23+
```
24+
25+
- # Install using cargo
26+
27+
* cargo install git-wippy
28+
29+
- ```
30+
31+
```
32+
-
33+
- Or download the latest binary for your platform from the [releases page](https://github.com/mekwall/git-wippy/releases).
1434

1535
## Build and install from sources
1636

@@ -21,19 +41,58 @@ To install, follow these steps:
2141
1. Install [Rust and cargo](https://www.rust-lang.org/tools/install).
2242
2. Clone this repository.
2343
3. Navigate to the project directory and run `cargo build -r`.
24-
4. Copy `git-wippy` binary from `target/release` to somehwere that is in your executable paths.
44+
4. Copy `git-wippy` binary from `target/release` to somewhere in your executable paths.
2545

2646
## Usage
2747

2848
When `git-wippy` is located somewhere in your executable paths it can be used as a `git` subcommand.
2949

30-
Executed with `git wippy <command>`:
50+
### Commands
51+
52+
```bash
53+
# Save your WIP changes (pushes to remote by default)
54+
git wippy save
55+
56+
# Save changes locally only
57+
git wippy save --local
58+
59+
# List all your WIP branches
60+
git wippy list
61+
62+
# Restore changes from a WIP branch
63+
git wippy restore
64+
```
65+
66+
## How It Works
67+
68+
1. **Saving Changes**:
3169

32-
- `restore`: Restore your WIP changes
33-
- `save`: Save your WIP changes (use `--local` flag to only save locally)
34-
- `list`: List all WIP branches
70+
- Creates a WIP branch named `wip/{username}/{timestamp}`
71+
- Preserves the state of all files (staged, unstaged, untracked)
72+
- Stores metadata about the source branch
73+
- Optionally pushes to remote
3574

36-
## Contributing
75+
2. **Listing Changes**:
76+
77+
- Shows all WIP branches for the current user
78+
- Filters branches matching `wip/{username}/*`
79+
- Handles both local and remote branches
80+
81+
3. **Restoring Changes**:
82+
- Retrieves changes from the WIP branch
83+
- Recreates the original file states
84+
- Returns to the source branch
85+
- Cleans up the WIP branch
86+
87+
## Development
88+
89+
### Requirements
90+
91+
- Git 2.0+
92+
- Rust 1.70+
93+
- Git username configured (`git config user.name`)
94+
95+
### Contributing
3796

3897
If you want to contribute to this project, please follow these steps:
3998

@@ -43,6 +102,23 @@ If you want to contribute to this project, please follow these steps:
43102
4. Push your changes to your fork.
44103
5. Create a pull request.
45104

105+
```bash
106+
# Run tests
107+
cargo test
108+
109+
# Build release version
110+
cargo build -r
111+
112+
# Install locally
113+
cargo install --path .
114+
```
115+
116+
## Acknowledgments
117+
118+
- Built with Rust 🦀
119+
- Uses [tokio](https://tokio.rs/) for async operations
120+
- Uses [clap](https://clap.rs/) for CLI argument parsing
121+
46122
## License
47123

48-
This project is licensed under [MIT](./LICENSE).
124+
This project is licensed under the [MIT License](./LICENSE).

src/commands/list.rs

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1-
use crate::utils::{get_user_wip_branches, git_username};
1+
use crate::utils::{get_user_wip_branches, git_username, GitCommand};
22
use anyhow::Result;
33

4+
/// Lists all WIP branches for the current Git user.
5+
///
6+
/// # Details
7+
/// * Retrieves the current Git username
8+
/// * Finds all branches matching the pattern "wip/{username}/*"
9+
/// * Displays the branches in a formatted list
10+
/// * Shows a message if no WIP branches are found
11+
///
12+
/// # Returns
13+
/// * `Ok(())` if the operation succeeds
14+
/// * `Err` if username retrieval or branch listing fails
415
pub async fn list_wip_branches() -> Result<()> {
16+
let git = GitCommand::new();
517
let username = git_username().await?;
6-
let wip_branches = get_user_wip_branches(&username).await?;
18+
let wip_branches = get_user_wip_branches(&username, &git).await?;
719

820
if wip_branches.is_empty() {
921
println!("No WIP branches found for the user: {}", username);
@@ -16,3 +28,68 @@ pub async fn list_wip_branches() -> Result<()> {
1628

1729
Ok(())
1830
}
31+
32+
#[cfg(test)]
33+
mod tests {
34+
use super::*;
35+
use crate::utils::MockGit;
36+
37+
/// Tests listing WIP branches when branches exist
38+
#[tokio::test]
39+
async fn test_list_wip_branches() -> Result<()> {
40+
let mut mock_git = MockGit::new();
41+
42+
// Mock the git username command
43+
mock_git
44+
.expect_execute()
45+
.with(mockall::predicate::eq(vec![
46+
"config".to_string(),
47+
"user.name".to_string(),
48+
]))
49+
.returning(|_| Ok("test-user".to_string()));
50+
51+
// Mock the branch listing command
52+
mock_git
53+
.expect_execute()
54+
.with(mockall::predicate::eq(vec![
55+
"branch".to_string(),
56+
"-a".to_string(),
57+
]))
58+
.returning(|_| {
59+
Ok(
60+
"* main\nwip/test-user/branch1\nwip/test-user/branch2\nother-branch"
61+
.to_string(),
62+
)
63+
});
64+
65+
list_wip_branches().await?;
66+
Ok(())
67+
}
68+
69+
/// Tests listing WIP branches when no branches exist
70+
#[tokio::test]
71+
async fn test_list_wip_branches_empty() -> Result<()> {
72+
let mut mock_git = MockGit::new();
73+
74+
// Mock the git username command
75+
mock_git
76+
.expect_execute()
77+
.with(mockall::predicate::eq(vec![
78+
"config".to_string(),
79+
"user.name".to_string(),
80+
]))
81+
.returning(|_| Ok("test-user".to_string()));
82+
83+
// Mock the branch listing command with no WIP branches
84+
mock_git
85+
.expect_execute()
86+
.with(mockall::predicate::eq(vec![
87+
"branch".to_string(),
88+
"-a".to_string(),
89+
]))
90+
.returning(|_| Ok("* main\nother-branch".to_string()));
91+
92+
list_wip_branches().await?;
93+
Ok(())
94+
}
95+
}

src/commands/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
//! Command implementations for git-wippy
2+
//!
3+
//! This module contains the main command implementations that provide
4+
//! the core functionality of git-wippy:
5+
//!
6+
//! * `list` - Lists all WIP branches for the current user
7+
//! * `save` - Saves current changes to a WIP branch
8+
//! * `restore` - Restores changes from a WIP branch back to original branch
9+
110
pub mod list;
211
pub mod restore;
312
pub mod save;

0 commit comments

Comments
 (0)