Skip to content

Commit 4b6d4f6

Browse files
committed
track: only print snapshot stats and hints once
Move the `track` specific logic to track.rs, let print_snapshot_stats handle just the default case. Previously print_snapshot_stats would get called twice and could warn twice about a file (if that file was both in the auto-track fileset as well as in the fileset passed to `jj file track`), so now we merge the snapshot stats and display appropriate hints for each file.
1 parent d4ab59c commit 4b6d4f6

File tree

5 files changed

+112
-83
lines changed

5 files changed

+112
-83
lines changed

cli/src/cli_util.rs

Lines changed: 22 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,7 @@ impl CommandHelper {
414414
#[instrument(skip(self, ui))]
415415
pub fn workspace_helper(&self, ui: &Ui) -> Result<WorkspaceCommandHelper, CommandError> {
416416
let (workspace_command, stats) = self.workspace_helper_with_stats(ui)?;
417-
print_snapshot_stats(
418-
ui,
419-
&stats,
420-
workspace_command.env().path_converter(),
421-
SnapshotContext::Automatic,
422-
)?;
417+
print_snapshot_stats(ui, &stats, workspace_command.env().path_converter())?;
423418
Ok(workspace_command)
424419
}
425420

@@ -1101,12 +1096,7 @@ impl WorkspaceCommandHelper {
11011096
let stats = self
11021097
.maybe_snapshot_impl(ui)
11031098
.map_err(|err| err.into_command_error())?;
1104-
print_snapshot_stats(
1105-
ui,
1106-
&stats,
1107-
self.path_converter(),
1108-
SnapshotContext::Automatic,
1109-
)?;
1099+
print_snapshot_stats(ui, &stats, self.path_converter())?;
11101100
Ok(stats)
11111101
}
11121102

@@ -2658,13 +2648,6 @@ pub fn print_conflicted_paths(
26582648
Ok(())
26592649
}
26602650

2661-
pub enum SnapshotContext {
2662-
Automatic,
2663-
Status,
2664-
Track,
2665-
Untrack,
2666-
}
2667-
26682651
/// Build human-readable messages explaining why the file was not tracked
26692652
fn build_untracked_reason_message<'a>(
26702653
(path, reason): (&'a RepoPathBuf, &'a UntrackedReason),
@@ -2717,48 +2700,29 @@ pub fn print_snapshot_stats(
27172700
ui: &Ui,
27182701
stats: &SnapshotStats,
27192702
path_converter: &RepoPathUiConverter,
2720-
context: SnapshotContext,
27212703
) -> io::Result<()> {
27222704
print_untracked_files(ui, &stats.untracked_paths, path_converter)?;
27232705

2724-
let large_files = stats
2725-
.untracked_paths
2726-
.iter()
2727-
.filter_map(|(path, reason)| match reason {
2728-
UntrackedReason::FileTooLarge { size, .. } => Some((path, size)),
2729-
UntrackedReason::FileNotAutoTracked => None,
2730-
})
2731-
.collect_vec();
2732-
if let Some(size) = large_files.iter().map(|(_, size)| size).max() {
2733-
match context {
2734-
SnapshotContext::Track => {
2735-
let large_files_list = large_files
2736-
.iter()
2737-
.map(|(p, _)| path_converter.format_file_path(p))
2738-
.join(" ");
2739-
writedoc!(
2740-
ui.hint_default(),
2741-
r"
2742-
This is to prevent large files from being added by accident. You can fix this by:
2743-
- Run `jj config set --repo snapshot.max-new-file-size {size}`
2744-
This will increase the maximum file size allowed for new files, in this repository only.
2745-
- Run `jj --config snapshot.max-new-file-size={size} file track {large_files_list}`
2746-
This will increase the maximum file size allowed for new files, for this command only.
2747-
"
2748-
)?;
2749-
}
2750-
_ => writedoc!(
2751-
ui.hint_default(),
2752-
r"
2753-
This is to prevent large files from being added by accident. You can fix this by:
2754-
- Adding the file to `.gitignore`
2755-
- Run `jj config set --repo snapshot.max-new-file-size {size}`
2756-
This will increase the maximum file size allowed for new files, in this repository only.
2757-
- Run `jj --config snapshot.max-new-file-size={size} st`
2758-
This will increase the maximum file size allowed for new files, for this command only.
2759-
"
2760-
)?,
2761-
};
2706+
let large_files_sizes =
2707+
stats
2708+
.untracked_paths
2709+
.iter()
2710+
.filter_map(|(_path, reason)| match reason {
2711+
UntrackedReason::FileTooLarge { size, .. } => Some(size),
2712+
UntrackedReason::FileNotAutoTracked => None,
2713+
});
2714+
if let Some(size) = large_files_sizes.max() {
2715+
writedoc!(
2716+
ui.hint_default(),
2717+
r"
2718+
This is to prevent large files from being added by accident. You can fix this by:
2719+
- Adding the file to `.gitignore`
2720+
- Run `jj config set --repo snapshot.max-new-file-size {size}`
2721+
This will increase the maximum file size allowed for new files, in this repository only.
2722+
- Run `jj --config snapshot.max-new-file-size={size} st`
2723+
This will increase the maximum file size allowed for new files, for this command only.
2724+
"
2725+
)?;
27622726
}
27632727
Ok(())
27642728
}

cli/src/commands/file/track.rs

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,21 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use std::io;
1516
use std::io::Write;
17+
use std::ops::Not;
1618

19+
use indoc::writedoc;
20+
use itertools::Itertools;
21+
use jj_lib::matchers::Matcher;
22+
use jj_lib::repo_path::RepoPathUiConverter;
23+
use jj_lib::working_copy::SnapshotStats;
24+
use jj_lib::working_copy::UntrackedReason;
1725
use tracing::instrument;
1826

1927
use crate::cli_util::print_snapshot_stats;
28+
use crate::cli_util::print_untracked_files;
2029
use crate::cli_util::CommandHelper;
21-
use crate::cli_util::SnapshotContext;
2230
use crate::command_error::CommandError;
2331
use crate::ui::Ui;
2432

@@ -44,26 +52,90 @@ pub(crate) fn cmd_file_track(
4452
command: &CommandHelper,
4553
args: &FileTrackArgs,
4654
) -> Result<(), CommandError> {
47-
let mut workspace_command = command.workspace_helper(ui)?;
55+
let (mut workspace_command, auto_stats) = command.workspace_helper_with_stats(ui)?;
4856
let matcher = workspace_command
4957
.parse_file_patterns(ui, &args.paths)?
5058
.to_matcher();
59+
5160
let options = workspace_command.snapshot_options_with_start_tracking_matcher(&matcher)?;
5261

5362
let mut tx = workspace_command.start_transaction().into_inner();
5463
let (mut locked_ws, _wc_commit) = workspace_command.start_working_copy_mutation()?;
55-
let (_tree_id, stats) = locked_ws.locked_wc().snapshot(&options)?;
64+
let (_tree_id, track_stats) = locked_ws.locked_wc().snapshot(&options)?;
5665
let num_rebased = tx.repo_mut().rebase_descendants()?;
5766
if num_rebased > 0 {
5867
writeln!(ui.status(), "Rebased {num_rebased} descendant commits")?;
5968
}
6069
let repo = tx.commit("track paths")?;
6170
locked_ws.finish(repo.op_id().clone())?;
62-
print_snapshot_stats(
71+
print_track_snapshot_stats(
6372
ui,
64-
&stats,
73+
auto_stats,
74+
track_stats,
75+
&matcher,
6576
workspace_command.env().path_converter(),
66-
SnapshotContext::Track,
6777
)?;
6878
Ok(())
6979
}
80+
81+
pub fn print_track_snapshot_stats(
82+
ui: &Ui,
83+
auto_stats: SnapshotStats,
84+
track_stats: SnapshotStats,
85+
track_matcher: &dyn Matcher,
86+
path_converter: &RepoPathUiConverter,
87+
) -> io::Result<()> {
88+
if track_stats
89+
.untracked_paths
90+
.iter()
91+
.any(|(path, _)| track_matcher.matches(path))
92+
.not()
93+
{
94+
// we can use the "normal" report path, nothing special happened to a file we
95+
// care about
96+
return print_snapshot_stats(ui, &auto_stats, path_converter);
97+
}
98+
99+
let mut merged_untracked_paths = auto_stats.untracked_paths;
100+
for (path, reason) in track_stats
101+
.untracked_paths
102+
.into_iter()
103+
// focus on files that are now tracked with `file track`
104+
.filter(|(_, reason)| matches!(reason, UntrackedReason::FileNotAutoTracked).not())
105+
{
106+
// if the path was previously rejected because it wasn't tracked, update its
107+
// reason
108+
merged_untracked_paths
109+
.entry(path)
110+
.and_modify(|other_reason| *other_reason = reason.clone())
111+
.or_insert(reason);
112+
}
113+
114+
print_untracked_files(ui, &merged_untracked_paths, path_converter)?;
115+
116+
let large_files = merged_untracked_paths
117+
.iter()
118+
.filter_map(|(path, reason)| match reason {
119+
UntrackedReason::FileTooLarge { size, .. } => Some((path, size)),
120+
UntrackedReason::FileNotAutoTracked => None,
121+
})
122+
.collect_vec();
123+
if let Some(size) = large_files.iter().map(|(_path, size)| size).max() {
124+
let large_files_list = large_files
125+
.iter()
126+
.map(|(path, _)| path_converter.format_file_path(path))
127+
.join(" ");
128+
writedoc!(
129+
ui.hint_default(),
130+
r"
131+
This is to prevent large files from being added by accident. You can fix this by:
132+
- Adding the file to `.gitignore`
133+
- Run `jj config set --repo snapshot.max-new-file-size {size}`
134+
This will increase the maximum file size allowed for new files, in this repository only.
135+
- Run `jj --config snapshot.max-new-file-size={size} file track {large_files_list}`
136+
This will increase the maximum file size allowed for new files, for this command only.
137+
"
138+
)?;
139+
}
140+
Ok(())
141+
}

cli/src/commands/file/untrack.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use tracing::instrument;
2323

2424
use crate::cli_util::print_snapshot_stats;
2525
use crate::cli_util::CommandHelper;
26-
use crate::cli_util::SnapshotContext;
2726
use crate::command_error::user_error_with_hint;
2827
use crate::command_error::CommandError;
2928
use crate::complete;
@@ -112,11 +111,6 @@ Make sure they're ignored, then try again.",
112111
}
113112
let repo = tx.commit("untrack paths")?;
114113
locked_ws.finish(repo.op_id().clone())?;
115-
print_snapshot_stats(
116-
ui,
117-
&stats,
118-
workspace_command.env().path_converter(),
119-
SnapshotContext::Untrack,
120-
)?;
114+
print_snapshot_stats(ui, &stats, workspace_command.env().path_converter())?;
121115
Ok(())
122116
}

cli/src/commands/status.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use tracing::instrument;
2424
use crate::cli_util::print_conflicted_paths;
2525
use crate::cli_util::print_snapshot_stats;
2626
use crate::cli_util::CommandHelper;
27-
use crate::cli_util::SnapshotContext;
2827
use crate::command_error::CommandError;
2928
use crate::diff_util::get_copy_records;
3029
use crate::diff_util::DiffFormat;
@@ -59,7 +58,6 @@ pub(crate) fn cmd_status(
5958
ui,
6059
&snapshot_stats,
6160
workspace_command.env().path_converter(),
62-
SnapshotContext::Status,
6361
)?;
6462
let repo = workspace_command.repo();
6563
let maybe_wc_commit = workspace_command

cli/tests/test_working_copy.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,24 +58,25 @@ fn test_snapshot_large_file() {
5858
This will increase the maximum file size allowed for new files, for this command only.
5959
"#);
6060

61-
// test with file track for hint formatting
61+
// test with file track for hint formatting, both files should appear in
62+
// warnings even though they were snapshotted separately
6263
std::fs::write(repo_path.join("large2"), big_string).unwrap();
63-
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["file", "track", "large", "large2"]);
64+
let (stdout, stderr) = test_env.jj_cmd_ok(
65+
&repo_path,
66+
&[
67+
"file",
68+
"--config=snapshot.auto-track='large'",
69+
"track",
70+
"large2",
71+
],
72+
);
6473
insta::assert_snapshot!(stdout, @"");
6574
insta::assert_snapshot!(stderr, @r#"
6675
Warning: Refused to snapshot some files:
6776
large: 11.0KiB (11264 bytes); the maximum size allowed is 10.0KiB (10240 bytes)
6877
large2: 11.0KiB (11264 bytes); the maximum size allowed is 10.0KiB (10240 bytes)
6978
Hint: This is to prevent large files from being added by accident. You can fix this by:
7079
- Adding the file to `.gitignore`
71-
- Run `jj config set --repo snapshot.max-new-file-size 11264`
72-
This will increase the maximum file size allowed for new files, in this repository only.
73-
- Run `jj --config snapshot.max-new-file-size=11264 st`
74-
This will increase the maximum file size allowed for new files, for this command only.
75-
Warning: Refused to snapshot some files:
76-
large: 11.0KiB (11264 bytes); the maximum size allowed is 10.0KiB (10240 bytes)
77-
large2: 11.0KiB (11264 bytes); the maximum size allowed is 10.0KiB (10240 bytes)
78-
Hint: This is to prevent large files from being added by accident. You can fix this by:
7980
- Run `jj config set --repo snapshot.max-new-file-size 11264`
8081
This will increase the maximum file size allowed for new files, in this repository only.
8182
- Run `jj --config snapshot.max-new-file-size=11264 file track large large2`

0 commit comments

Comments
 (0)