-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: Add support for in rebase gps listing
The intention with this is to facilitate users running gps list while in the middle of a rebase and being presented with useful information about the current state that they are in. For example it should show which patches have been played and which ones are planned to be played, and their associated statuses. To accomplish this there is a decent amount of work that was needed. We effectively had to implement our own functionality to read the file system state that Git manages during rebases and interpret it so that we can have the necessary information to be able to present to the user about the rebase underway. This included adding the `git::in_rebase` function to determine if the user is currently in the middle of a rebase. Adding the `RebaseTodo` struct to represent rebase todo items. Rebase todo items are line items that Git keeps track of during the rebase to keep track of which patches have been played already and which ones are still to be played. Hence, the name todo. <!-- ps-id: 347c1924-99d4-4d67-b4a3-bcd4f040e5f6 -->
- Loading branch information
1 parent
6f44241
commit 474ff42
Showing
5 changed files
with
319 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
use std::path::Path; | ||
|
||
/// Check if we are in the middle of a rebase | ||
/// | ||
/// Checks to see if we are in the middle of a rebase given a path to the .git directory within the | ||
/// repository and return `true` if we are or `false` if we aren't. | ||
pub fn in_rebase<P: AsRef<Path>>(repo_gitdir: P) -> bool { | ||
repo_gitdir.as_ref().join("rebase-merge").is_dir() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
use super::rebase_todo::RebaseTodo; | ||
use std::result::Result; | ||
|
||
#[derive(Debug, PartialEq, Eq)] | ||
pub enum LineToRebaseTodoError { | ||
MissingSha { line: String }, | ||
} | ||
|
||
impl std::fmt::Display for LineToRebaseTodoError { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
match self { | ||
Self::MissingSha { line } => write!(f, "missing sha in line, {}", line), | ||
} | ||
} | ||
} | ||
|
||
impl std::error::Error for LineToRebaseTodoError { | ||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { | ||
match self { | ||
Self::MissingSha { line: _ } => None, | ||
} | ||
} | ||
} | ||
|
||
fn str_to_next_whitespace(s: &str) -> Option<(&str, &str)> { | ||
s.find(char::is_whitespace) | ||
.map(|idx| (&s[..idx], &s[(idx + 1)..])) | ||
} | ||
|
||
/// Parse line from a rebase todo file into a RebaseTodo struct | ||
/// | ||
/// Attempt to parse the given line into a RebaseTodo struct. | ||
pub fn line_to_rebase_todo(line: &str) -> Result<RebaseTodo, LineToRebaseTodoError> { | ||
let (cmd, rest_after_cmd) = | ||
str_to_next_whitespace(line.trim()).ok_or(LineToRebaseTodoError::MissingSha { | ||
line: line.to_string(), | ||
})?; | ||
|
||
match str_to_next_whitespace(rest_after_cmd) { | ||
Some((sha, rest_after_sha)) => Ok(RebaseTodo { | ||
command: cmd.to_string(), | ||
sha: sha.to_string(), | ||
summary: rest_after_sha.to_string(), | ||
}), | ||
None => Ok(RebaseTodo { | ||
command: cmd.to_string(), | ||
sha: rest_after_cmd.to_string(), | ||
summary: "".to_string(), | ||
}), | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::RebaseTodo; | ||
use super::{line_to_rebase_todo, LineToRebaseTodoError}; | ||
|
||
#[test] | ||
fn parses_valid_rebase_todo_line() { | ||
let rebase_todo = | ||
line_to_rebase_todo("pick a403343e8a173dc8cc2fa27d9465b13fe2c0d627 Free new world") | ||
.unwrap(); | ||
let expected_rebase_todo = RebaseTodo { | ||
command: "pick".to_string(), | ||
sha: "a403343e8a173dc8cc2fa27d9465b13fe2c0d627".to_string(), | ||
summary: "Free new world".to_string(), | ||
}; | ||
|
||
assert_eq!(rebase_todo, expected_rebase_todo); | ||
} | ||
|
||
#[test] | ||
fn parses_valid_rebase_todo_line_with_ending_newline() { | ||
let rebase_todo = | ||
line_to_rebase_todo("pick a403343e8a173dc8cc2fa27d9465b13fe2c0d627 Free new world\n") | ||
.unwrap(); | ||
let expected_rebase_todo = RebaseTodo { | ||
command: "pick".to_string(), | ||
sha: "a403343e8a173dc8cc2fa27d9465b13fe2c0d627".to_string(), | ||
summary: "Free new world".to_string(), | ||
}; | ||
|
||
assert_eq!(rebase_todo, expected_rebase_todo); | ||
} | ||
|
||
#[test] | ||
fn parses_valid_rebase_todo_line_missing_a_summary() { | ||
let rebase_todo = | ||
line_to_rebase_todo("pick a403343e8a173dc8cc2fa27d9465b13fe2c0d627").unwrap(); | ||
let expected_rebase_todo = RebaseTodo { | ||
command: "pick".to_string(), | ||
sha: "a403343e8a173dc8cc2fa27d9465b13fe2c0d627".to_string(), | ||
summary: "".to_string(), | ||
}; | ||
|
||
assert_eq!(rebase_todo, expected_rebase_todo); | ||
} | ||
|
||
#[test] | ||
fn parses_valid_rebase_todo_line_missing_a_summary_with_ending_newline() { | ||
let rebase_todo = | ||
line_to_rebase_todo("pick a403343e8a173dc8cc2fa27d9465b13fe2c0d627\n").unwrap(); | ||
let expected_rebase_todo = RebaseTodo { | ||
command: "pick".to_string(), | ||
sha: "a403343e8a173dc8cc2fa27d9465b13fe2c0d627".to_string(), | ||
summary: "".to_string(), | ||
}; | ||
|
||
assert_eq!(rebase_todo, expected_rebase_todo); | ||
} | ||
|
||
#[test] | ||
fn returns_error_missing_sha_when_invalid_rebase_todo_line_missing_sha() { | ||
let rebase_todo = line_to_rebase_todo("pick"); | ||
let expected_error: Result<RebaseTodo, LineToRebaseTodoError> = | ||
Err(LineToRebaseTodoError::MissingSha { | ||
line: "pick".to_string(), | ||
}); | ||
|
||
assert_eq!(rebase_todo, expected_error); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#[derive(Debug, PartialEq, Eq)] | ||
pub struct RebaseTodo { | ||
pub command: String, /* pick, edit, etc. */ | ||
pub sha: String, | ||
pub summary: String, | ||
} |
Oops, something went wrong.