1

I can test if the current directory like this:

[[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == true ]] && echo yes

..but how can I do the same for a directory that is not the current working directory?

3 Answers 3

2

Just use the -C global option to git. Doing this, and simplifying your code (why would you parse the output to reconstruct information that's directly encoded in the return status?):

directory=. # or wherever
if git -C "$directory" rev-parse --is-inside-work-tree >/dev/null 2>/dev/null; then
  echo yes
fi
6
  • I don't know what you mean by your question, but I would like to understand. Is using an if statement more efficient?
    – paradroid
    Commented Apr 8, 2021 at 21:14
  • 1
    @paradroid It's slightly more efficient, but more importantly it's easier to understand. Because it's doing strictly less work. Commented Apr 8, 2021 at 21:34
  • @paradroid in the general case the approach is potentially infinitely more efficient, because capturing output is O(size_of_output) memory cost for the shell while checking the exit status is O(1).
    – mtraceur
    Commented Oct 2, 2023 at 12:37
  • In fact, the OS could optimize so that writes to /dev/null skip copying bytes from user-space to kernel-space, and I'm pretty sure modern OSs actually do this... in theory it could be optimized to the point that you don't even pay the system call overhead for those writes (implementation left as exercise to reader, but consider how Linux makes current time checking efficient by writing to a memory page mapped readable into the process... perhaps also consider repurposing the fast path of a futex).
    – mtraceur
    Commented Oct 2, 2023 at 12:52
  • Also in theory, a program can detect stdout is /dev/null, and not even allocate or write to any of the memory it would normally use for writes, or bypass any other relevant code paths. For git rev-parse specifically, the gains of any such optimization would be negligible because it's writing out, like, 5-6 bytes. But like I said, in the general case (in other arbitrary situations where you could either check output or exit status) the approach could be a significant efficiency gain.
    – mtraceur
    Commented Oct 2, 2023 at 12:59
1

I suspect the simplest option is to change to the directory, temporarily:

(cd /path/to/target && [[ $(git rev-parse --is-inside-work-tree) == true ]]) 2> /dev/null && echo yes
1

I would do it with a function that moves to the target directory, runs the command there and returns the result:

isGitDIr(){
    for dir in "$@"; do
    ( 
        cd "$dir" || return
        [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == true ]] && 
        echo "yes"
    )
    done
}

The parentheses make the commands run in a subshell so that when the function finishes, you haven't changed the directory of the parent shell. Add the lines to your shell's initialization file (e.g. ~/.bashrc) or paste directly into your terminal, and you can do:

isGitDIr /path

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .