Skip to content

Commit 5e02d34

Browse files
authored
662 submodule diffs (#699)
1 parent 67745fe commit 5e02d34

File tree

4 files changed

+119
-5
lines changed

4 files changed

+119
-5
lines changed

etc/examples/662-submodules

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
REPO_ROOT=/tmp/submodule-diff-example
3+
REPO_DATE_FMT=%H:%M:%S.%N
4+
mkdir ${REPO_ROOT} && git -C ${REPO_ROOT} init && cd ${REPO_ROOT}
5+
date +${REPO_DATE_FMT} >> baserepo && git add baserepo && git commit -m "Base repo commit 1"
6+
7+
for sub in A B C; do
8+
git init submodule${sub}
9+
for iter in $(seq 1 4); do
10+
date +${REPO_DATE_FMT} >> submodule${sub}/subcontent
11+
git -C submodule${sub} add subcontent && git -C submodule${sub} commit -m "Submodule ${sub} initial commit $iter"
12+
done
13+
# Add initial submodule, message of "Submodule submoduleX 0000000...xxxxxxx (new submodule)", no individual commits
14+
git submodule add ../bogus-url-${sub} submodule${sub} && \
15+
git commit -m "Add submodule${sub}" # the diff handling for this is correct in delta
16+
17+
# Create additional submodule commits
18+
for iter in $(seq 1 2); do
19+
date +${REPO_DATE_FMT} >> submodule${sub}/subcontent
20+
git -C submodule${sub} add subcontent && git -C submodule${sub} commit -m "Submodule ${sub} extra change ${iter}"
21+
done
22+
git add submodule${sub} && git commit -m "Update submodule${sub}"
23+
done
24+
25+
git -C submoduleA reset --hard HEAD~4
26+
git -C submoduleC reset --hard HEAD~2
27+
28+
for sub in B C; do
29+
for iter in $(seq 1 3); do
30+
date +${REPO_DATE_FMT} >> submodule${sub}/subcontent
31+
git -C submodule${sub} add subcontent && git -C submodule${sub} commit -m "Submodule ${sub} stage change ${iter}"
32+
done
33+
done
34+
35+
# Add all submodule updates in single commit to test multiple submodule updates in single commit
36+
git add submodule[A-C] && git commit -m "Update all submodules"
37+
38+
# submoduleA end state is only removed commits
39+
# submoduleB end state is only added commits
40+
# submoduleC is a mixture of removed and added commits (e.g. different branch)
41+
42+
# Manual, inspect superproject history via:
43+
# "git -c diff.submodule=short log -p | delta --no-gitconfig"
44+
# "git -c diff.submodule=log log -p | delta --no-gitconfig"
45+
# "git -c diff.submodule=diff log -p | delta --no-gitconfig"

src/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ impl Config {
100100
State::CommitMeta => &self.commit_style,
101101
State::FileMeta => &self.file_style,
102102
State::HunkHeader => &self.hunk_header_style,
103+
State::Submodule => &self.file_style,
103104
_ => delta_unreachable("Unreachable code reached in get_style."),
104105
}
105106
}

src/delta.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub enum State {
2424
HunkZero, // In hunk; unchanged line
2525
HunkMinus(Option<String>), // In hunk; removed line (raw_line)
2626
HunkPlus(Option<String>), // In hunk; added line (raw_line)
27+
Submodule,
2728
Unknown,
2829
}
2930

