Skip to content

Commit a2720c5

Browse files
committed
implement diff
1 parent 0d28460 commit a2720c5

File tree

3 files changed

+65
-8
lines changed

3 files changed

+65
-8
lines changed

src/git.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ pub(crate) fn shas_match(ref1: &str, ref2: &str) -> bool {
4141
}
4242
}
4343

44+
/// Run a git command and return the output. If the git command fails, this will return an error.
45+
pub(crate) fn run_git_passthrough(args: &[&str]) -> Result<ExitStatus> {
46+
tracing::debug!("Running `git {}`", args.join(" "));
47+
let mut child = Command::new("git").args(args).spawn()?;
48+
Ok(child.wait()?)
49+
}
50+
4451
/// Run a git command and return the output. If the git command fails, this will return an error.
4552
pub(crate) fn run_git(args: &[&str]) -> Result<GitOutput> {
4653
tracing::debug!("Running `git {}`", args.join(" "));

src/main.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,29 @@ enum Commands {
4343
#[arg(long, short)]
4444
branch: Option<String>,
4545
},
46-
/// Create a new branch and make it a descendent of the current branch.
47-
Checkout { branch_name: String },
46+
/// Shows the diff between the given branch and its parent (git-stack tree) branch.
47+
Diff {
48+
/// Specifies the branch whose diff should be shown. If ommitted, the current branch will
49+
/// be used.
50+
branch: Option<String>,
51+
},
52+
/// Create a new branch and make it a descendent of the current branch. If the branch already
53+
/// exists, then it will simply be checked out.
54+
Checkout {
55+
/// The name of the branch to check out.
56+
branch_name: String,
57+
},
4858
/// Mount the current branch on top of the named parent branch. If no parent branch is named,
4959
/// then the trunk branch will be used.
5060
Mount {
5161
/// The name of the parent branch upon which to stack the current branch.
5262
parent_branch: Option<String>,
5363
},
5464
/// Delete a branch from the git-stack tree.
55-
Delete { branch_name: String },
65+
Delete {
66+
/// The name of the branch to delete.
67+
branch_name: String,
68+
},
5669
}
5770

5871
fn main() {
@@ -106,9 +119,27 @@ fn inner_main() -> Result<()> {
106119
Commands::Mount { parent_branch } => state.mount(&repo, &current_branch, parent_branch),
107120
Commands::Status => status(state, &repo, &current_branch),
108121
Commands::Delete { branch_name } => state.delete_branch(&repo, &branch_name),
122+
Commands::Diff { branch } => diff(state, &repo, &branch.unwrap_or(current_branch)),
109123
}
110124
}
111125

126+
fn diff(state: State, repo: &str, branch: &str) -> Result<()> {
127+
let parent_branch = state
128+
.get_parent_branch_of(repo, branch)
129+
.ok_or_else(|| anyhow!("No parent branch found for current branch: {}", branch))?;
130+
tracing::debug!(
131+
parent_branch = &parent_branch.name,
132+
branch = branch,
133+
"Diffing branches"
134+
);
135+
let status =
136+
git::run_git_passthrough(&["diff", &format!("{}..{}", &parent_branch.name, branch)])?;
137+
if !status.success() {
138+
bail!("git format-patch failed");
139+
}
140+
Ok(())
141+
}
142+
112143
fn selection_marker() -> &'static str {
113144
if cfg!(target_os = "windows") {
114145
">"

src/state.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ impl State {
5757
let current_branch_exists_in_tree = self.branch_exists_in_tree(repo, &current_branch);
5858

5959
if git_branch_exists(&branch_name) {
60-
println!("AAA");
6160
if !branch_exists_in_tree {
6261
tracing::warn!(
6362
"Branch {branch_name} exists in the git repo but is not tracked by git-stack. \
@@ -93,6 +92,11 @@ impl State {
9392
// Actually create the git branch.
9493
run_git(&["checkout", "-b", &branch_name, &current_branch])?;
9594

95+
println!(
96+
"Branch {branch_name} created and checked out.",
97+
branch_name = branch_name.yellow()
98+
);
99+
96100
// Save the state after modifying it.
97101
save_state(self)?;
98102

@@ -153,6 +157,11 @@ impl State {
153157
bail!("Branch {branch_name} not found in the git-stack tree.");
154158
};
155159
tree.branches.retain(|branch| branch.name != branch_name);
160+
println!(
161+
"Branch {branch_name} removed from git-stack tree.",
162+
branch_name = branch_name.yellow()
163+
);
164+
156165
save_state(self)?;
157166

158167
Ok(())
@@ -189,7 +198,7 @@ impl State {
189198
);
190199
}
191200

192-
tracing::info!("Mounting {branch_name} on {parent_branch:?}");
201+
tracing::debug!("Mounting {branch_name} on {parent_branch:?}");
193202

194203
// Make sure the parent branch is actually changing.
195204
if let (Some(Branch { name: name_a, .. }), Some(Branch { name: name_b, .. })) = (
@@ -220,15 +229,25 @@ impl State {
220229
} else {
221230
bail!("Parent branch {parent_branch} not found in the git-stack tree.");
222231
}
232+
println!(
233+
"Branch {branch_name} stacked on {parent_branch}.",
234+
branch_name = branch_name.yellow(),
235+
parent_branch = parent_branch.yellow()
236+
);
237+
223238
save_state(self)?;
224239
Ok(())
225240
}
226-
fn get_parent_branch_of(&self, repo: &str, branch_name: &str) -> Option<&Branch> {
241+
pub fn get_parent_branch_of(&self, repo: &str, branch_name: &str) -> Option<&Branch> {
227242
self.trees
228243
.get(repo)
229244
.and_then(|tree| find_parent_of_branch(tree, branch_name))
230245
}
231-
fn get_parent_branch_of_mut(&mut self, repo: &str, branch_name: &str) -> Option<&mut Branch> {
246+
pub fn get_parent_branch_of_mut(
247+
&mut self,
248+
repo: &str,
249+
branch_name: &str,
250+
) -> Option<&mut Branch> {
232251
self.trees
233252
.get_mut(repo)
234253
.and_then(|tree| find_parent_of_branch_mut(tree, branch_name))
@@ -366,7 +385,7 @@ pub fn load_state() -> anyhow::Result<State> {
366385

367386
pub fn save_state(state: &State) -> Result<()> {
368387
let config_path = get_xdg_path()?;
369-
tracing::info!(?state, ?config_path, "Saving state to config file");
388+
tracing::debug!(?state, ?config_path, "Saving state to config file");
370389
Ok(fs::write(config_path, serde_yaml::to_string(&state)?)?)
371390
}
372391

0 commit comments

Comments
 (0)