1033 lines · 35.2 KB · Rust
RawDownload
pub(crate) mod convert_to_diffable {     use gix_diff::blob::{        ResourceKind, pipeline,        pipeline::{Options, WorktreeRoots},    };    use gix_filter::{eol, eol::AutoCrlf};    use gix_object::{bstr::ByteSlice, tree::EntryKind};     use crate::util::{insert, object_db};     #[test]    fn simple() -> crate::Result {        for mode in [            pipeline::Mode::ToWorktreeAndBinaryToText,            pipeline::Mode::ToGit,            pipeline::Mode::ToGitUnlessBinaryToTextIsPresent,        ] {            let tmp = gix_testtools::tempfile::TempDir::new()?;            let mut filter = gix_diff::blob::Pipeline::new(                WorktreeRoots {                    old_root: Some(tmp.path().to_owned()),                    new_root: None,                },                gix_filter::Pipeline::default(),                vec![],                default_options(),            );             let does_not_matter = gix_hash::Kind::Sha1.null();            let mut buf = Vec::new();            let a_name = "a";            let a_content = "a-content";            std::fs::write(tmp.path().join(a_name), a_content.as_bytes())?;            let out = filter.convert_to_diffable(                &does_not_matter,                EntryKind::Blob,                a_name.into(),                ResourceKind::OldOrSource,                &mut |_, _| {},                &gix_object::find::Never,                mode,                &mut buf,            )?;            assert!(out.driver_index.is_none(), "there was no driver");            assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));            assert_eq!(buf.as_bstr(), a_content, "there is no transformations configured");             let link_name = "link";            gix_fs::symlink::create(a_name.as_ref(), &tmp.path().join(link_name))?;            let out = filter.convert_to_diffable(                &does_not_matter,                EntryKind::Link,                link_name.into(),                ResourceKind::OldOrSource,                &mut |_, _| {},                &gix_object::find::Never,                mode,                &mut buf,            )?;             assert!(out.driver_index.is_none());            assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));            assert_eq!(                buf.as_bstr(),                a_name,                "links are just files with a different mode, with its content pointing to the target"            );            drop(tmp);             let db = object_db();            let b_content = "b-content";            let id = insert(&db, b_content)?;             let out = filter.convert_to_diffable(                &id,                EntryKind::Blob,                a_name.into(),                ResourceKind::NewOrDestination,                &mut |_, _| {},                &db,                mode,                &mut buf,            )?;             assert!(out.driver_index.is_none(), "there was no driver");            assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));            assert_eq!(buf.as_bstr(), b_content, "there is no transformations configured");        }         Ok(())    }     #[test]    fn binary_below_large_file_threshold() -> crate::Result {        let tmp = gix_testtools::tempfile::TempDir::new()?;        let mut filter = gix_diff::blob::Pipeline::new(            WorktreeRoots {                old_root: None,                new_root: Some(tmp.path().to_owned()),            },            gix_filter::Pipeline::default(),            vec![],            gix_diff::blob::pipeline::Options {                large_file_threshold_bytes: 5,                ..default_options()            },        );         let does_not_matter = gix_hash::Kind::Sha1.null();        let mut buf = Vec::new();        let a_name = "a";        let large_content = "a\0b";        std::fs::write(tmp.path().join(a_name), large_content.as_bytes())?;        let out = filter.convert_to_diffable(            &does_not_matter,            EntryKind::BlobExecutable,            a_name.into(),            ResourceKind::NewOrDestination,            &mut |_, _| {},            &gix_object::find::Never,            pipeline::Mode::default(),            &mut buf,        )?;        assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, Some(pipeline::Data::Binary { size: 3 }), "detected in buffer");        assert_eq!(buf.len(), 0, "it should avoid querying that data in the first place");         let db = object_db();        let id = insert(&db, large_content)?;        let out = filter.convert_to_diffable(            &id,            EntryKind::Blob,            a_name.into(),            ResourceKind::OldOrSource,            &mut |_, _| {},            &db,            pipeline::Mode::default(),            &mut buf,        )?;         assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, Some(pipeline::Data::Binary { size: 3 }));        assert_eq!(buf.len(), 0, "it should avoid querying that data in the first place");         Ok(())    }     #[test]    fn above_large_file_threshold() -> crate::Result {        let tmp = gix_testtools::tempfile::TempDir::new()?;        let mut filter = gix_diff::blob::Pipeline::new(            WorktreeRoots {                old_root: None,                new_root: Some(tmp.path().to_owned()),            },            gix_filter::Pipeline::default(),            vec![],            gix_diff::blob::pipeline::Options {                large_file_threshold_bytes: 4,                ..default_options()            },        );         let does_not_matter = gix_hash::Kind::Sha1.null();        let mut buf = Vec::new();        let a_name = "a";        let large_content = "hello";        std::fs::write(tmp.path().join(a_name), large_content.as_bytes())?;        let out = filter.convert_to_diffable(            &does_not_matter,            EntryKind::BlobExecutable,            a_name.into(),            ResourceKind::NewOrDestination,            &mut |_, _| {},            &gix_object::find::Never,            pipeline::Mode::default(),            &mut buf,        )?;        assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, Some(pipeline::Data::Binary { size: 5 }));        assert_eq!(buf.len(), 0, "it should avoid querying that data in the first place");         // On windows, this test fails as it needs the link target to exist, and it was        // hard to make it exist with a relative path, strangely enough.        // For worktree checkouts, this works, that's all that matters for now.        if !cfg!(windows) {            let link_name = "link";            gix_fs::symlink::create(large_content.as_ref(), &tmp.path().join(link_name))?;            let out = filter.convert_to_diffable(                &does_not_matter,                EntryKind::Link,                link_name.into(),                ResourceKind::NewOrDestination,                &mut |_, _| {},                &gix_object::find::Never,                pipeline::Mode::default(),                &mut buf,            )?;             assert!(out.driver_index.is_none());            assert_eq!(                out.data,                Some(pipeline::Data::Buffer { is_derived: false }),                "links are always read and never considered large"            );            assert_eq!(buf.as_bstr(), large_content);        }        drop(tmp);         let db = object_db();        let id = insert(&db, large_content)?;         let out = filter.convert_to_diffable(            &id,            EntryKind::Blob,            a_name.into(),            ResourceKind::OldOrSource,            &mut |_, _| {},            &db,            pipeline::Mode::default(),            &mut buf,        )?;         assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, Some(pipeline::Data::Binary { size: 5 }));        assert_eq!(buf.len(), 0, "it should avoid querying that data in the first place");         Ok(())    }     #[test]    fn non_existing() -> crate::Result {        let tmp = gix_testtools::tempfile::TempDir::new()?;        let mut filter = gix_diff::blob::Pipeline::new(            WorktreeRoots {                old_root: Some(tmp.path().to_owned()),                new_root: None,            },            gix_filter::Pipeline::default(),            vec![],            default_options(),        );         let null = gix_hash::Kind::Sha1.null();        let mut buf = vec![1];        let a_name = "a";        assert!(            !tmp.path().join(a_name).exists(),            "precondition: worktree file doesn't exist"        );        let out = filter.convert_to_diffable(            &null,            EntryKind::Blob,            a_name.into(),            ResourceKind::OldOrSource,            &mut |_, _| {},            &gix_object::find::Never,            pipeline::Mode::default(),            &mut buf,        )?;        assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, None);        assert_eq!(buf.len(), 0, "always cleared");         buf.push(1);        let out = filter.convert_to_diffable(            &null,            EntryKind::Link,            "link".into(),            ResourceKind::OldOrSource,            &mut |_, _| {},            &gix_object::find::Never,            pipeline::Mode::default(),            &mut buf,        )?;        assert!(out.driver_index.is_none());        assert_eq!(out.data, None);        assert_eq!(buf.len(), 0, "always cleared");         drop(tmp);         buf.push(1);        let out = filter.convert_to_diffable(            &null,            EntryKind::Blob,            a_name.into(),            ResourceKind::NewOrDestination,            &mut |_, _| {},            &gix_object::find::Never,            pipeline::Mode::default(),            &mut buf,        )?;         assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, None);        assert_eq!(buf.len(), 0, "it's always cleared before any potential use");         Ok(())    }     #[test]    fn worktree_filter() -> crate::Result {        let tmp = gix_testtools::tempfile::TempDir::new()?;        let filter = gix_filter::Pipeline::new(            Default::default(),            gix_filter::pipeline::Options {                eol_config: eol::Configuration {                    auto_crlf: AutoCrlf::Enabled,                    ..Default::default()                },                ..Default::default()            },        );        let mut filter = gix_diff::blob::Pipeline::new(            WorktreeRoots {                old_root: Some(tmp.path().to_owned()),                new_root: None,            },            filter,            vec![],            default_options(),        );         let does_not_matter = gix_hash::Kind::Sha1.null();        let mut buf = Vec::new();        let a_name = "a";        let a_content = "a-content\n";        std::fs::write(tmp.path().join(a_name), a_content.as_bytes())?;        let out = filter.convert_to_diffable(            &does_not_matter,            EntryKind::Blob,            a_name.into(),            ResourceKind::OldOrSource,            &mut |_, _| {},            &gix_object::find::Never,            pipeline::Mode::default(),            &mut buf,        )?;        assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));        assert_eq!(            buf.as_bstr(),            a_content,            "worktree files are assumed to be filtered already, and are verbatim"        );         let b_name = "b";        let b_content = "a\r\nb";        std::fs::write(tmp.path().join(b_name), b_content.as_bytes())?;        let out = filter.convert_to_diffable(            &does_not_matter,            EntryKind::Blob,            b_name.into(),            ResourceKind::OldOrSource,            &mut |_, _| {},            &gix_object::find::Never,            pipeline::Mode::ToGit,            &mut buf,        )?;        assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));        assert_eq!(            buf.as_bstr(),            "a\nb",            "worktree files are converted back to git if the mode needs it"        );         // On windows, this test fails as it needs the link target to exist, and it's kind of impossible        // to test what we want to test apparently.        if !cfg!(windows) {            let link_name = "link";            let link_content = "hello\n";            gix_fs::symlink::create(link_content.as_ref(), &tmp.path().join(link_name))?;            let out = filter.convert_to_diffable(                &does_not_matter,                EntryKind::Link,                link_name.into(),                ResourceKind::OldOrSource,                &mut |_, _| {},                &gix_object::find::Never,                pipeline::Mode::default(),                &mut buf,            )?;             assert!(out.driver_index.is_none());            assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));            assert_eq!(                buf.as_bstr(),                link_content,                "links aren't put through worktree filters, otherwise it would have its newlines replaced"            );        }        drop(tmp);         let db = object_db();        let b_content = "b-content\n";        let id = insert(&db, b_content)?;         let out = filter.convert_to_diffable(            &id,            EntryKind::Blob,            a_name.into(),            ResourceKind::NewOrDestination,            &mut |_, _| {},            &db,            pipeline::Mode::default(),            &mut buf,        )?;         assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));        assert_eq!(buf.as_bstr(), "b-content\r\n", "LF to CRLF by worktree filtering");         let db = object_db();        let b_content = "b\n";        let id = insert(&db, b_content)?;        let out = filter.convert_to_diffable(            &id,            EntryKind::Blob,            a_name.into(),            ResourceKind::NewOrDestination,            &mut |_, _| {},            &db,            pipeline::Mode::ToGit,            &mut buf,        )?;         assert!(out.driver_index.is_none(), "there was no driver");        assert_eq!(out.data, Some(pipeline::Data::Buffer { is_derived: false }));        assert_eq!(buf.as_bstr(), "b\n", "no filtering was performed at all");         Ok(())    }     #[test]    fn worktree_filter_skips_null_id_lookups() -> crate::Result {        let tmp = gix_testtools::tempfile::TempDir::new()?;        std::fs::write(tmp.path().join("a"), "worktree\r\n")?;        let mut filter = gix_diff::blob::Pipeline::new(            WorktreeRoots {                old_root: None,                new_root: Some(tmp.path().to_owned()),            },            gix_filter::Pipeline::new(                Default::default(),                gix_filter::pipeline::Options {                    eol_config: eol::Configuration {                        auto_crlf: AutoCrlf::Input,                        ..Default::default()                    },                    ..Default::default()                },            ),            vec![],            default_options(),        );        let objects = object_db();        let index_id = insert(&objects, "index\r\n")?;        let mut buf = Vec::new();        for mode in [pipeline::Mode::ToGit, pipeline::Mode::ToGitUnlessBinaryToTextIsPresent] {            for (id, expected) in [                (crate::fixture_hash_kind().null(), "worktree\n"),                (index_id, "worktree\r\n"),            ] {                let objects: &dyn gix_object::FindObjectOrHeader = if id.is_null() {                    &gix_object::find::Never::panic_on_access()                } else {                    &objects                };                let out = filter.convert_to_diffable(                    &id,                    EntryKind::Blob,                    "a".into(),                    ResourceKind::NewOrDestination,                    &mut |_, _| {},                    objects,                    mode,                    &mut buf,                )?;                assert_eq!(                    out.data,                    Some(pipeline::Data::Buffer { is_derived: false }),                    "worktree content remains available for diffing"                );                assert_eq!(                    buf.as_bstr(),                    expected,                    "only a known index object can prevent CRLF normalization"                );            }        }        Ok(())    }     #[test]    fn binary_by_buffer_inspection() -> crate::Result {        let tmp = gix_testtools::tempfile::TempDir::new()?;        let root = crate::scripted_fixture_read_only("make_blob_repo.sh")?;        let mut attributes = crate::blob::new_attributes_stack(root);

Lines 1–500 of 1033.