-
Notifications
You must be signed in to change notification settings - Fork 67
Remove Change: footer on split push #1586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Remove Change: footer on split push #1586
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR removes "Change:" footers from commit messages during split push operations to accommodate projects that don't want extra metadata. After pushing, the Change: footer is no longer needed in the remote repository.
Key Changes:
- Added regex-based text transformation functionality to remove "Change:" footers from commit messages
- Modified the
unapply_filterfunction in history.rs to strip "Change:" footers when processing commits with change IDs - Updated test expectations to reflect that "Change:" footers are removed after push
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| josh-core/src/filter/text.rs | New module providing template-based text transformation with regex support |
| josh-core/src/history.rs | Modified to apply text transformation to remove "Change:" footers during unapply operations |
| tests/cli/push_stacked_split.t | Updated test expectations to verify "Change:" footers are removed and commit hashes reflect the change |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Build a HashMap with all named captures and globals | ||
| // We need to store the string values to keep them alive for the HashMap references | ||
| let mut string_storage: HashMap<String, String> = HashMap::new(); | ||
|
|
||
| // Collect all named capture values | ||
| for name in re.capture_names().flatten() { | ||
| if let Some(m) = caps.name(name) { | ||
| string_storage.insert(name.to_string(), m.as_str().to_string()); | ||
| } | ||
| } | ||
|
|
||
| // Build the HashMap for strfmt with references to the stored strings | ||
| let mut vars: HashMap<String, &dyn strfmt::DisplayStr> = HashMap::new(); | ||
|
|
||
| // Add all globals first (lower priority) | ||
| for (key, value) in globals { | ||
| vars.insert(key.clone(), value as &dyn strfmt::DisplayStr); | ||
| } | ||
|
|
||
| // Add all named captures (higher priority - will overwrite globals if there's a conflict) | ||
| for (key, value) in &string_storage { | ||
| vars.insert(key.clone(), value as &dyn strfmt::DisplayStr); | ||
| } | ||
|
|
||
| // Format the template, propagating errors | ||
| match strfmt::strfmt(template, &vars) { | ||
| Ok(s) => s, | ||
| Err(e) => { | ||
| let mut error = first_error.borrow_mut(); | ||
| if error.is_none() { | ||
| *error = Some(e.into()); | ||
| } | ||
| caps[0].to_string() | ||
| } | ||
| } | ||
| }) | ||
| .into_owned(); | ||
|
|
||
| match first_error.into_inner() { | ||
| Some(e) => Err(e), | ||
| None => Ok(result), | ||
| } |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function contains complex template formatting logic (lines 18-50) that is not used in the current implementation. The only caller passes an empty string as the template, making the strfmt logic, string_storage, vars HashMap, and error handling for template formatting dead code. Consider simplifying to a basic regex replace function or documenting the intended future use of template parameters.
| // Build a HashMap with all named captures and globals | |
| // We need to store the string values to keep them alive for the HashMap references | |
| let mut string_storage: HashMap<String, String> = HashMap::new(); | |
| // Collect all named capture values | |
| for name in re.capture_names().flatten() { | |
| if let Some(m) = caps.name(name) { | |
| string_storage.insert(name.to_string(), m.as_str().to_string()); | |
| } | |
| } | |
| // Build the HashMap for strfmt with references to the stored strings | |
| let mut vars: HashMap<String, &dyn strfmt::DisplayStr> = HashMap::new(); | |
| // Add all globals first (lower priority) | |
| for (key, value) in globals { | |
| vars.insert(key.clone(), value as &dyn strfmt::DisplayStr); | |
| } | |
| // Add all named captures (higher priority - will overwrite globals if there's a conflict) | |
| for (key, value) in &string_storage { | |
| vars.insert(key.clone(), value as &dyn strfmt::DisplayStr); | |
| } | |
| // Format the template, propagating errors | |
| match strfmt::strfmt(template, &vars) { | |
| Ok(s) => s, | |
| Err(e) => { | |
| let mut error = first_error.borrow_mut(); | |
| if error.is_none() { | |
| *error = Some(e.into()); | |
| } | |
| caps[0].to_string() | |
| } | |
| } | |
| }) | |
| .into_owned(); | |
| match first_error.into_inner() { | |
| Some(e) => Err(e), | |
| None => Ok(result), | |
| } | |
| // Since template formatting is not used, just return the matched string | |
| caps[0].to_string() | |
| }) | |
| .into_owned(); | |
| Ok(result) |
| let new_message = filter::text::transform_with_template( | ||
| ®ex::Regex::new(&"(?m)^Change: [^ ]+")?, | ||
| &"", | ||
| module_commit.message_raw().unwrap(), | ||
| &std::collections::HashMap::new(), | ||
| )?; |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex pattern &\"(?m)^Change: [^ ]+\" has an unnecessary reference operator before the string literal. It should be \"(?m)^Change: [^ ]+\" (without the leading &). The Regex::new() function expects &str, not &&str.
| let new_message = filter::text::transform_with_template( | ||
| ®ex::Regex::new(&"(?m)^Change: [^ ]+")?, | ||
| &"", | ||
| module_commit.message_raw().unwrap(), | ||
| &std::collections::HashMap::new(), | ||
| )?; |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex pattern (?m)^Change: [^ ]+ will match and remove the line but leave the newline character, resulting in blank lines in commit messages. Consider using (?m)^Change: [^ ]+\\n? to also remove the trailing newline, or (?m)^Change: [^ ]+$\\n? to be more precise about matching end-of-line.
ec32124 to
d9a5213
Compare
Some projects don't like extra metadata in the commit messages, and after the push it is not needed anyway.
d9a5213 to
92e6f88
Compare
Some projects don't like extra metadata in the commit messages, and after the push it is not needed anyway.