Skip to content

Commit 1ecb346

Browse files
committed
minor refactor before the actual change
1 parent 0323d8e commit 1ecb346

File tree

4 files changed

+36
-17
lines changed

4 files changed

+36
-17
lines changed

crates/gitbutler-branch-actions/src/undo_commit.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,26 @@ use gitbutler_repo::{
77
rebase::cherry_rebase_group,
88
};
99
use gitbutler_stack::{OwnershipClaim, Stack, StackId};
10+
use tracing::instrument;
1011

1112
use crate::VirtualBranchesExt as _;
1213

1314
/// Removes a commit from a branch by rebasing all commits _except_ for it
1415
/// onto it's parent.
1516
///
16-
/// if successful, it will update the branch head to the new head commit.
17+
/// If successful, it will update the branch head to the new head commit.
1718
///
1819
/// It intentionally does **not** update the branch tree. It is a feature
1920
/// of the operation that the branch tree will not be updated as it allows
2021
/// the user to then re-commit the changes if they wish.
2122
///
2223
/// This may create conflicted commits above the commit that is getting
2324
/// undone.
25+
#[instrument(level = tracing::Level::DEBUG, skip(ctx))]
2426
pub(crate) fn undo_commit(
2527
ctx: &CommandContext,
2628
stack_id: StackId,
27-
commit_oid: git2::Oid,
29+
commit_to_remove: git2::Oid,
2830
) -> Result<Stack> {
2931
let vb_state = ctx.project().virtual_branches();
3032

@@ -33,15 +35,15 @@ pub(crate) fn undo_commit(
3335
let UndoResult {
3436
new_head: new_head_commit,
3537
ownership_update,
36-
} = inner_undo_commit(ctx.repo(), stack.head(), commit_oid)?;
38+
} = rebase_all_but_last(ctx.repo(), stack.head(), commit_to_remove)?;
3739

3840
for ownership in ownership_update {
3941
stack.ownership.put(ownership);
4042
}
4143

4244
stack.set_stack_head(ctx, new_head_commit, None)?;
4345

44-
let removed_commit = ctx.repo().find_commit(commit_oid)?;
46+
let removed_commit = ctx.repo().find_commit(commit_to_remove)?;
4547
stack.replace_head(ctx, &removed_commit, &removed_commit.parent(0)?)?;
4648

4749
crate::integration::update_workspace_commit(&vb_state, ctx)
@@ -55,7 +57,8 @@ struct UndoResult {
5557
ownership_update: Vec<OwnershipClaim>,
5658
}
5759

58-
fn inner_undo_commit(
60+
#[instrument(level = tracing::Level::DEBUG, skip(repository))]
61+
fn rebase_all_but_last(
5962
repository: &git2::Repository,
6063
branch_head_commit: git2::Oid,
6164
commit_to_remove: git2::Oid,
@@ -82,14 +85,13 @@ fn inner_undo_commit(
8285
.hunks
8386
.iter()
8487
.map(Into::into)
85-
.filter(|hunk: &Hunk| hunk.start != 0 && hunk.end != 0)
88+
.filter(|hunk: &Hunk| !hunk.is_null())
8689
.collect::<Vec<_>>();
8790
if hunks.is_empty() {
8891
return None;
8992
}
90-
Some((file_path, hunks))
93+
Some(OwnershipClaim { file_path, hunks })
9194
})
92-
.map(|(file_path, hunks)| OwnershipClaim { file_path, hunks })
9395
.collect::<Vec<_>>();
9496

9597
// if commit is the head, just set head to the parent
@@ -131,7 +133,7 @@ mod test {
131133
assert_commit_tree_matches, TestingRepository,
132134
};
133135

134-
use crate::undo_commit::{inner_undo_commit, UndoResult};
136+
use crate::undo_commit::{rebase_all_but_last, UndoResult};
135137

136138
#[test]
137139
fn undoing_conflicted_commit_errors() {
@@ -146,7 +148,7 @@ mod test {
146148

147149
// Branch looks like "A -> ConflictedCommit"
148150

149-
let result = inner_undo_commit(
151+
let result = rebase_all_but_last(
150152
&test_repository.repository,
151153
conflicted_commit.id(),
152154
conflicted_commit.id(),
@@ -169,7 +171,7 @@ mod test {
169171
let UndoResult {
170172
new_head,
171173
ownership_update,
172-
} = inner_undo_commit(&test_repository.repository, c.id(), c.id()).unwrap();
174+
} = rebase_all_but_last(&test_repository.repository, c.id(), c.id()).unwrap();
173175

174176
assert_eq!(new_head, b.id(), "The new head should be C's parent");
175177
assert_eq!(
@@ -208,7 +210,7 @@ mod test {
208210
let UndoResult {
209211
new_head,
210212
ownership_update,
211-
} = inner_undo_commit(&test_repository.repository, c.id(), b.id()).unwrap();
213+
} = rebase_all_but_last(&test_repository.repository, c.id(), b.id()).unwrap();
212214

213215
let new_head_commit: git2::Commit =
214216
test_repository.repository.find_commit(new_head).unwrap();

crates/gitbutler-diff/src/hunk.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ pub type HunkHash = md5::Digest;
99

1010
#[derive(Debug, Eq, Clone)]
1111
pub struct Hunk {
12+
/// A hash over the actual lines of the hunk, including the newlines between them
13+
/// (i.e. the first character of the first line to the last character of the last line in the input buffer)
1214
pub hash: Option<HunkHash>,
15+
/// The index of the first line this hunk is representing.
1316
pub start: u32,
17+
/// The index of *one past* the last line this hunk is representing.
1418
pub end: u32,
1519
}
1620

@@ -91,6 +95,7 @@ impl Display for Hunk {
9195
}
9296
}
9397

98+
/// Instantiation
9499
impl Hunk {
95100
pub fn new(start: u32, end: u32, hash: Option<HunkHash>) -> Result<Self> {
96101
if start > end {
@@ -104,18 +109,28 @@ impl Hunk {
104109
self.hash = Some(hash);
105110
self
106111
}
112+
}
107113

108-
pub(crate) fn contains(&self, line: u32) -> bool {
114+
/// Access
115+
impl Hunk {
116+
fn contains_line(&self, line: u32) -> bool {
109117
self.start <= line && self.end >= line
110118
}
111119

112120
pub fn intersects(&self, another: &diff::GitHunk) -> bool {
113-
self.contains(another.new_start)
114-
|| self.contains(another.new_start + another.new_lines)
121+
self.contains_line(another.new_start)
122+
|| self.contains_line(another.new_start + another.new_lines)
115123
|| another.contains(self.start)
116124
|| another.contains(self.end)
117125
}
118126

127+
pub fn is_null(&self) -> bool {
128+
self.start == self.end && self.start == 0
129+
}
130+
}
131+
132+
/// Hashing
133+
impl Hunk {
119134
/// Produce a hash from `diff` as hex-string, which is **assumed to have a one-line diff header**!
120135
/// `diff` can also be entirely empty, or not contain a diff header which is when it will just be hashed
121136
/// with [`Self::hash()`].

crates/gitbutler-oxidize/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ publish = false
77

88
[dependencies]
99
anyhow.workspace = true
10-
gix.workspace = true
11-
git2.workspace = true
10+
git2.workspace = true
11+
gix = { workspace = true, features = ["merge"] }

crates/gitbutler-repo/src/rebase.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use gitbutler_commit::{
1414
};
1515
use gitbutler_oxidize::{git2_to_gix_object_id, gix_to_git2_oid, GixRepositoryExt as _};
1616
use serde::{Deserialize, Serialize};
17+
use tracing::instrument;
1718

1819
/// cherry-pick based rebase, which handles empty commits
1920
/// this function takes a commit range and generates a Vector of commit oids
@@ -46,6 +47,7 @@ pub fn cherry_rebase(
4647
/// rebase empty commits (two commits with identical trees)
4748
///
4849
/// the commit id's to rebase should be ordered such that the child most commit is first
50+
#[instrument(level = tracing::Level::DEBUG, skip(repository, ids_to_rebase))]
4951
pub fn cherry_rebase_group(
5052
repository: &git2::Repository,
5153
target_commit_oid: git2::Oid,

0 commit comments

Comments
 (0)