Skip to content

Commit 96a2266

Browse files
authored
Merge pull request #1106 from git-ai-project/revert-1081-fix/total-additions-reset-inherited-prompts
Revert "fix: preserve total_additions for inherited prompts and prevent amend inflation"
2 parents bef02e4 + 0c849cc commit 96a2266

2 files changed

Lines changed: 10 additions & 161 deletions

File tree

src/authorship/rebase_authorship.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4556,16 +4556,15 @@ fn transform_attributions_to_final_state(
45564556
}
45574557
}
45584558

4559-
// Calculate and update prompt metrics based on transformed attributions.
4560-
// Empty session maps preserve existing total_additions/total_deletions values.
4559+
// Calculate and update prompt metrics based on transformed attributions
45614560
crate::authorship::virtual_attribution::VirtualAttributions::calculate_and_update_prompt_metrics(
45624561
&mut prompts,
45634562
&attributions,
4564-
&HashMap::new(),
4565-
&HashMap::new(),
4563+
&HashMap::new(), // Empty - will result in total_additions = 0
4564+
&HashMap::new(), // Empty - will result in total_deletions = 0
45664565
);
45674566

4568-
// Overwrite with the saved pre-rebase totals (rebase should preserve original totals).
4567+
// Restore the saved total_additions and total_deletions
45694568
for (prompt_id, commits) in prompts.iter_mut() {
45704569
if let Some(&(additions, deletions)) = saved_totals.get(prompt_id) {
45714570
for prompt_record in commits.values_mut() {

src/authorship/virtual_attribution.rs

Lines changed: 6 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,12 +1914,8 @@ impl VirtualAttributions {
19141914
// Update all prompt records with calculated metrics
19151915
for (session_id, commits) in prompts.iter_mut() {
19161916
for prompt_record in commits.values_mut() {
1917-
if let Some(&additions) = session_additions.get(session_id) {
1918-
prompt_record.total_additions = additions;
1919-
}
1920-
if let Some(&deletions) = session_deletions.get(session_id) {
1921-
prompt_record.total_deletions = deletions;
1922-
}
1917+
prompt_record.total_additions = *session_additions.get(session_id).unwrap_or(&0);
1918+
prompt_record.total_deletions = *session_deletions.get(session_id).unwrap_or(&0);
19231919
prompt_record.accepted_lines =
19241920
*session_accepted_lines.get(session_id).unwrap_or(&0);
19251921
prompt_record.overriden_lines =
@@ -2076,17 +2072,15 @@ pub fn merge_attributions_favoring_first(
20762072
}
20772073
}
20782074

2079-
// Calculate and update prompt metrics (will set accepted_lines and overridden_lines).
2080-
// Empty session maps preserve existing total_additions/total_deletions values.
2075+
// Calculate and update prompt metrics (will set accepted_lines and overridden_lines)
20812076
VirtualAttributions::calculate_and_update_prompt_metrics(
20822077
&mut merged.prompts,
20832078
&merged.attributions,
2084-
&HashMap::new(),
2085-
&HashMap::new(),
2079+
&HashMap::new(), // Empty - will result in total_additions = 0
2080+
&HashMap::new(), // Empty - will result in total_deletions = 0
20862081
);
20872082

2088-
// Overwrite total_additions/total_deletions with the summed values from both sources,
2089-
// since merge should reflect the combined totals from primary + secondary.
2083+
// Restore the saved total_additions and total_deletions
20902084
for (prompt_id, commits) in merged.prompts.iter_mut() {
20912085
if let Some(&(additions, deletions)) = saved_totals.get(prompt_id) {
20922086
for prompt_record in commits.values_mut() {
@@ -2612,148 +2606,4 @@ mod tests {
26122606

26132607
assert!(!virtual_attributions.files().is_empty());
26142608
}
2615-
2616-
/// Regression test for https://github.com/git-ai-project/git-ai/issues/1080
2617-
///
2618-
/// When a prompt is inherited from INITIAL (e.g., from a previous agent session)
2619-
/// and has no new checkpoints in the current working log, its `total_additions`
2620-
/// must be preserved. Previously, `calculate_and_update_prompt_metrics` would
2621-
/// unconditionally overwrite with `unwrap_or(0)`, zeroing out inherited values.
2622-
#[test]
2623-
fn test_inherited_prompt_preserves_total_additions_when_no_checkpoint_data() {
2624-
use crate::authorship::authorship_log::PromptRecord;
2625-
use crate::authorship::working_log::AgentId;
2626-
2627-
// Set up two prompts: one with checkpoint data, one inherited (no checkpoint data)
2628-
let mut prompts = BTreeMap::new();
2629-
2630-
// Prompt A: inherited from INITIAL, already has total_additions = 42
2631-
let prompt_a_record = PromptRecord {
2632-
agent_id: AgentId {
2633-
tool: "cursor".to_string(),
2634-
id: "session_a".to_string(),
2635-
model: "gpt-4".to_string(),
2636-
},
2637-
human_author: Some("dev@example.com".to_string()),
2638-
messages: vec![],
2639-
total_additions: 42,
2640-
total_deletions: 10,
2641-
accepted_lines: 0,
2642-
overriden_lines: 0,
2643-
messages_url: None,
2644-
custom_attributes: None,
2645-
};
2646-
let mut prompt_a_commits = BTreeMap::new();
2647-
prompt_a_commits.insert(String::new(), prompt_a_record);
2648-
prompts.insert("session_a".to_string(), prompt_a_commits);
2649-
2650-
// Prompt B: has checkpoint data in this session
2651-
let prompt_b_record = PromptRecord {
2652-
agent_id: AgentId {
2653-
tool: "codex".to_string(),
2654-
id: "session_b".to_string(),
2655-
model: "gpt-4".to_string(),
2656-
},
2657-
human_author: Some("dev@example.com".to_string()),
2658-
messages: vec![],
2659-
total_additions: 0,
2660-
total_deletions: 0,
2661-
accepted_lines: 0,
2662-
overriden_lines: 0,
2663-
messages_url: None,
2664-
custom_attributes: None,
2665-
};
2666-
let mut prompt_b_commits = BTreeMap::new();
2667-
prompt_b_commits.insert(String::new(), prompt_b_record);
2668-
prompts.insert("session_b".to_string(), prompt_b_commits);
2669-
2670-
// Only session_b has checkpoint data; session_a has none (inherited from INITIAL)
2671-
let mut session_additions = HashMap::new();
2672-
session_additions.insert("session_b".to_string(), 25u32);
2673-
let mut session_deletions = HashMap::new();
2674-
session_deletions.insert("session_b".to_string(), 5u32);
2675-
2676-
// Empty attributions (we're only testing the total_additions/total_deletions logic)
2677-
let attributions: HashMap<String, (Vec<Attribution>, Vec<LineAttribution>)> =
2678-
HashMap::new();
2679-
2680-
VirtualAttributions::calculate_and_update_prompt_metrics(
2681-
&mut prompts,
2682-
&attributions,
2683-
&session_additions,
2684-
&session_deletions,
2685-
);
2686-
2687-
// Session A (inherited, no checkpoint data): total_additions must be PRESERVED
2688-
let prompt_a = prompts["session_a"].values().next().unwrap();
2689-
assert_eq!(
2690-
prompt_a.total_additions, 42,
2691-
"inherited prompt total_additions should be preserved, not reset to 0"
2692-
);
2693-
assert_eq!(
2694-
prompt_a.total_deletions, 10,
2695-
"inherited prompt total_deletions should be preserved, not reset to 0"
2696-
);
2697-
2698-
// Session B (has checkpoint data): total_additions must be UPDATED from checkpoints
2699-
let prompt_b = prompts["session_b"].values().next().unwrap();
2700-
assert_eq!(
2701-
prompt_b.total_additions, 25,
2702-
"prompt with checkpoint data should have total_additions updated"
2703-
);
2704-
assert_eq!(
2705-
prompt_b.total_deletions, 5,
2706-
"prompt with checkpoint data should have total_deletions updated"
2707-
);
2708-
}
2709-
2710-
/// Test that passing empty session maps preserves all existing values.
2711-
/// This is the pattern used by merge_attributions_favoring_first and rebase_authorship.
2712-
#[test]
2713-
fn test_empty_session_maps_preserve_existing_totals() {
2714-
use crate::authorship::authorship_log::PromptRecord;
2715-
use crate::authorship::working_log::AgentId;
2716-
2717-
let mut prompts = BTreeMap::new();
2718-
2719-
let prompt_record = PromptRecord {
2720-
agent_id: AgentId {
2721-
tool: "cursor".to_string(),
2722-
id: "session_x".to_string(),
2723-
model: "gpt-4".to_string(),
2724-
},
2725-
human_author: None,
2726-
messages: vec![],
2727-
total_additions: 100,
2728-
total_deletions: 30,
2729-
accepted_lines: 0,
2730-
overriden_lines: 0,
2731-
messages_url: None,
2732-
custom_attributes: None,
2733-
};
2734-
let mut commits = BTreeMap::new();
2735-
commits.insert("abc123".to_string(), prompt_record);
2736-
prompts.insert("session_x".to_string(), commits);
2737-
2738-
let attributions: HashMap<String, (Vec<Attribution>, Vec<LineAttribution>)> =
2739-
HashMap::new();
2740-
2741-
// Empty session maps (as used in merge/rebase paths)
2742-
VirtualAttributions::calculate_and_update_prompt_metrics(
2743-
&mut prompts,
2744-
&attributions,
2745-
&HashMap::new(),
2746-
&HashMap::new(),
2747-
);
2748-
2749-
let prompt = prompts["session_x"].values().next().unwrap();
2750-
assert_eq!(
2751-
prompt.total_additions, 100,
2752-
"empty session_additions map should not zero out existing total_additions"
2753-
);
2754-
assert_eq!(
2755-
prompt.total_deletions, 30,
2756-
"empty session_deletions map should not zero out existing total_deletions"
2757-
);
2758-
}
27592609
}

0 commit comments

Comments
 (0)