summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2021-08-22 11:25:39 -0700
committerGitHub <noreply@github.com>2021-08-22 11:25:39 -0700
commit5e02d340a8b3f3184f84a34434d7ad170988331f (patch)
tree8bc03172e17e1104ae578f0c0d7a73968b87b770
parent67745fee86b3cc6a00849651fae0f4ad896e4f63 (diff)
662 submodule diffs (#699)
-rwxr-xr-xetc/examples/662-submodules45
-rw-r--r--src/config.rs1
-rw-r--r--src/delta.rs12
-rw-r--r--src/tests/test_example_diffs.rs66
4 files changed, 119 insertions, 5 deletions
diff --git a/etc/examples/662-submodules b/etc/examples/662-submodules
new file mode 100755
index 00000000..1f4a5189
--- /dev/null
+++ b/etc/examples/662-submodules
@@ -0,0 +1,45 @@
+#!/bin/bash
+REPO_ROOT=/tmp/submodule-diff-example
+REPO_DATE_FMT=%H:%M:%S.%N
+mkdir ${REPO_ROOT} && git -C ${REPO_ROOT} init && cd ${REPO_ROOT}
+date +${REPO_DATE_FMT} >> baserepo && git add baserepo && git commit -m "Base repo commit 1"
+
+for sub in A B C; do
+ git init submodule${sub}
+ for iter in $(seq 1 4); do
+ date +${REPO_DATE_FMT} >> submodule${sub}/subcontent
+ git -C submodule${sub} add subcontent && git -C submodule${sub} commit -m "Submodule ${sub} initial commit $iter"
+ done
+ # Add initial submodule, message of "Submodule submoduleX 0000000...xxxxxxx (new submodule)", no individual commits
+ git submodule add ../bogus-url-${sub} submodule${sub} && \
+ git commit -m "Add submodule${sub}" # the diff handling for this is correct in delta
+
+ # Create additional submodule commits
+ for iter in $(seq 1 2); do
+ date +${REPO_DATE_FMT} >> submodule${sub}/subcontent
+ git -C submodule${sub} add subcontent && git -C submodule${sub} commit -m "Submodule ${sub} extra change ${iter}"
+ done
+ git add submodule${sub} && git commit -m "Update submodule${sub}"
+done
+
+git -C submoduleA reset --hard HEAD~4
+git -C submoduleC reset --hard HEAD~2
+
+for sub in B C; do
+ for iter in $(seq 1 3); do
+ date +${REPO_DATE_FMT} >> submodule${sub}/subcontent
+ git -C submodule${sub} add subcontent && git -C submodule${sub} commit -m "Submodule ${sub} stage change ${iter}"
+ done
+done
+
+# Add all submodule updates in single commit to test multiple submodule updates in single commit
+git add submodule[A-C] && git commit -m "Update all submodules"
+
+# submoduleA end state is only removed commits
+# submoduleB end state is only added commits
+# submoduleC is a mixture of removed and added commits (e.g. different branch)
+
+# Manual, inspect superproject history via:
+# "git -c diff.submodule=short log -p | delta --no-gitconfig"
+# "git -c diff.submodule=log log -p | delta --no-gitconfig"
+# "git -c diff.submodule=diff log -p | delta --no-gitconfig"
diff --git a/src/config.rs b/src/config.rs
index b0a8cb3c..acf7d0c9 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -100,6 +100,7 @@ impl Config {
State::CommitMeta => &self.commit_style,
State::FileMeta => &self.file_style,
State::HunkHeader => &self.hunk_header_style,
+ State::Submodule => &self.file_style,
_ => delta_unreachable("Unreachable code reached in get_style."),
}
}
diff --git a/src/delta.rs b/src/delta.rs
index e1770b7e..c42ba9f1 100644
--- a/src/delta.rs
+++ b/src/delta.rs
@@ -24,6 +24,7 @@ pub enum State {
HunkZero, // In hunk; unchanged line
HunkMinus(Option<String>), // In hunk; removed line (raw_line)
HunkPlus(Option<String>), // In hunk; added line (raw_line)
+ Submodule,
Unknown,
}
@@ -140,10 +141,11 @@ impl<'a> StateMachine<'a> {
} else if line.starts_with("@@") {
self.handle_hunk_header_line()?
} else if self.source == Source::DiffUnified && line.starts_with("Only in ")
- || line.starts_with("Submodule ")
|| line.starts_with("Binary files ")
{
- self.handle_additional_file_meta_cases()?
+ self.handle_additional_cases(State::FileMeta)?
+ } else if line.starts_with("Submodule ") {
+ self.handle_additional_cases(State::Submodule)?
} else if self.state.is_in_hunk() {
// A true hunk line should start with one of: '+', '-', ' '. However, handle_hunk_line
// handles all lines until the state transitions away from the hunk states.
@@ -381,10 +383,10 @@ impl<'a> StateMachine<'a> {
_write_generic_file_meta_header_line(&line, &line, &mut self.painter, self.config)
}
- fn handle_additional_file_meta_cases(&mut self) -> std::io::Result<bool> {
+ fn handle_additional_cases(&mut self, to_state: State) -> std::io::Result<bool> {
let mut handled_line = false;
- // Additional FileMeta cases:
+ // Additional cases:
//
// 1. When comparing directories with diff -u, if filenames match between the
// directories, the files themselves will be compared. However, if an equivalent
@@ -398,7 +400,7 @@ impl<'a> StateMachine<'a> {
// proposal for more robust parsing logic.
self.painter.paint_buffered_minus_and_plus_lines();
- self.state = State::FileMeta;
+ self.state = to_state;
if self.should_handle() {
self.painter.emit()?;
_write_generic_file_meta_header_line(
diff --git a/src/tests/test_example_diffs.rs b/src/tests/test_example_diffs.rs
index 3f28d200..3b249eff 100644
--- a/src/tests/test_example_diffs.rs
+++ b/src/tests/test_example_diffs.rs
@@ -201,6 +201,16 @@ mod tests {
}
#[test]
+ fn test_submodule_diff_log() {
+ // See etc/examples/662-submodules
+ // diff.submodule = log
+ let config = integration_test_utils::make_config_from_args(&["--width", "49"]);
+ let output = integration_test_utils::run_delta(SUBMODULE_DIFF_LOG, &config);
+ let output = strip_ansi_codes(&output);
+ assert_eq!(output, SUBMODULE_DIFF_LOG_EXPECTED_OUTPUT);
+ }
+
+ #[test]
fn test_submodule_contains_untracked_content() {
let config = integration_test_utils::make_config_from_args(&[]);
let output =
@@ -1902,6 +1912,62 @@ This is a regular file that contains:
+Some text with a plus
";
+ // See etc/examples/662-submodules
+ // diff.submodule = log
+ const SUBMODULE_DIFF_LOG: &str = "\
+commit ccb444baa861fdcb14d411b471a74614ed28776d
+Author: Dan Davison <dandavison7@gmail.com>
+Date: Sat Aug 21 18:56:34 2021 -0700
+
+ Update all submodules
+
+Submodule submoduleA f4f55af..310b551 (rewind):
+ < Submodule A extra change 2
+ < Submodule A extra change 1
+ < Submodule A initial commit 4
+ < Submodule A initial commit 3
+Submodule submoduleB 0ffa700..0c8b00d:
+ > Submodule B stage change 3
+ > Submodule B stage change 2
+ > Submodule B stage change 1
+Submodule submoduleC 9f3b744...e04f848:
+ > Submodule C stage change 3
+ > Submodule C stage change 2
+ < Submodule C extra change 2
+ > Submodule C stage change 1
+ < Submodule C extra change 1
+";
+
+ const SUBMODULE_DIFF_LOG_EXPECTED_OUTPUT: &str = "\
+commit ccb444baa861fdcb14d411b471a74614ed28776d
+Author: Dan Davison <dandavison7@gmail.com>
+Date: Sat Aug 21 18:56:34 2021 -0700
+
+ Update all submodules
+
+
+Submodule submoduleA f4f55af..310b551 (rewind):
+─────────────────────────────────────────────────
+ < Submodule A extra change 2
+ < Submodule A extra change 1
+ < Submodule A initial commit 4
+ < Submodule A initial commit 3
+
+Submodule submoduleB 0ffa700..0c8b00d:
+─────────────────────────────────────────────────
+ > Submodule B stage change 3
+ > Submodule B stage change 2
+ > Submodule B stage change 1
+
+Submodule submoduleC 9f3b744...e04f848:
+─────────────────────────────────────────────────
+ > Submodule C stage change 3
+ > Submodule C stage change 2
+ < Submodule C extra change 2
+ > Submodule C stage change 1
+ < Submodule C extra change 1
+";
+
const SUBMODULE_CONTAINS_UNTRACKED_CONTENT_INPUT: &str = "\
--- a
+++ b