Image of fatal: not a git repository (or any of the parent directories): .git

ADVERTISEMENT

Introduction

Working with Git can be a joy, until it isn't. Suppose you're working on your project at a nice pace, you've created a branch, doing regular commits and a dozen other things. Then you're not exactly sure what you did last, but Git isn't liking it. Suddenly, you're faced with the nondescript error message:

fatal: not a git repository (or any of the parent directories): .git

In this article, we'll discuss the reasons for the error fatal: not a git repository (or any of the parent directories): .git and how to fix it.

Why Am I Seeing This Error?

The fact that the error received is a "Git error" means that Git is installed on the local system, and that the executable is accessible on the local path. This typically rules out an installation issue as being the problem.

What the error is telling you is that you issued a Git command, (usually within a command line shell), inside a directory that isn't part of a Git repository, or isn't recognized as one. Essentially, the directory you ran the Git command in is not tracked by Git, so Git can’t perform the requested action such as git status, git add, git commit, etc.

Git determines whether you're in a Git repository by looking for a specific hidden folder in the current directory, or one of its parents. This folder is aptly named, .git. If present, this folder should be in the root of your project tree. If Git can't locate this folder from the directory you issued the Git command in, it will throw the above error.

There are a few scenarios that commonly lead to this issue:

  1. Most likely: You need a little help setting up a new local repository, or cloning an existing one.
  2. Somewhat likely: You need help locating an existing Git repository on your local machine.
  3. Pretty unlikely: You deleted your entire Git repository or just the .git folder at the root of your project.
  4. Unlikely: Somehow the state of your local repository got corrupted.

Let's discuss each of these in turn.

Setting Up A New Repository

Before you can successfully run most of Git's commands, you need to create and navigate into a Git repository.

You may have a project folder already created, perhaps with sources already present, or you may be starting fresh and need to create a brand new project folder.

In either case, open your preferred command shell (cmd on Windows, bash on unix-like systems, or Terminal on your Mac) and follow these steps:

  • If you're starting fresh, create a new folder for your project.
  • Then cd into your newly created, or already present, project folder - you want to be at the root of your project's folder tree.
  • From within this folder enter the command: git init

That's it. very simple. You should see some output like the following:

$ mkdir my-project  # If creating a new folder.
$ cd my-project
$ git init

Initialized empty Git repository in /home/me/projects/my-project/.git/

If you have existing sources you can add them to the repository using the git add and git commit commands. git add "stages" (or prepares) any changes you've made to files in your repository for a check in. To check in, or in version control vernacular, to commit these changes, you issue the git commit command along with a brief commit message describing what modifications are being committed.

The commands with the output should look something like the following:

$ git add .
$ git commit -m "Initial commit"

[master (root-commit) 0879183] initial commit
 21 files changed, 4630 insertions(+)
 create mode 100644 LICENSE-MIT
 create mode 100644 README.md
           :
           :

Each time you make a commit, the repository keeps information on the state of your files - a sort of snapshot. And it's good practice to do a commit on any significant change to any of your files. A clean commit history can be very useful to you as you learn more about Git's version control capabilities.

Cloning An Existing Repository

If you are not starting a new project, but instead joining an existing project, you will need to clone (download and copy) that repository to your local machine.

Cloning an existing repository is a very simple operation using the git clone command. You should have a URL to the remote repository; or if cloning locally, you should have a file system path to the repository folder or share. For instance, let's say we want to grab a project from GitHub.

GitHub has training projects that users can access to safely experiment with. So let's use one such training project called Spoon-Knife whose URL is https://github.com/octocat/Spoon-Knife. All we need to do to download/copy the files for the project is issue the git clone command like so:

$ git clone https://github.com/octocat/Spoon-Knife

Cloning into 'Spoon-Knife'...
remote: Enumerating objects: 16, done.
remote: Total 16 (delta 0), reused 0 (delta 0), pack-reused 16
Unpacking objects: 100% (16/16), 2.24 KiB | 458.00 KiB/s, done.

After navigating into the Spoon-Knife folder, you can now issue the git status command (or any other Git command), and the error message you saw earlier shouldn't occur for this local repository. You should see something like the following:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

That's all there is to retrieving the sources and creating a local repository. Very simple.

Locating An Existing Repository

If you know that you previously had a local project folder that was successfully being tracked using Git, you may just need to manually (visually) verify whether the current directory holds the hidden .git folder, you can issue the following commands.

Unix-like systems:

