Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I use something even simpler

My dotfiles git repo is meant to be cloned in my home directory. It comes with this .gitignore committed in the repo:

  /*
  !/.vim/
  /.vim/.netrwhist
Basically it ignores everything in my home directory, unless I explicitly `git add` it, which matches my workflow. For the few cases where I want to notice changes (like the entire ~/.vim/ subdirectory), I explicitly un-ignore it as you can see above.

The only downside I've experienced is my bash PS1 prompt shows the status of the dotfiles repo (branch/dirty/etc) in any directory I'm in that's inside my home dir - I've learnt to ignore it, and it doesn't interfere with CDing into an actual directory that's its own git repo.



That's clever, thanks for sharing this technique!

In the past I wrote a bash setup script for my dotfiles repository which pretty much does the opposite, symlinking a combination of shared and os-specific directories and files into my home dirs. One definite advantage with your technique is that no special setup script is required. I'm thinking I can obviate the need for splitting ommon and os-specific dirs by just detecting when the OS is Linux or macOS within the scripts themselves and using an if statement to gate their execution or sourcing.

This concept is related to another HN personal favorite of mine: "Best thing in your bash_profile / aliases" [0]. Lots of interesting command-line shell optimization and slick hack ideas in there.

Thanks again for showing me a superior way :)

[0] https://news.ycombinator.com/item?id=18898523


i do the same (dotfiles with symlinking script) and it’s mostly great, but I’d recommend against os-specific switching in the scripts and files themselves. it’s the way i’d always done it previously but i switched to git-branch-per-system and it’s much better. the problems started when “chromebook linux” was different than “other laptop linux” and then “server linux” (not to mention os x) and there kept being more and more messy logic. separate git branches is way easier and has the benefit of a sort of “inheritance” of the shared stuff (branching and rebasing)


I think that method requires git to scan all the files in the directory so it can then ignore them. The advantage of the “showUntrackedFiles no” method is that git will only look at the tracked files, which is much faster if you have a million files in your home dir, like I do. (Or so I believe.)


I tried quickly looking into this to verify the claim, but haven't yet found anything to explain why this would be the case. Do you have any details about how or why git will scan everything in this case?

I did find a pretty neat stack overflow post on the subject of gitignore whitelisting [0]. If we can get to the bottom of possible performance impact, would be cool to add the info there.

[0] https://stackoverflow.com/a/15320746/293064


Without spending too much time on it, I think a cursory check shows git doing "the smart thing" with ignore rules.

  $ mkdir foo
  $ cd foo
  $ mkdir $(seq 1 1000)
  $ git init .
  $ strace -c git status
    On branch master

    No commits yet

    nothing to commit (create/copy files and use "git add" to track)
    % time     seconds  usecs/call     calls    errors syscall
    ------ ----------- ----------- --------- --------- ----------------
     75.97    0.058830          57      1035        15 openat
     16.48    0.012764           6      2002           getdents
      3.87    0.002999           3      1021           close
      2.91    0.002254           2      1022           fstat
      0.19    0.000147           8        18        14 lstat
      0.13    0.000100           4        24           read
      0.12    0.000092           6        16        12 stat
      0.09    0.000072           3        21        14 access
      0.06    0.000048          10         5           write
      0.04    0.000033          33         1           unlink
      0.03    0.000020           3         8           rt_sigaction
      0.02    0.000018           2        12           mprotect
      0.02    0.000015          15         1           munmap
      0.01    0.000010           3         4           getcwd
      0.01    0.000006           0        16           mmap
      0.01    0.000006           6         1           ioctl
      0.01    0.000005           2         3           brk
      0.01    0.000004           4         1           chdir
      0.00    0.000003           2         2           getpid
      0.00    0.000003           3         1         1 readlink
      0.00    0.000002           1         2           rt_sigprocmask
      0.00    0.000002           2         1           set_tid_address
      0.00    0.000002           2         1           set_robust_list
      0.00    0.000002           2         1           prlimit64
      0.00    0.000000           0         1           execve
      0.00    0.000000           0         1           arch_prctl
    ------ ----------- ----------- --------- --------- ----------------
    100.00    0.077437                  5221        56 total
Now let's add an ignore-all and check:

  $ echo "/*" > .gitignore
  $ strace -c git status
    On branch master

    No commits yet

    nothing to commit (create/copy files and use "git add" to track)
    % time     seconds  usecs/call     calls    errors syscall
    ------ ----------- ----------- --------- --------- ----------------
     46.25    0.000568         284         2           getdents
     16.78    0.000206           6        35        14 openat
      7.41    0.000091           6        16        12 stat
      7.17    0.000088           4        21        14 access
      5.62    0.000069           3        25           read
      4.72    0.000058           3        18        14 lstat
      4.15    0.000051           2        22           close
      2.93    0.000036          36         1           unlink
      2.28    0.000028           1        23           fstat
      0.81    0.000010           3         4           getcwd
      0.65    0.000008           1         8           rt_sigaction
      0.41    0.000005           5         1           ioctl
      0.33    0.000004           4         1           chdir
      0.24    0.000003           2         2           getpid
      0.24    0.000003           3         1         1 readlink
      0.00    0.000000           0         5           write
      0.00    0.000000           0        16           mmap
      0.00    0.000000           0        12           mprotect
      0.00    0.000000           0         1           munmap
      0.00    0.000000           0         3           brk
      0.00    0.000000           0         2           rt_sigprocmask
      0.00    0.000000           0         1           execve
      0.00    0.000000           0         1           arch_prctl
      0.00    0.000000           0         1           set_tid_address
      0.00    0.000000           0         1           set_robust_list
      0.00    0.000000           0         1           prlimit64
    ------ ----------- ----------- --------- --------- ----------------
    100.00    0.001228                   224        55 total


Apparently either I’m remembering an ancient and fixed git behavior, or I’m just totally wrong. Either way, awesome, this is much simpler!


You can use the `git check-ignore` command to check if a certain directory is ignored. I used it in my zsh config to suppress the status of ignored directories in my prompt.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: