Replies: 1 comment
-
|
I stumbled upon this, and I did play around a bit in a test. I suspect the in: #[test]
fn hunk_id_consistent_after_staging() {
let mut ctx = TestContext::setup_init();
let mut app = ctx.init_app();
// Add some unstaged changes
fs::write(ctx.dir.child("unstaged.txt"), "unstaged\n").unwrap();
run(ctx.dir.path(), &["git", "add", "-N", "unstaged.txt"]);
ctx.update(&mut app, keys("g"));
// Produce an `id` of unstaged changes at file 0, hunk 0
let diff_unstaged = crate::git::diff_unstaged(&app.state.repo).unwrap();
let unstaged_patch = [diff_unstaged.file_diff_header(0), diff_unstaged.hunk(0, 0)];
println!(
"unstaged: {:?}, hash: {}",
unstaged_patch,
crate::items::hash(unstaged_patch)
);
// Stage those changes
run(ctx.dir.path(), &["git", "add", "."]);
// Produce an `id` of now staged changes at file 0, hunk 0
let diff_staged = crate::git::diff_staged(&app.state.repo).unwrap();
let staged_patch = [diff_unstaged.file_diff_header(0), diff_staged.hunk(0, 0)];
println!(
" staged: {:?}, hash: {}",
staged_patch,
crate::items::hash(staged_patch)
);
// If they're equal, we're all good I think?
assert_eq!(unstaged_patch, staged_patch);
}Perhaps there are cases where it wouldn't be? |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Backstory
In Magit, the staged section follows the collapsed state of the file section (
TargetData::Deltain gitu), defaulting to collapsed. Some examples:In gitu, the staged section follows the state of the corresponding unstaged section. So if you expand a file, then decide to stage the whole file, the staged file is remains expanded.
Approach
At a high level I was expecting to implement this along these lines:
TargetData::Delta/TargetData::Hunk/TargetData::HunkLine, find the corresponding section for the file/delta in the staged areaThere is some existing code for finding the first hunk item etc, which just searches for the first
Itemthat matchesTargetData::Hunketc. but to refer specifically to a section seems to be something there is not currently any code for, as far as I can tell.I noticed that
Itemhas anidand implementedcollapse_item_by_id, to directly address an item. The staging functions (ops/stage.rs) then attempt to produce the same ID by using the same logic as found when creating the sections increate_diff_items. This appeared to work, because I was just staging entire deltas, but it wouldn't work at all when partially staging files. This is because the id for deltas and hunks is based on the file diff header, which includes an index which uniquely identifies the change. Staging an entire delta "works" because the ID doesn't change.Problem
So the issue I've run in to is that I can't know how to address the section that will be created by partially staging a file, since I don't know how to generate an identical diff header for the new diff that will be staged after the
stage_action has been executed and the UI updated.Maybe there is an easy solution to the above that I can't see, but it seems like you would need a way to address any existing staged item for that file in order to compute the new diff anyway.
Possibilities
header.new_fileThis seems janky, because it makes assumptions about the order of sections, how the ID is generated, etc.
When staging something, the most direct question I want to ask is "Is this file collapsed in the staged section?", if it were possible to address that section as a composite of each of its parent IDs, then it could be constructed without knowledge of the diff-to-be:
Blind spots
ItemIDcases could be added for thoseBeta Was this translation helpful? Give feedback.
All reactions