$ ls -a

Windows:

C:...> dir /d

Each command with the additional parameter lists the hidden folders in addition to the visible folders. You can issue cd .. to navigate back through each of the parent folders in turn, also checking them for the hidden .git folder.

If you are on Unix/Linux and still have no clue where the hidden .git folder might be, you can use the Linux find command to track it down by doing a system-wide search.

Unix-like systems:

$ find / -type d -name ".git"

./projects/emoji_chat/.git
./projects/python_projects/web_scraper/.git
./projects/python_projects/experiments/.git

The / specifies the path of the folder find will start from as it recursively descends into child folders looking for any .git directories. The above will start the search from your system's root directory. You can replace this with whatever path you feel is appropriate.

The -type d option will specifically search for directories, and the -name ".git" option will only list those named .git.

On Windows, you can use the file explorer to search, but make sure it's configured to show hidden folders.

Have Sources But No .git Folder

This section covers the case where you have the sources to a project that has a Git repository, but for whatever reason don't have the .git folder. This isn't an uncommon problem. Maybe you downloaded the sources for a project in a compressed archive that didn't include the version control files, or you did have the .git folder at one point but for whatever reason deleted it.

If you haven't made modifications to the sources, you can opt to clone a fresh local copy of the project.

If you've modified the sources and want to add your changes to the repository, a simple strategy is to clone the project into a new project folder, then copy the files you modified over their counterparts in the new tree.

It's a good idea to compare your version of the affected files with their counterparts. Otherwise you could be overwriting recent changes made by other developers. If you skip that step and commit your overwritten files, Git will assume any differences between these files and and the version of them last checked in are changes you intentionally made - it doesn't know the difference.

One approach is to do a side-by-side comparison in your editor of choice if the changes are minor, and cut/paste the changes in. Or you can use the diff features of your IDE or other tools you're familiar with, such as the git diff command.

Another option, and probably the best in most cases, is to create a new branch in the project repository, copy your files over the new branch's files, then merge the new branch with the master branch (or whichever branch you plan on updating). The examples below will assume you chose the master branch to merge to.

For any given Git repository, there is one main branch, the name of it can vary, but for the majority of projects it's named master, but is also sometimes named main. You can use the git branch command from within your project directory to get a listing of your branch names.

To create and switch to a new branch, issue the following commands in the shell:

$ git status
On branch master
      :
$ git checkout -b my-changes
Switched to a new branch 'my-changes'

The output of the last command indicates we successfully created a new branch called my-changes and switched to the new branch in our working directory. Now copy your modified files over the files in the repository. Copying over the files is safe, changes we make to this new branch won't affect the master branch for now. After copying over the files, issue the following commands to commit the changes and switch back to the master branch.

$ git commit -a -m "Copied over files."

[temp 64295f3] Copied over files.
 1 file changed, 6 insertions(+)

$ git checkout master

Switched to branch 'master'
Your branch is up to date with 'origin/master'.

The first command above committed the files we overwrote, and the second command switched the repository back to the master branch. If you were to look at the files again, you'd see that they reverted to their original state from before we copied over them. If you were to switch back to the my-changes branch, you'd see the copied over versions.

Now we'll interactively merge the changes from my-changes into master. Issue the following command to begin the process.

git checkout -p my-changes --

The interactive merge utility will display the changes to be approved in small blocks with the code being replaced above the code replacing it. You can have the utility break its currently displayed block into smaller pieces for approval with the "s" option - if displayed.

$ git checkout -p my-changes --

diff --git b/index.html a/index.html
index a83618b..cf2b938 100644
--- b/index.html
+++ a/index.html
@@ -16,5 +16,11 @
    :
-<img src="my-dog.jpg" id="pet-pic" alt="" />
    :
+<img src="my-cat.jpg" id="pet-pic" alt="" />
    :

(1/1) Apply this hunk to index and worktree [y,n,q,a,d,e,?]?

In the output above, lines that are to be removed are preceded by a "-", and lines to be added added preceded by a "+". To get a listing of what the options mean, enter "?" at the prompt.

Some of the useful options are:

  • ? - help on the available options.
  • n - reject the currently displayed block's changes.
  • y - accept the current block.
  • s - break the current block into smaller pieces.
  • e - edit the current block in the terminal's graphical editor.

Once you're done with your interactive session, you'll have merged your changes in while preserving any changes submitted by others. The sources are now ready to be checked in to the repository.

