Reputation: 42697
I am writing a series of scripts for Git management in zsh.
How do I check if the current directory is a Git repository? (When I'm not in a Git repo, I don't want to execute a bunch of commands and get a bunch of fatal: Not a git repository
responses).
Upvotes: 353
Views: 215143
Reputation: 1329092
While William Pursell's 2010 answer is about two states (in a valid git repository or not), a git rev-parse --is-inside-work-tree
is actually more detailed, as illustrated with Git 2.46 (Q3 2024), batch 8:
See commit d424488 (01 May 2024) by Junio C Hamano (gitster
).
(Merged by Junio C Hamano -- gitster
-- in commit 3acecc0, 28 May 2024)
rev-parse
: document how--is-*
options work outside a repository
When "
git rev-parse
"(man) is run with the--is-inside-work-tree
option and friends outside a Git repository, the command exits with a non-zero status and says "fatal: not a repository
".While it is not wrong per-se, in the sense that it is useless to learn if we are inside or outside a working tree in the first place when we are not even in a repository, it could be argued that they should emit "false" and exit with status 0, as they cannot possibly be "true".
As the current behaviour has been with us for a decade or more since it was introduced in Git 1.5.3 timeframe, it is too late to change it.
And arguably, the current behaviour is easier to use if you want to distinguish among three states, i.e.,
- the
cwd
is not controlled by Git at all- the
cwd
is inside a working tree- the cwd is not inside a working tree (e.g.,
.git/hooks/
)with a single invocation of the command by doing
if inout=$(git rev-parse --is-inside-work-tree) then case "$inout" in true) : in a working tree ;; false) : not in a working tree ;; esac else : not in a repository fi
So, let's document clearly that the command will
die()
when run outside a repository in general, unless in some special cases like when the command is in the--parseopt
mode.While at it, update the introductory text that makes it sound as if the primary operating mode is the only operating mode of the command, which was written long before we added "
--parseopt
" and "--sq-quote
" modes.
git rev-parse
now includes in its man page:
Unless otherwise specified, most of the options and operation modes require you to run this command inside a git repository or a working tree that is under the control of a git repository, and will give you a fatal error otherwise. [...] The command in this mode can be used outside a repository or a working tree controlled by a repository.
Upvotes: 1
Reputation: 21
simple use any of the git commands like git branch or on linux machine if u want to search everywhere for .git file to know git folder use these command sudo find / -type d -name ".git"
Upvotes: 0
Reputation: 4298
Why not using exit codes? If a git repository exists in the current directory, then git branch
and git tag
commands return exit code of 0 (even if there are no tags or branches); otherwise, a non-zero exit code will be returned. This way, you can determine if a git repository exist or not. Simply, you can run:
git tag > /dev/null 2>&1
Advantage: Portable. It works for both bare and non-bare repositories, and in sh, zsh and bash.
git tag
: Getting tags of the repository to determine if exists or not.> /dev/null 2>&1
: Preventing from printing anything, including normal and error outputs.check-git-repo
As an example, you can create a file named check-git-repo
with the following contents, make it executable and run it:
#!/bin/sh
if git tag > /dev/null 2>&1; then
echo "Repository exists!";
else
echo "No repository here.";
fi
Upvotes: 9
Reputation: 31
This questions is really old, and there are some nice answers.
Yet there is missing one thing: The solution how it is handled by git itself inside it's git-prompt.sh
with __git_ps ()
.
Here is the snippet taken from there:
# [...]
local repo_info rev_parse_exit_code
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
--is-bare-repository --is-inside-work-tree \
--short HEAD 2>/dev/null)"
rev_parse_exit_code="$?"
if [ -z "$repo_info" ]; then
return $exit
fi
local short_sha=""
if [ "$rev_parse_exit_code" = "0" ]; then
short_sha="${repo_info##*$'\n'}"
repo_info="${repo_info%$'\n'*}"
fi
# [...]
This is pretty nice, as it seems to handle all the mentioned issues to the other answers given here. Simply by combining the already known parameters in one call of git rev-parse
.
Maybe this script (git-prompt.sh
with __git_ps ()
) wasn't available 13 years ago, when this question was asked, but I thought it could be still interesting for people who want to create their own ps1.
Upvotes: 2
Reputation: 111127
You can use:
git rev-parse --is-inside-work-tree
Which will print 'true' to STDOUT if you are in a git repos working tree.
Note that it still returns output to STDERR if you are outside of a git repo (and does not print 'false').
Taken from this answer: https://stackoverflow.com/a/2044714/12983
Upvotes: 288
Reputation: 1716
##Current branch
echo $(git branch --show-current 2> /dev/null && echo '')
echo $(git branch --show-current 2> /dev/null)
##OR
GIT_DIR=$(git rev-parse --git-dir 2> /dev/null)
Upvotes: 0
Reputation: 36106
Based on @Alex Cory's answer:
[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]
doesn't contain any redundant operations and works in -e
mode.
git rev-parse
succeeding, ignoring its output.
git
commands are only valid inside a worktree. So for scripting purposes, you're most likely interested in being not just inside a "git repo" but inside a worktree.Upvotes: 22
Reputation: 212634
Use git rev-parse --git-dir
if git rev-parse --git-dir > /dev/null 2>&1; then
: # This is a valid git repository (but the current working
# directory may not be the top level.
# Check the output of the git rev-parse command if you care)
else
: # this is not a git repository
fi
edit: git-rev-parse
now (as of 1.7.0) supports --show-toplevel
, so you could do if test "$(pwd)" = "$(git rev-parse --show-toplevel)"
to determine if the current directory is the top-level dir.
Upvotes: 76
Reputation: 546
This works for me. You still get the errors but they're easy enough to suppress. it also works from within subfolders!
git status >/dev/null 2>&1 && echo Hello World!
You can put this in an if then statement if you need to conditionally do more.
Upvotes: 3
Reputation: 2714
Copied from the bash completion file, the following is a naive way to do it
# Copyright (C) 2006,2007 Shawn O. Pearce <[email protected]>
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
# Distributed under the GNU General Public License, version 2.0.
if [ -d .git ]; then
echo .git;
else
git rev-parse --git-dir 2> /dev/null;
fi;
You could either wrap that in a function or use it in a script.
Condensed into a one line condition suitable for bash and zsh
[ -d .git ] && echo .git || git rev-parse --git-dir > /dev/null 2>&1
Upvotes: 217
Reputation: 61
# check if git repo
if [ $(git rev-parse --is-inside-work-tree) = true ]; then
echo "yes, is a git repo"
git pull
else
echo "no, is not a git repo"
git clone url --depth 1
fi
Upvotes: 3
Reputation: 2308
This answer provides a sample POSIX shell function and a usage example to complement @jabbie's answer.
is_inside_git_repo() {
git rev-parse --is-inside-work-tree >/dev/null 2>&1
}
git
returns errorlevel 0
if it is inside a git repository, else it returns errorlevel 128
. (It also returns true
or false
if it is inside a git repository.)
Usage example
for repo in *; do
# skip files
[ -d "$repo" ] || continue
# run commands in subshell so each loop starts in the current dir
(
cd "$repo"
# skip plain directories
is_inside_git_repo || continue
printf '== %s ==\n' "$repo"
git remote update --prune 'origin' # example command
# other commands here
)
done
Upvotes: 9
Reputation: 11875
Or you could do this:
inside_git_repo="$(git rev-parse --is-inside-work-tree 2>/dev/null)"
if [ "$inside_git_repo" ]; then
echo "inside git repo"
else
echo "not in git repo"
fi
Upvotes: 37
Reputation:
Another solution is to check for the command's exit code.
git rev-parse 2> /dev/null; [ $? == 0 ] && echo 1
This will print 1 if you're in a git repository folder.
Upvotes: 7
Reputation: 255
Not sure if there is a publicly accessible/documented way to do this (there are some internal git functions which you can use/abuse in the git source itself)
You could do something like;
if ! git ls-files >& /dev/null; then
echo "not in git"
fi
Upvotes: 10