diff --git a/Cargo.lock b/Cargo.lock
index 4992a1d19..41829a7a7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -19,9 +19,9 @@ dependencies = [
 
 [[package]]
 name = "assert_cmd"
-version = "2.0.2"
+version = "2.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e996dc7940838b7ef1096b882e29ec30a3149a3a443cdc8dba19ed382eca1fe2"
+checksum = "93ae1ddd39efd67689deb1979d80bad3bf7f2b09c6e6117c8d1f2443b5e2f83e"
 dependencies = [
  "bstr",
  "doc-comment",
@@ -109,9 +109,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.0.71"
+version = "1.0.72"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
+checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
 dependencies = [
  "jobserver",
 ]
@@ -134,9 +134,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "clap"
-version = "3.0.4"
+version = "3.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d01c9347757e131122b19cd19a05c85805b68c2352a97b623efdc3c295290299"
+checksum = "12e8611f9ae4e068fa3e56931fded356ff745e70987ff76924a6e0ab1c8ef2e3"
 dependencies = [
  "atty",
  "bitflags",
@@ -151,18 +151,18 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "3.0.2"
+version = "3.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a394f7ec0715b42a4e52b294984c27c9a61f77c8d82f7774c5198350be143f19"
+checksum = "d044e9db8cd0f68191becdeb5246b7462e4cf0c069b19ae00d1bf3fa9889498d"
 dependencies = [
  "clap",
 ]
 
 [[package]]
 name = "clap_derive"
-version = "3.0.2"
+version = "3.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "448c8b00367288ad41804ac7a9e0fe58f2324a36901cb5d6b6db58be86d1db8f"
+checksum = "517358c28fcef6607bf6f76108e02afad7e82297d132a6b846dcc1fc3efcd153"
 dependencies = [
  "heck",
  "proc-macro-error",
@@ -186,13 +186,23 @@ dependencies = [
 
 [[package]]
 name = "crc32fast"
-version = "1.2.1"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
+checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
 dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120"
+dependencies = [
+ "cfg-if",
+ "lazy_static",
+]
+
 [[package]]
 name = "difflib"
 version = "0.4.0"
@@ -217,6 +227,15 @@ version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 
+[[package]]
+name = "fastrand"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2"
+dependencies = [
+ "instant",
+]
+
 [[package]]
 name = "filetime"
 version = "0.2.15"
@@ -256,15 +275,28 @@ checksum = "5ebd3504ad6116843b8375ad70df74e7bfe83cac77a1f3fe73200c844d43bfe0"
 
 [[package]]
 name = "getrandom"
-version = "0.2.3"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
+checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
 dependencies = [
  "cfg-if",
  "libc",
  "wasi",
 ]
 
+[[package]]
+name = "globset"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd"
+dependencies = [
+ "aho-corasick",
+ "bstr",
+ "fnv",
+ "log",
+ "regex",
+]
+
 [[package]]
 name = "hashbrown"
 version = "0.11.2"
@@ -286,11 +318,29 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "ignore"
+version = "0.4.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d"
+dependencies = [
+ "crossbeam-utils",
+ "globset",
+ "lazy_static",
+ "log",
+ "memchr",
+ "regex",
+ "same-file",
+ "thread_local",
+ "walkdir",
+ "winapi-util",
+]
+
 [[package]]
 name = "indexmap"
-version = "1.7.0"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
+checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
 dependencies = [
  "autocfg",
  "hashbrown",
@@ -317,11 +367,20 @@ dependencies = [
  "cfb",
 ]
 
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
 [[package]]
 name = "itertools"
-version = "0.10.1"
+version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
 dependencies = [
  "either",
 ]
@@ -343,9 +402,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.106"
+version = "0.2.112"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
+checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
 
 [[package]]
 name = "libz-sys"
@@ -364,6 +423,15 @@ version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
 
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if",
+]
+
 [[package]]
 name = "lzma-sys"
 version = "0.1.17"
@@ -417,9 +485,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
 
 [[package]]
 name = "once_cell"
-version = "1.8.0"
+version = "1.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
+checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
 
 [[package]]
 name = "os_str_bytes"
@@ -441,6 +509,7 @@ dependencies = [
  "clap_complete",
  "flate2",
  "fs-err",
+ "ignore",
  "indicatif",
  "infer",
  "libc",
@@ -454,7 +523,6 @@ dependencies = [
  "tar",
  "tempfile",
  "test-strategy",
- "walkdir",
  "xz2",
  "zip",
  "zstd",
@@ -488,21 +556,21 @@ dependencies = [
 
 [[package]]
 name = "pkg-config"
-version = "0.3.22"
+version = "0.3.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
+checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.15"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
+checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
 
 [[package]]
 name = "predicates"
-version = "2.0.3"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6ce811d0b2e103743eec01db1c50612221f173084ce2f7941053e94b6bb474"
+checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c"
 dependencies = [
  "difflib",
  "itertools",
@@ -511,15 +579,15 @@ dependencies = [
 
 [[package]]
 name = "predicates-core"
-version = "1.0.2"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
+checksum = "da1c2388b1513e1b605fcec39a95e0a9e8ef088f71443ef37099fa9ae6673fcb"
 
 [[package]]
 name = "predicates-tree"
-version = "1.0.4"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7"
+checksum = "4d86de6de25020a36c6d3643a86d9a6a9f552107c0559c60ea03551b5e16c032"
 dependencies = [
  "predicates-core",
  "termtree",
@@ -551,9 +619,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.32"
+version = "1.0.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
+checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
 dependencies = [
  "unicode-xid",
 ]
@@ -592,9 +660,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
 
 [[package]]
 name = "quote"
-version = "1.0.10"
+version = "1.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
+checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
 dependencies = [
  "proc-macro2",
 ]
@@ -608,7 +676,6 @@ dependencies = [
  "libc",
  "rand_chacha",
  "rand_core",
- "rand_hc",
 ]
 
 [[package]]
@@ -630,15 +697,6 @@ dependencies = [
  "getrandom",
 ]
 
-[[package]]
-name = "rand_hc"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
-dependencies = [
- "rand_core",
-]
-
 [[package]]
 name = "rand_xorshift"
 version = "0.3.0"
@@ -747,9 +805,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "1.0.81"
+version = "1.0.85"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
+checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -758,9 +816,9 @@ dependencies = [
 
 [[package]]
 name = "tar"
-version = "0.4.37"
+version = "0.4.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c"
+checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
 dependencies = [
  "filetime",
  "libc",
@@ -769,13 +827,13 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.2.0"
+version = "3.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
 dependencies = [
  "cfg-if",
+ "fastrand",
  "libc",
- "rand",
  "redox_syscall",
  "remove_dir_all",
  "winapi",
@@ -802,9 +860,9 @@ dependencies = [
 
 [[package]]
 name = "termtree"
-version = "0.2.3"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16"
+checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b"
 
 [[package]]
 name = "test-strategy"
@@ -844,6 +902,15 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "thread_local"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
+dependencies = [
+ "once_cell",
+]
+
 [[package]]
 name = "unicode-xid"
 version = "0.2.2"
@@ -957,18 +1024,18 @@ dependencies = [
 
 [[package]]
 name = "zstd"
-version = "0.9.0+zstd.1.5.0"
+version = "0.9.2+zstd.1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07749a5dc2cb6b36661290245e350f15ec3bbb304e493db54a1d354480522ccd"
+checksum = "2390ea1bf6c038c39674f22d95f0564725fc06034a47129179810b2fc58caa54"
 dependencies = [
  "zstd-safe",
 ]
 
 [[package]]
 name = "zstd-safe"
-version = "4.1.1+zstd.1.5.0"
+version = "4.1.3+zstd.1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c91c90f2c593b003603e5e0493c837088df4469da25aafff8bce42ba48caf079"
+checksum = "e99d81b99fb3c2c2c794e3fe56c305c63d5173a16a46b5850b07c935ffc7db79"
 dependencies = [
  "libc",
  "zstd-sys",
@@ -976,9 +1043,9 @@ dependencies = [
 
 [[package]]
 name = "zstd-sys"
-version = "1.6.1+zstd.1.5.0"
+version = "1.6.2+zstd.1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "615120c7a2431d16cf1cf979e7fc31ba7a5b5e5707b29c8a99e5dbf8a8392a33"
+checksum = "2daf2f248d9ea44454bfcb2516534e8b8ad2fc91bf818a1885495fc42bc8ac9f"
 dependencies = [
  "cc",
  "libc",
diff --git a/Cargo.toml b/Cargo.toml
index f2d9a6a42..2e088e6eb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,11 +24,11 @@ lzzzz = "0.8.0"
 once_cell = "1.8.0"
 snap = "1.0.5"
 tar = "0.4.37"
-walkdir = "2.3.2"
 xz2 = "0.1.6"
 zip = { version = "0.5.13", default-features = false }
 zstd = { version = "0.9.0", default-features = false }
 tempfile = "3.2.0"
+ignore = "0.4.18"
 indicatif = "0.16.2"
 
 [build-dependencies]
diff --git a/src/archive/tar.rs b/src/archive/tar.rs
index 330c950b7..acf0908c4 100644
--- a/src/archive/tar.rs
+++ b/src/archive/tar.rs
@@ -10,13 +10,12 @@ use std::{
 
 use fs_err as fs;
 use tar;
-use walkdir::WalkDir;
 
 use crate::{
     error::FinalError,
     info,
     list::FileInArchive,
-    utils::{self, Bytes},
+    utils::{self, Bytes, FileVisibilityPolicy},
 };
 
 /// Unpacks the archive given by `archive` into the folder given by `into`.
@@ -79,7 +78,12 @@ pub fn list_archive(
 }
 
 /// Compresses the archives given by `input_filenames` into the file given previously to `writer`.
-pub fn build_archive_from_paths<W, D>(input_filenames: &[PathBuf], writer: W, mut display_handle: D) -> crate::Result<W>
+pub fn build_archive_from_paths<W, D>(
+    input_filenames: &[PathBuf],
+    writer: W,
+    file_visibility_policy: FileVisibilityPolicy,
+    mut display_handle: D,
+) -> crate::Result<W>
 where
     W: Write,
     D: Write,
@@ -92,7 +96,7 @@ where
         // Safe unwrap, input shall be treated before
         let filename = filename.file_name().unwrap();
 
-        for entry in WalkDir::new(&filename) {
+        for entry in file_visibility_policy.build_walker(filename) {
             let entry = entry?;
             let path = entry.path();
 
diff --git a/src/archive/zip.rs b/src/archive/zip.rs
index b661358de..147bc51f1 100644
--- a/src/archive/zip.rs
+++ b/src/archive/zip.rs
@@ -9,14 +9,16 @@ use std::{
 };
 
 use fs_err as fs;
-use walkdir::WalkDir;
 use zip::{self, read::ZipFile, ZipArchive};
 
 use crate::{
     error::FinalError,
     info,
     list::FileInArchive,
-    utils::{self, cd_into_same_dir_as, concatenate_os_str_list, get_invalid_utf8_paths, strip_cur_dir, to_utf, Bytes},
+    utils::{
+        self, cd_into_same_dir_as, concatenate_os_str_list, get_invalid_utf8_paths, strip_cur_dir, to_utf, Bytes,
+        FileVisibilityPolicy,
+    },
 };
 
 /// Unpacks the archive given by `archive` into the folder given by `output_folder`.
@@ -119,7 +121,12 @@ where
 }
 
 /// Compresses the archives given by `input_filenames` into the file given previously to `writer`.
-pub fn build_archive_from_paths<W, D>(input_filenames: &[PathBuf], writer: W, mut display_handle: D) -> crate::Result<W>
+pub fn build_archive_from_paths<W, D>(
+    input_filenames: &[PathBuf],
+    writer: W,
+    file_visibility_policy: FileVisibilityPolicy,
+    mut display_handle: D,
+) -> crate::Result<W>
 where
     W: Write + Seek,
     D: Write,
@@ -144,7 +151,7 @@ where
         // Safe unwrap, input shall be treated before
         let filename = filename.file_name().unwrap();
 
-        for entry in WalkDir::new(filename) {
+        for entry in file_visibility_policy.build_walker(filename) {
             let entry = entry?;
             let path = entry.path();
 
diff --git a/src/cli.rs b/src/cli.rs
index 298818167..f8578e64b 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -10,7 +10,7 @@ use clap::Parser;
 use fs_err as fs;
 use once_cell::sync::OnceCell;
 
-use crate::{Opts, QuestionPolicy, Subcommand};
+use crate::{utils::FileVisibilityPolicy, Opts, QuestionPolicy, Subcommand};
 
 /// Whether to enable accessible output (removes info output and reduces other
 /// output, removes visual markers like '[' and ']').
@@ -23,7 +23,7 @@ impl Opts {
     /// And:
     ///   1. Make paths absolute.
     ///   2. Checks the QuestionPolicy.
-    pub fn parse_args() -> crate::Result<(Self, QuestionPolicy)> {
+    pub fn parse_args() -> crate::Result<(Self, QuestionPolicy, FileVisibilityPolicy)> {
         let mut opts = Self::parse();
 
         ACCESSIBLE.set(opts.accessible).unwrap();
@@ -40,7 +40,14 @@ impl Opts {
             (true, true) => unreachable!(),
         };
 
-        Ok((opts, skip_questions_positively))
+        // TODO: change this to be just a single function call?
+        let file_visibility_policy = FileVisibilityPolicy::new()
+            .read_git_exclude(opts.gitignore)
+            .read_ignore(opts.gitignore)
+            .read_git_ignore(opts.gitignore)
+            .read_hidden(opts.hidden);
+
+        Ok((opts, skip_questions_positively, file_visibility_policy))
     }
 }
 
diff --git a/src/commands.rs b/src/commands.rs
index fe96eb70a..57a7e4af4 100644
--- a/src/commands.rs
+++ b/src/commands.rs
@@ -24,7 +24,7 @@ use crate::{
     progress::Progress,
     utils::{
         self, concatenate_os_str_list, dir_is_empty, nice_directory_display, to_utf, try_infer_extension,
-        user_wants_to_continue,
+        user_wants_to_continue, FileVisibilityPolicy,
     },
     warning, Opts, QuestionAction, QuestionPolicy, Subcommand,
 };
@@ -43,7 +43,11 @@ fn represents_several_files(files: &[PathBuf]) -> bool {
 }
 
 /// Entrypoint of ouch, receives cli options and matches Subcommand to decide what to do
-pub fn run(args: Opts, question_policy: QuestionPolicy) -> crate::Result<()> {
+pub fn run(
+    args: Opts,
+    question_policy: QuestionPolicy,
+    file_visibility_policy: FileVisibilityPolicy,
+) -> crate::Result<()> {
     match args.cmd {
         Subcommand::Compress { mut files, output: output_path } => {
             // If the output_path file exists and is the same as some of the input files, warn the user and skip those inputs (in order to avoid compression recursion)
@@ -156,7 +160,8 @@ pub fn run(args: Opts, question_policy: QuestionPolicy) -> crate::Result<()> {
                     formats = new_formats;
                 }
             }
-            let compress_result = compress_files(files, formats, output_file, &output_path, question_policy);
+            let compress_result =
+                compress_files(files, formats, output_file, &output_path, question_policy, file_visibility_policy);
 
             // If any error occurred, delete incomplete file
             if compress_result.is_err() {
@@ -285,6 +290,7 @@ fn compress_files(
     output_file: fs::File,
     output_dir: &Path,
     question_policy: QuestionPolicy,
+    file_visibility_policy: FileVisibilityPolicy,
 ) -> crate::Result<()> {
     // The next lines are for displaying the progress bar
     // If the input files contain a directory, then the total size will be underestimated
@@ -348,6 +354,7 @@ fn compress_files(
             archive::tar::build_archive_from_paths(
                 &files,
                 &mut writer,
+                file_visibility_policy,
                 progress.as_mut().map(Progress::display_handle).unwrap_or(&mut io::stdout()),
             )?;
             writer.flush()?;
@@ -385,6 +392,7 @@ fn compress_files(
             archive::zip::build_archive_from_paths(
                 &files,
                 &mut vec_buffer,
+                file_visibility_policy,
                 progress.as_mut().map(Progress::display_handle).unwrap_or(&mut io::stdout()),
             )?;
             let vec_buffer = vec_buffer.into_inner();
diff --git a/src/error.rs b/src/error.rs
index bf98006f6..34a9c9910 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -172,8 +172,8 @@ impl From<zip::result::ZipError> for Error {
     }
 }
 
-impl From<walkdir::Error> for Error {
-    fn from(err: walkdir::Error) -> Self {
+impl From<ignore::Error> for Error {
+    fn from(err: ignore::Error) -> Self {
         Self::WalkdirError { reason: err.to_string() }
     }
 }
diff --git a/src/main.rs b/src/main.rs
index 97426b2a3..deea33c41 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -28,6 +28,6 @@ fn main() {
 }
 
 fn run() -> Result<()> {
-    let (args, skip_questions_positively) = Opts::parse_args()?;
-    commands::run(args, skip_questions_positively)
+    let (args, skip_questions_positively, file_visibility_policy) = Opts::parse_args()?;
+    commands::run(args, skip_questions_positively, file_visibility_policy)
 }
diff --git a/src/opts.rs b/src/opts.rs
index 182788dc0..e33fbdcc4 100644
--- a/src/opts.rs
+++ b/src/opts.rs
@@ -23,6 +23,14 @@ pub struct Opts {
     #[clap(short = 'A', long, env = "ACCESSIBLE", global = true)]
     pub accessible: bool,
 
+    /// Ignores hidden files
+    #[clap(short = 'H', long)]
+    pub hidden: bool,
+
+    /// Ignores files matched by git's ignore files
+    #[clap(short = 'g', long)]
+    pub gitignore: bool,
+
     /// Ouch and claps subcommands
     #[clap(subcommand)]
     pub cmd: Subcommand,
diff --git a/src/utils/file_visibility.rs b/src/utils/file_visibility.rs
new file mode 100644
index 000000000..f0570bc2c
--- /dev/null
+++ b/src/utils/file_visibility.rs
@@ -0,0 +1,68 @@
+use std::path::Path;
+
+/// Determines which files should be read or ignored during directory walking
+pub struct FileVisibilityPolicy {
+    /// Enables reading .ignore files.
+    ///
+    /// Disabled by default.
+    pub read_ignore: bool,
+
+    /// If enabled, ignores hidden files.
+    ///
+    /// Disabled by default
+    pub read_hidden: bool,
+
+    /// Enables reading .gitignore files.
+    ///
+    /// This is enabled by default.
+    pub read_git_ignore: bool,
+
+    /// Enables reading `.git/info/exclude` files.
+    pub read_git_exclude: bool,
+}
+
+impl Default for FileVisibilityPolicy {
+    fn default() -> Self {
+        Self { read_ignore: false, read_hidden: true, read_git_ignore: false, read_git_exclude: false }
+    }
+}
+
+impl FileVisibilityPolicy {
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    #[must_use]
+    /// Enables reading .ignore files.
+    pub fn read_ignore(self, read_ignore: bool) -> Self {
+        Self { read_ignore, ..self }
+    }
+
+    #[must_use]
+    /// Enables reading .gitignore files.
+    pub fn read_git_ignore(self, read_git_ignore: bool) -> Self {
+        Self { read_git_ignore, ..self }
+    }
+
+    #[must_use]
+    /// Enables reading `.git/info/exclude` files.
+    pub fn read_git_exclude(self, read_git_exclude: bool) -> Self {
+        Self { read_git_exclude, ..self }
+    }
+
+    #[must_use]
+    /// Enables reading `.git/info/exclude` files.
+    pub fn read_hidden(self, read_hidden: bool) -> Self {
+        Self { read_hidden, ..self }
+    }
+
+    /// Walks through a directory using [`ignore::Walk`]
+    pub fn build_walker(&self, path: impl AsRef<Path>) -> ignore::Walk {
+        ignore::WalkBuilder::new(path)
+            .git_exclude(self.read_git_exclude)
+            .git_ignore(self.read_git_ignore)
+            .ignore(self.read_ignore)
+            .hidden(self.read_hidden)
+            .build()
+    }
+}
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
index e3dde097b..78fb2a9f4 100644
--- a/src/utils/mod.rs
+++ b/src/utils/mod.rs
@@ -4,10 +4,12 @@
 //! stdin interaction helpers.
 
 pub mod colors;
+mod file_visibility;
 mod formatting;
 mod fs;
 mod question;
 
+pub use file_visibility::FileVisibilityPolicy;
 pub use formatting::{concatenate_os_str_list, nice_directory_display, strip_cur_dir, to_utf, Bytes};
 pub use fs::{
     cd_into_same_dir_as, clear_path, create_dir_if_non_existent, dir_is_empty, is_symlink, try_infer_extension,