The merge utility doesn't automatically commit the changes. It only modifies the work files, which should be ready for commit after you've run it and carefully selected the changes to include.

The above process assumes you want to merge changes into the master branch, but you could just as well have merged into another branch you created, or checked out.

Something Is Wrong Within An Existing .git Directory

This is an uncommon problem, but fixable. The good news is you almost certainly won't have to go into the .git folder and hack things manually.

It's a wise decision to make a copy of the project tree before doing anything else, so if something goes wrong you won't lose the current state of your source files.

Generally, to verify something went awry in a .git repository, you can issue the git fsck command to get a report on what the problem may be. However, if you were getting this article's error message, that's all you're likely to see in this specific case.

$ git fsck

fatal: not a git repository (or any of the parent directories): .git

If you run it, you'll likely see the error message that brought you here in the first place. Checking the .git folder you should see the following.

$ ls .git

branches        config       FETCH_HEAD  hooks  info  objects    refs
COMMIT_EDITMSG  description  HEAD        index  logs  ORIG_HEAD

When a repository is broken, it can be hard to detect an obvious cause of the problem unless you have some in-depth experience with Git and the files it maintains, but it doesn't hurt to give a quick visual inspection of the .git folder in case there's an obvious cause, such missing files.

Anyway, you have a confirmed problem that needs fixing. There's an application that may be able to fix the repository automatically for you called git-repair. This is a fairly comprehensive tool that fixes a wide range of issues.

First, confirm whether the tool is already installed or not by trying to invoke it with the help flag: git-repair --help. If it's there you should see the help text displayed and you can skip the installation steps.

Information on the tool can be found on the git-repair home page, or the Haskell package repository for git-repair.

If you're using Linux, this tool may be available via a package manager like apt. You can try the following command to see if that's the case.

sudo apt-get update
sudo apt-get install git-repair

If it's not available that way, you can follow the simple instructions on the tool's home page to install the Haskell platform and build the tool for your system.

Once you have the tool installed, you can give it a run.

$ git-repair
Running git fsck ...
No problems found.

In the example above, the tool ran and then reported there were no problems. That doesn't mean it didn't do anything. Now if you run git fsck again you should see some encouraging information displayed instead of the fatal: not a git repository... message. It should look something like the following.

$ git fsck

Checking object directories: 100% (256/256), done.
notice: HEAD points to an unborn branch (master)

In the above example, it looks like the tool has done a somewhat good job at recovering what may have felt to be a dire situation at first. The notice message above is indicating that HEAD is pointing to the wrong place. HEAD is simply a file with the one line of text indicating which branch we're currently working on. Minor problems like this aren't difficult to fix.

Continuing with the above example, let's try switching to the 'master' branch.

$ git switch master

error: The following untracked working tree files would be overwritten by checkout:
	README.md
	index.html
	styles.css
Please move or remove them before you switch branches.
Aborting

So the error message is telling us to move or remove the listed files to ensure we don't lose any work. So let's remove these files and then switch back to the branch we were working on, which was 'master' in the example.

$ rm README.md 
$ rm index.html 
$ rm styles.css 

$ git switch master

Switched to branch 'master'
Your branch is up to date with 'origin/master'.

$ ls

backup  git-repair  index.html  README.md  styles.css

Now the repository is recovered, and in this particular case we can copy the files back over. This should be fine because the files were restored from the local repository and should be current minus some changes that hadn't been checked in yet.

Summary

In this article, we discussed several reasons for the error fatal: not a git repository (or any of the parent directories): .git and how to fix them.

We've covered quite a few scenarios, and if you've read along you should have some new tools in your tool case. Git is a great version control tool, and it can be very useful, not only for work or project contributions, but also for any personal projects you have on your system that you want to maintain a change history for that you can refer to, create experimental branches while preserving the work in others, revert to previous versions of files, etc.

Next Steps

I find it's very useful to have a cheat sheet for command line applications like Git. We've written several cheat sheets to help users with different levels of coding experience. The simplest is the beginner Git cheat sheet, followed by the intermediate Git cheat sheet, and lastly the expert Git cheat sheet.

If you're interested in learning more about how Git works under the hood, check out our Baby Git Guidebook for Developers, which dives into Git's code in an accessible way. We wrote it for curious developers to learn how Git works at the code level. To do this we documented the first version of Git's code and discuss it in detail.

Thanks and happy coding! We hope you enjoyed this article. If you have any questions or comments, feel free to reach out to jacob@initialcommit.io.