Is your feature request related to a problem? Please describe.
To interact with other VCS it is sometimes easiest to apply a diff generated with git or jj using the good old POSIX patch utility. patch generally ignores metadata it doesn't understand. Some implementations are unaware of the git-specific 'rename from/rename to' and 'copy from/copy to' (or similarity index) part of diffs. The result is they don't actually rename/copy the old file. This can result in obscure build failures that may take some time to debug.
The --no-renames flag and the diff.renames config of git avoid this problem: a rename is split into two diffs against /dev/null, one that removes (or at least empties) the old file and one that creates the new one. Similarly, a copy is a diff from /dev/null that creates the copy. That's something all patch utilities I've ever used handle correctly. The obvious downside of is that it significantly increases the size of the diff.
Describe the solution you'd like
- Support
--no-renames in commands that output git-style unified diffs via --git or -p.
- A config option akin to git's
diff.renames that makes such output the default.
I'm only concerned with the display aspect of this config option here, not with possible implications on git's rebase or merge behavior.
Describe alternatives you've considered
None.
Additional context
I expect this to be rather easy but I currently lack the time to tackle this and push it over the line. If --no-renames is given, skip the writeln!() here:
|
if let Some(op) = path.copy_operation() { |
|
let operation = match op { |
|
CopyOperation::Copy => "copy", |
|
CopyOperation::Rename => "rename", |
|
}; |
|
// TODO: include similarity index? |
|
writeln!(formatter, "{operation} from {left_path_string}")?; |
|
writeln!(formatter, "{operation} to {right_path_string}")?; |
|
} |
and don't do the
// no content hunks so as to output the diffs against
/dev/null as appropriate for
copy and
rename mode:
|
if left_part.content.contents == right_part.content.contents { |
|
continue; // no content hunks |
|
} |
|
|
|
let left_path = match left_part.mode { |
|
Some(_) => format!("a/{left_path_string}"), |
|
None => "/dev/null".to_owned(), |
|
}; |
|
let right_path = match right_part.mode { |
|
Some(_) => format!("b/{right_path_string}"), |
|
None => "/dev/null".to_owned(), |
|
}; |
Some thought needs to be given on permissions to match git's behavior. The bulk of the work will be plumbing to add the option where needed and tests.
Is your feature request related to a problem? Please describe.
To interact with other VCS it is sometimes easiest to apply a diff generated with git or jj using the good old POSIX
patchutility.patchgenerally ignores metadata it doesn't understand. Some implementations are unaware of the git-specific 'rename from/rename to' and 'copy from/copy to' (or similarity index) part of diffs. The result is they don't actually rename/copy the old file. This can result in obscure build failures that may take some time to debug.The
--no-renamesflag and thediff.renamesconfig of git avoid this problem: a rename is split into two diffs against/dev/null, one that removes (or at least empties) the old file and one that creates the new one. Similarly, a copy is a diff from/dev/nullthat creates the copy. That's something all patch utilities I've ever used handle correctly. The obvious downside of is that it significantly increases the size of the diff.Describe the solution you'd like
--no-renamesin commands that output git-style unified diffs via--gitor-p.diff.renamesthat makes such output the default.I'm only concerned with the display aspect of this config option here, not with possible implications on git's rebase or merge behavior.
Describe alternatives you've considered
None.
Additional context
I expect this to be rather easy but I currently lack the time to tackle this and push it over the line. If
--no-renamesis given, skip thewriteln!()here:jj/cli/src/diff_util.rs
Lines 1743 to 1751 in e155cb3
and don't do the
// no content hunksso as to output the diffs against/dev/nullas appropriate forcopyandrenamemode:jj/cli/src/diff_util.rs
Lines 1766 to 1777 in e155cb3
Some thought needs to be given on permissions to match git's behavior. The bulk of the work will be plumbing to add the option where needed and tests.