@@ -140,10 +141,11 @@ impl<'a> StateMachine<'a> {
140141
} else if line.starts_with("@@") {
141142
self.handle_hunk_header_line()?
142143
} else if self.source == Source::DiffUnified && line.starts_with("Only in ")
143-
|| line.starts_with("Submodule ")
144144
|| line.starts_with("Binary files ")
145145
{
146-
self.handle_additional_file_meta_cases()?
146+
self.handle_additional_cases(State::FileMeta)?
147+
} else if line.starts_with("Submodule ") {
148+
self.handle_additional_cases(State::Submodule)?
147149
} else if self.state.is_in_hunk() {
148150
// A true hunk line should start with one of: '+', '-', ' '. However, handle_hunk_line
149151
// handles all lines until the state transitions away from the hunk states.
@@ -381,10 +383,10 @@ impl<'a> StateMachine<'a> {
381383
_write_generic_file_meta_header_line(&line, &line, &mut self.painter, self.config)
382384
}
383385

384-
fn handle_additional_file_meta_cases(&mut self) -> std::io::Result<bool> {
386+
fn handle_additional_cases(&mut self, to_state: State) -> std::io::Result<bool> {
385387
let mut handled_line = false;
386388

387-
// Additional FileMeta cases:
389+
// Additional cases:
388390
//
389391
// 1. When comparing directories with diff -u, if filenames match between the
390392
// directories, the files themselves will be compared. However, if an equivalent
@@ -398,7 +400,7 @@ impl<'a> StateMachine<'a> {
398400
// proposal for more robust parsing logic.
399401

400402
self.painter.paint_buffered_minus_and_plus_lines();
401-
self.state = State::FileMeta;
403+
self.state = to_state;
402404
if self.should_handle() {
403405
self.painter.emit()?;
404406
_write_generic_file_meta_header_line(

src/tests/test_example_diffs.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,16 @@ mod tests {
200200
assert_eq!(strip_ansi_codes(&output), DIFF_WITH_MERGE_CONFLICT);
201201
}
202202

203+
#[test]
204+
fn test_submodule_diff_log() {
205+
// See etc/examples/662-submodules
206+
// diff.submodule = log
207+
let config = integration_test_utils::make_config_from_args(&["--width", "49"]);
208+
let output = integration_test_utils::run_delta(SUBMODULE_DIFF_LOG, &config);
209+
let output = strip_ansi_codes(&output);
210+
assert_eq!(output, SUBMODULE_DIFF_LOG_EXPECTED_OUTPUT);
211+
}
212+
203213
#[test]
204214
fn test_submodule_contains_untracked_content() {
205215
let config = integration_test_utils::make_config_from_args(&[]);
@@ -1902,6 +1912,62 @@ This is a regular file that contains:
19021912
+Some text with a plus
19031913
";
19041914

1915+
// See etc/examples/662-submodules
1916+
// diff.submodule = log
1917+
const SUBMODULE_DIFF_LOG: &str = "\
1918+
commit ccb444baa861fdcb14d411b471a74614ed28776d
1919+
Author: Dan Davison <dandavison7@gmail.com>
1920+
Date: Sat Aug 21 18:56:34 2021 -0700
1921+
1922+
Update all submodules
1923+
1924+
Submodule submoduleA f4f55af..310b551 (rewind):
1925+
< Submodule A extra change 2
1926+
< Submodule A extra change 1
1927+
< Submodule A initial commit 4
1928+
< Submodule A initial commit 3
1929+
Submodule submoduleB 0ffa700..0c8b00d:
1930+
> Submodule B stage change 3
1931+
> Submodule B stage change 2
1932+
> Submodule B stage change 1
1933+
Submodule submoduleC 9f3b744...e04f848:
1934+
> Submodule C stage change 3
1935+
> Submodule C stage change 2
1936+
< Submodule C extra change 2
1937+
> Submodule C stage change 1
1938+
< Submodule C extra change 1
1939+
";
1940+
1941+
const SUBMODULE_DIFF_LOG_EXPECTED_OUTPUT: &str = "\
1942+
commit ccb444baa861fdcb14d411b471a74614ed28776d
1943+
Author: Dan Davison <dandavison7@gmail.com>
1944+
Date: Sat Aug 21 18:56:34 2021 -0700
1945+
1946+
Update all submodules
1947+
1948+
1949+
Submodule submoduleA f4f55af..310b551 (rewind):
1950+
─────────────────────────────────────────────────
1951+
< Submodule A extra change 2
1952+
< Submodule A extra change 1
1953+
< Submodule A initial commit 4
1954+
< Submodule A initial commit 3
1955+
1956+
Submodule submoduleB 0ffa700..0c8b00d:
1957+
─────────────────────────────────────────────────
1958+
> Submodule B stage change 3
1959+
> Submodule B stage change 2
1960+
> Submodule B stage change 1
1961+
1962+
Submodule submoduleC 9f3b744...e04f848:
1963+
─────────────────────────────────────────────────
1964+
> Submodule C stage change 3
1965+
> Submodule C stage change 2
1966+
< Submodule C extra change 2
1967+
> Submodule C stage change 1
1968+
< Submodule C extra change 1
1969+
";
1970+
19051971
const SUBMODULE_CONTAINS_UNTRACKED_CONTENT_INPUT: &str = "\
19061972
--- a
19071973
+++ b

0 commit comments

Comments
 (0)