Commit a26f5c4

HPCesia <me@hpcesia.com>
2026-10-11 11:19:32
jujutsu: rebase lfs patch to 0.46.0
Assisted-by: crush:deepseek-v4.1-flash
1 parent 67c2538
Changed files (2)
modules/dev/jujutsu-lfs.patch
@@ -1,8 +1,8 @@
 diff --git a/CHANGELOG.md b/CHANGELOG.md
-index 19ffa10..60eae12 100644
+index 5e3d8d9..430ad41 100644
 --- a/CHANGELOG.md
 +++ b/CHANGELOG.md
-@@ -75,6 +75,8 @@ None
+@@ -246,6 +246,8 @@ None
    directory or loaded via `--config-file`). This allows precise file targeting
    and avoids interactive prompts when multiple config files exist.
  
@@ -12,7 +12,7 @@ index 19ffa10..60eae12 100644
  
  * [The default `immutable_heads()` set](docs/config.md#set-of-immutable-commits)
 diff --git a/cli/src/command_error.rs b/cli/src/command_error.rs
-index 3b6ea7b..30f4f3d 100644
+index e7c410a..7157756 100644
 --- a/cli/src/command_error.rs
 +++ b/cli/src/command_error.rs
 @@ -35,6 +35,8 @@ use jj_lib::fileset::FilePatternParseError;
@@ -24,7 +24,7 @@ index 3b6ea7b..30f4f3d 100644
  use jj_lib::gitignore::GitIgnoreError;
  use jj_lib::index::IndexError;
  use jj_lib::op_heads_store::OpHeadsStoreError;
-@@ -733,6 +735,13 @@ impl From<GitIgnoreError> for CommandError {
+@@ -742,6 +744,13 @@ impl From<GitIgnoreError> for CommandError {
      }
  }
  
@@ -38,8 +38,29 @@ index 3b6ea7b..30f4f3d 100644
  impl From<ParseBulkEditMessageError> for CommandError {
      fn from(err: ParseBulkEditMessageError) -> Self {
          user_error(err)
+diff --git a/cli/src/commands/file/edit.rs b/cli/src/commands/file/edit.rs
+index f1d7154..a1329a3 100644
+--- a/cli/src/commands/file/edit.rs
++++ b/cli/src/commands/file/edit.rs
+@@ -12,6 +12,7 @@
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+ 
++use std::collections::HashSet;
+ use std::io::Write as _;
+ 
+ use clap_complete::ArgValueCompleter;
+@@ -121,6 +122,8 @@ pub(crate) async fn cmd_file_edit(
+         eol_conversion_mode: EolConversionMode::None,
+         exec_change_setting: ExecChangeSetting::Auto,
+         fsmonitor_settings: FsmonitorSettings::None,
++        // The user asked to edit this file explicitly, so never filter it out.
++        ignore_filters: HashSet::new(),
+     };
+     let mut tree_state = TreeState::init(
+         repo.store().clone(),
 diff --git a/cli/src/commands/run.rs b/cli/src/commands/run.rs
-index 3e386a5..e839790 100644
+index 974e8c7..584453c 100644
 --- a/cli/src/commands/run.rs
 +++ b/cli/src/commands/run.rs
 @@ -16,6 +16,7 @@
@@ -50,7 +71,7 @@ index 3e386a5..e839790 100644
  use std::fmt;
  use std::fs;
  use std::io;
-@@ -99,12 +100,13 @@ impl From<RunError> for CommandError {
+@@ -113,12 +114,13 @@ impl From<RunError> for CommandError {
      }
  }
  
@@ -65,31 +86,31 @@ index 3e386a5..e839790 100644
      }
  }
  
-@@ -166,6 +168,7 @@ struct WorkspacePool {
-     /// When true, wipe each slot's working copy on acquisition so every commit
-     /// starts from a freshly checked-out tree (no artifact reuse).
-     clean: bool,
+@@ -183,6 +185,7 @@ struct WorkspacePool {
+     /// Sparse patterns that influence what parts of the tree are materialized
+     /// when running the command. If None, whole tree is materialized.
+     sparsity: Option<Vec<RepoPathBuf>>,
 +    ignore_filters: HashSet<String>,
  }
  
  impl WorkspacePool {
-@@ -174,6 +177,7 @@ impl WorkspacePool {
-         size: NonZeroUsize,
+@@ -192,6 +195,7 @@ impl WorkspacePool {
          auto_tracking_matcher: Box<dyn Matcher>,
          clean: bool,
+         sparsity: Option<Vec<RepoPathBuf>>,
 +        ignore_filters: HashSet<String>,
      ) -> Result<Self, RunError> {
          // The parent() call is needed to not write under `.jj/repo/`.
          let base_path = repo_path.parent().unwrap().join("run").join("default");
-@@ -183,6 +187,7 @@ impl WorkspacePool {
-             size,
+@@ -202,6 +206,7 @@ impl WorkspacePool {
              auto_tracking_matcher,
              clean,
+             sparsity,
 +            ignore_filters,
          })
      }
  
-@@ -209,7 +214,7 @@ impl WorkspacePool {
+@@ -228,7 +233,7 @@ impl WorkspacePool {
          let tree_state_path = state_dir.join("tree_state");
  
          let is_reused_workspace = tree_state_path.exists();
@@ -98,9 +119,9 @@ index 3e386a5..e839790 100644
          let mut tree_state = if !self.clean && is_reused_workspace {
              // Load the persisted tree state so `check_out` below can diff
              // against it, only touching files that changed and removing files
-@@ -754,6 +759,20 @@ pub async fn cmd_run(
-     let store = workspace_command.repo().store().clone();
-     let auto_tracking_matcher = workspace_command.auto_tracking_matcher(ui)?;
+@@ -829,6 +834,21 @@ pub async fn cmd_run(
+         }
+     };
  
 +    let ignore_filters = {
 +        #[cfg(feature = "git")]
@@ -116,34 +137,23 @@ index 3e386a5..e839790 100644
 +            HashSet::new()
 +        }
 +    };
++
      let mut tx = workspace_command.start_transaction();
  
      let rt = {
-@@ -769,6 +788,7 @@ pub async fn cmd_run(
-         jobs,
+@@ -845,6 +865,7 @@ pub async fn cmd_run(
          auto_tracking_matcher,
          args.clean,
+         sparsity,
 +        ignore_filters,
      )?);
  
      let spec = Arc::new(CommandSpec {
-diff --git a/cli/src/config/misc.toml b/cli/src/config/misc.toml
-index 70ed210..cd5d01c 100644
---- a/cli/src/config/misc.toml
-+++ b/cli/src/config/misc.toml
-@@ -26,6 +26,7 @@ disabled-branches = []
- 
- [git]
- colocate = true
-+ignore-filters = ["lfs"]
- object-hash = "sha1"
- private-commits = "none()"
- sign-on-push = false
 diff --git a/cli/src/config-schema.json b/cli/src/config-schema.json
-index aa84124..9b7d768 100644
+index ddf82bb..1a93cd7 100644
 --- a/cli/src/config-schema.json
 +++ b/cli/src/config-schema.json
-@@ -559,6 +559,14 @@
+@@ -569,6 +569,14 @@
                      "enum": ["sha1", "sha256"],
                      "description": "Object hash algorithm used when initializing a new Git repository",
                      "default": "sha1"
@@ -158,17 +168,29 @@ index aa84124..9b7d768 100644
                  }
              }
          },
+diff --git a/cli/src/config/misc.toml b/cli/src/config/misc.toml
+index 70ed210..cd5d01c 100644
+--- a/cli/src/config/misc.toml
++++ b/cli/src/config/misc.toml
+@@ -26,6 +26,7 @@ disabled-branches = []
+ 
+ [git]
+ colocate = true
++ignore-filters = ["lfs"]
+ object-hash = "sha1"
+ private-commits = "none()"
+ sign-on-push = false
 diff --git a/cli/src/merge_tools/diff_working_copies.rs b/cli/src/merge_tools/diff_working_copies.rs
-index 7b5cb00..5113cd8 100644
+index 771cc58..c4171da 100644
 --- a/cli/src/merge_tools/diff_working_copies.rs
 +++ b/cli/src/merge_tools/diff_working_copies.rs
 @@ -1,4 +1,5 @@
  use std::collections::HashMap;
 +use std::collections::HashSet;
+ use std::ffi::OsString;
  use std::fs::File;
- use std::io;
  use std::io::Write as _;
-@@ -156,6 +157,7 @@ pub(crate) async fn check_out_trees(
+@@ -144,6 +145,7 @@ pub(crate) async fn check_out_trees(
      matcher: &dyn Matcher,
      diff_type: DiffType,
      conflict_marker_style: ConflictMarkerStyle,
@@ -176,7 +198,7 @@ index 7b5cb00..5113cd8 100644
  ) -> Result<DiffWorkingCopies, DiffCheckoutError> {
      let store = trees.before.store();
      let changed_files: Vec<_> = trees
-@@ -179,6 +181,7 @@ pub(crate) async fn check_out_trees(
+@@ -170,6 +172,7 @@ pub(crate) async fn check_out_trees(
              eol_conversion_mode: EolConversionMode::None,
              exec_change_setting: ExecChangeSetting::Auto,
              fsmonitor_settings: FsmonitorSettings::None,
@@ -184,7 +206,7 @@ index 7b5cb00..5113cd8 100644
          };
          let mut state = TreeState::init(store.clone(), wc_path, state_dir, &tree_state_settings)?;
          state.set_sparse_patterns(changed_files.clone())?;
-@@ -214,9 +217,16 @@ impl DiffEditWorkingCopies {
+@@ -205,9 +208,16 @@ impl DiffEditWorkingCopies {
          diff_type: DiffType,
          instructions: Option<&str>,
          conflict_marker_style: ConflictMarkerStyle,
@@ -204,16 +226,16 @@ index 7b5cb00..5113cd8 100644
          if diff_type == DiffType::ThreeWay {
              working_copies.set_right_readonly()?;
 diff --git a/cli/src/merge_tools/external.rs b/cli/src/merge_tools/external.rs
-index 9465915..994ed83 100644
+index 1fcb437..34afb96 100644
 --- a/cli/src/merge_tools/external.rs
 +++ b/cli/src/merge_tools/external.rs
 @@ -1,4 +1,5 @@
  use std::collections::HashMap;
 +use std::collections::HashSet;
+ use std::ffi::OsString;
  use std::io;
  use std::io::Write;
- use std::path::Path;
-@@ -388,6 +389,7 @@ pub async fn edit_diff_external(
+@@ -386,6 +387,7 @@ pub async fn edit_diff_external(
      instructions: Option<&str>,
      base_ignores: Arc<GitIgnoreFile>,
      default_conflict_marker_style: ConflictMarkerStyle,
@@ -221,7 +243,7 @@ index 9465915..994ed83 100644
  ) -> Result<MergedTree, DiffEditError> {
      let conflict_marker_style = editor
          .conflict_marker_style
-@@ -405,6 +407,7 @@ pub async fn edit_diff_external(
+@@ -403,6 +405,7 @@ pub async fn edit_diff_external(
          diff_type,
          instructions,
          conflict_marker_style,
@@ -229,7 +251,7 @@ index 9465915..994ed83 100644
      )
      .await?;
  
-@@ -456,7 +459,14 @@ pub async fn generate_diff(
+@@ -454,7 +457,14 @@ pub async fn generate_diff(
      let conflict_marker_style = tool
          .conflict_marker_style
          .unwrap_or(default_conflict_marker_style);
@@ -246,7 +268,7 @@ index 9465915..994ed83 100644
      diff_wc.set_right_readonly()?;
      let mut patterns = diff_wc.to_command_variables(true);
 diff --git a/cli/src/merge_tools/mod.rs b/cli/src/merge_tools/mod.rs
-index 17f9521..f7a8958 100644
+index 2cfc12b..aaeb858 100644
 --- a/cli/src/merge_tools/mod.rs
 +++ b/cli/src/merge_tools/mod.rs
 @@ -16,6 +16,7 @@ mod builtin;
@@ -257,7 +279,7 @@ index 17f9521..f7a8958 100644
  use std::sync::Arc;
  
  use futures::future::try_join_all;
-@@ -235,6 +236,7 @@ pub fn get_external_tool_config(
+@@ -234,6 +235,7 @@ pub fn get_external_tool_config(
  pub struct DiffEditor {
      tool: DiffEditTool,
      base_ignores: Arc<GitIgnoreFile>,
@@ -265,7 +287,7 @@ index 17f9521..f7a8958 100644
      use_instructions: bool,
      conflict_marker_style: ConflictMarkerStyle,
  }
-@@ -284,9 +286,24 @@ impl DiffEditor {
+@@ -283,9 +285,24 @@ impl DiffEditor {
                  tool_name: name.to_string(),
              });
          }
@@ -290,7 +312,7 @@ index 17f9521..f7a8958 100644
              use_instructions: settings.get_bool("ui.diff-instructions")?,
              conflict_marker_style,
          })
-@@ -316,6 +333,7 @@ impl DiffEditor {
+@@ -315,6 +332,7 @@ impl DiffEditor {
                      instructions.as_deref(),
                      self.base_ignores.clone(),
                      self.conflict_marker_style,
@@ -299,7 +321,7 @@ index 17f9521..f7a8958 100644
                  .await
              }
 diff --git a/cli/tests/test_diffedit_command.rs b/cli/tests/test_diffedit_command.rs
-index 675c66e..2adff9c 100644
+index e54c639..fe074bb 100644
 --- a/cli/tests/test_diffedit_command.rs
 +++ b/cli/tests/test_diffedit_command.rs
 @@ -18,6 +18,48 @@ use testutils::TestResult;
@@ -352,7 +374,7 @@ index 675c66e..2adff9c 100644
  fn test_diffedit() -> TestResult {
      let mut test_env = TestEnvironment::default();
 diff --git a/cli/tests/test_run_command.rs b/cli/tests/test_run_command.rs
-index 2cb2a48..6fc07c3 100644
+index 8d3d990..f41a73d 100644
 --- a/cli/tests/test_run_command.rs
 +++ b/cli/tests/test_run_command.rs
 @@ -67,6 +67,48 @@ fn test_run_simple() {
@@ -405,10 +427,10 @@ index 2cb2a48..6fc07c3 100644
  fn test_run_on_immutable() {
      let test_env = TestEnvironment::default();
 diff --git a/docs/config.md b/docs/config.md
-index 5d4bb11..3c6b04d 100644
+index dd95ea6..81856a7 100644
 --- a/docs/config.md
 +++ b/docs/config.md
-@@ -2000,6 +2000,23 @@ you can:
+@@ -2065,6 +2065,23 @@ you can:
  executable-path = "/path/to/git"
  ```
  
@@ -433,7 +455,7 @@ index 5d4bb11..3c6b04d 100644
  
  ### Default remote
 diff --git a/docs/git-compatibility.md b/docs/git-compatibility.md
-index c9726fe..430acc3 100644
+index ab8f854..fa6e0c7 100644
 --- a/docs/git-compatibility.md
 +++ b/docs/git-compatibility.md
 @@ -35,8 +35,13 @@ a comparison with Git, including how workflows are different, see the
@@ -469,18 +491,18 @@ index c9726fe..430acc3 100644
  ## Creating an empty repo
  
 diff --git a/lib/src/git.rs b/lib/src/git.rs
-index 5c3c178..a84179a 100644
+index 9429cd8..0dfd7b1 100644
 --- a/lib/src/git.rs
 +++ b/lib/src/git.rs
-@@ -42,6 +42,7 @@ use crate::backend::CommitId;
+@@ -43,6 +43,7 @@ use crate::backend::CommitId;
  use crate::backend::TreeValue;
  use crate::commit::Commit;
  use crate::config::ConfigGetError;
 +use crate::config::ConfigGetResultExt as _;
  use crate::file_util::IoResultExt as _;
  use crate::file_util::PathError;
- use crate::git_backend::GitBackend;
-@@ -104,6 +105,7 @@ pub struct GitSettings {
+ use crate::file_util::is_empty_dir;
+@@ -112,6 +113,7 @@ pub struct GitSettings {
      pub executable_path: PathBuf,
      pub record_synthetic_predecessors: bool,
      pub write_change_id_header: bool,
@@ -488,7 +510,7 @@ index 5c3c178..a84179a 100644
  }
  
  impl GitSettings {
-@@ -114,6 +116,10 @@ impl GitSettings {
+@@ -122,6 +124,10 @@ impl GitSettings {
              record_synthetic_predecessors: settings
                  .get_bool("git.record-synthetic-predecessors")?,
              write_change_id_header: settings.get("git.write-change-id-header")?,
@@ -499,7 +521,7 @@ index 5c3c178..a84179a 100644
          })
      }
  
-diff --git b/lib/src/gitattributes.rs b/lib/src/gitattributes.rs
+diff --git a/lib/src/gitattributes.rs b/lib/src/gitattributes.rs
 new file mode 100644
 index 0000000..8a12782
 --- /dev/null
@@ -1480,7 +1502,7 @@ index 0000000..8a12782
 +    }
 +}
 diff --git a/lib/src/lib.rs b/lib/src/lib.rs
-index 7cb8160..c990b62 100644
+index 130ca7a..d3a5ee1 100644
 --- a/lib/src/lib.rs
 +++ b/lib/src/lib.rs
 @@ -55,6 +55,8 @@ pub mod git;
@@ -1493,7 +1515,7 @@ index 7cb8160..c990b62 100644
  pub mod gpg_signing;
  pub use jj_core::graph;
 diff --git a/lib/src/local_working_copy.rs b/lib/src/local_working_copy.rs
-index 87da9f5..c3547b3 100644
+index a254834..0587023 100644
 --- a/lib/src/local_working_copy.rs
 +++ b/lib/src/local_working_copy.rs
 @@ -93,6 +93,16 @@ use crate::fsmonitor::FsmonitorSettings;
@@ -1513,7 +1535,7 @@ index 87da9f5..c3547b3 100644
  use crate::gitignore::GitIgnoreFile;
  use crate::lock::FileLock;
  use crate::matchers::DifferenceMatcher;
-@@ -975,6 +985,10 @@ pub struct TreeStateSettings {
+@@ -977,6 +987,10 @@ pub struct TreeStateSettings {
      pub exec_change_setting: ExecChangeSetting,
      /// The fsmonitor (e.g. Watchman) to use, if any.
      pub fsmonitor_settings: FsmonitorSettings,
@@ -1524,7 +1546,7 @@ index 87da9f5..c3547b3 100644
  }
  
  impl TreeStateSettings {
-@@ -985,6 +999,19 @@ impl TreeStateSettings {
+@@ -987,6 +1001,19 @@ impl TreeStateSettings {
              eol_conversion_mode: EolConversionMode::try_from_settings(user_settings)?,
              exec_change_setting: user_settings.get("working-copy.exec-bit-change")?,
              fsmonitor_settings: FsmonitorSettings::from_settings(user_settings)?,
@@ -1544,7 +1566,7 @@ index 87da9f5..c3547b3 100644
          })
      }
  }
-@@ -1009,6 +1036,9 @@ pub struct TreeState {
+@@ -1011,6 +1038,9 @@ pub struct TreeState {
      exec_policy: ExecChangePolicy,
      fsmonitor_settings: FsmonitorSettings,
      target_eol_strategy: TargetEolStrategy,
@@ -1554,7 +1576,7 @@ index 87da9f5..c3547b3 100644
  }
  
  #[derive(Debug, Error)]
-@@ -1082,9 +1112,18 @@ impl TreeState {
+@@ -1084,9 +1114,18 @@ impl TreeState {
              eol_conversion_mode,
              exec_change_setting,
              fsmonitor_settings,
@@ -1573,7 +1595,7 @@ index 87da9f5..c3547b3 100644
          Self {
              store: store.clone(),
              working_copy_path,
-@@ -1099,6 +1138,7 @@ impl TreeState {
+@@ -1101,6 +1140,7 @@ impl TreeState {
              exec_policy,
              fsmonitor_settings: fsmonitor_settings.clone(),
              target_eol_strategy: TargetEolStrategy::new(*eol_conversion_mode),
@@ -1581,7 +1603,7 @@ index 87da9f5..c3547b3 100644
          }
      }
  
-@@ -1332,6 +1372,11 @@ impl TreeState {
+@@ -1337,6 +1377,11 @@ impl TreeState {
          let (untracked_paths_tx, untracked_paths_rx) = channel();
          let (invalid_utf8_paths_tx, invalid_utf8_paths_rx) = channel();
          let (deleted_files_tx, deleted_files_rx) = channel();
@@ -1593,7 +1615,7 @@ index 87da9f5..c3547b3 100644
  
          trace_span!("traverse filesystem").in_scope(|| -> Result<(), SnapshotError> {
              let snapshotter = FileSnapshotter {
-@@ -1349,6 +1394,10 @@ impl TreeState {
+@@ -1355,6 +1400,10 @@ impl TreeState {
                  error: OnceLock::new(),
                  progress: *progress,
                  max_new_file_size: *max_new_file_size,
@@ -1604,7 +1626,7 @@ index 87da9f5..c3547b3 100644
              };
              let directory_to_visit = DirectoryToVisit {
                  dir: RepoPathBuf::root(),
-@@ -1524,6 +1573,11 @@ struct FileSnapshotter<'a> {
+@@ -1544,6 +1593,11 @@ struct FileSnapshotter<'a> {
      error: OnceLock<SnapshotError>,
      progress: Option<&'a SnapshotProgress<'a>>,
      max_new_file_size: u64,
@@ -1616,7 +1638,7 @@ index 87da9f5..c3547b3 100644
  }
  
  impl FileSnapshotter<'_> {
-@@ -1589,7 +1643,7 @@ impl FileSnapshotter<'_> {
+@@ -1616,7 +1670,7 @@ impl FileSnapshotter<'_> {
              })
              .collect::<Result<_, _>>()?;
          let present_entries = PresentDirEntries { dirs, files };
@@ -1625,7 +1647,7 @@ index 87da9f5..c3547b3 100644
          Ok(())
      }
  
-@@ -1671,8 +1725,20 @@ impl FileSnapshotter<'_> {
+@@ -1785,8 +1839,20 @@ impl FileSnapshotter<'_> {
              if let Some(progress) = self.progress {
                  progress(&path);
              }
@@ -1647,7 +1669,7 @@ index 87da9f5..c3547b3 100644
              {
                  // If it wasn't already tracked and it matches
                  // the ignored paths, then ignore it.
-@@ -1731,6 +1797,14 @@ impl FileSnapshotter<'_> {
+@@ -1845,6 +1911,14 @@ impl FileSnapshotter<'_> {
              if !self.matcher.matches(tracked_path) {
                  continue;
              }
@@ -1662,7 +1684,7 @@ index 87da9f5..c3547b3 100644
              let disk_path = tracked_path.to_fs_path(&self.tree_state.working_copy_path)?;
              let metadata = match disk_path.symlink_metadata() {
                  Ok(metadata) => Some(metadata),
-@@ -1792,7 +1866,7 @@ impl FileSnapshotter<'_> {
+@@ -1906,7 +1980,7 @@ impl FileSnapshotter<'_> {
          dir: &RepoPath,
          file_states: FileStates<'_>,
          present_entries: &PresentDirEntries,
@@ -1671,7 +1693,7 @@ index 87da9f5..c3547b3 100644
          let file_state_chunks = file_states.iter().chunk_by(|(path, _state)| {
              // Extract <name> from <dir>, <dir>/<name>, or <dir>/<name>/**.
              // (file_states may contain <dir> file on file->dir transition.)
-@@ -1805,18 +1879,34 @@ impl FileSnapshotter<'_> {
+@@ -1919,18 +1993,34 @@ impl FileSnapshotter<'_> {
                  None => (PresentDirEntryKind::File, tail),
              }
          });
@@ -1738,10 +1760,10 @@ index 0d4317c..6b3950a 100644
      #[error(transparent)]
      WorkingCopyStateError(#[from] WorkingCopyStateError),
 diff --git a/lib/tests/test_local_working_copy.rs b/lib/tests/test_local_working_copy.rs
-index a689d6e..12d290d 100644
+index 509a20b..85c4708 100644
 --- a/lib/tests/test_local_working_copy.rs
 +++ b/lib/tests/test_local_working_copy.rs
-@@ -3173,3 +3173,181 @@ fn test_always_store_empty_tree() -> TestResult {
+@@ -3192,3 +3192,181 @@ fn test_always_store_empty_tree() -> TestResult {
      assert!(empty_tree.data.is_empty());
      Ok(())
  }
modules/dev/jujutsu.nix
@@ -12,7 +12,7 @@
         lib,
         ...
       }: let
-        # git.ignore-filters support, from https://github.com/jj-vcs/jj/pull/9635.
+        # git.ignore-filters support, from https://github.com/jj-vcs/jj/pull/9635
         # TODO: re-check this patch on every nixpkgs bump, drop it once upstreamed.
         jujutsu = pkgs.jujutsu.overrideAttrs {
           patches = [./jujutsu-lfs.patch];