12

Can git repositories be created inside the folder that is being version-controlled, or should the repository be placed outside that folder? Or is either possible? Does the repository location matter?

user2514157
  • 545
  • 6
  • 24
David Rhoden
  • 913
  • 5
  • 15
  • 30

6 Answers6

18

Adding a sixth answer might be a bit futile at this point, but I wrote something like this for a tutorial and I think it's important that an answer to this question clearly explains the standard layout of bare and non-bare repositories.

Usually with git you will be using a non-bare repository, or a repository with a working tree. By default, the directory that contains a .git directory will be at the top level of your working tree for that repository. For example, if you’ve created such a repository in a directory called toaster-simulator, then the directory structure might look like:

toaster-simulator/
    .git/
        HEAD
        config
        index
        objects/
        refs/
        ...
    README
    Makefile
    src/
        toaster.c

There is only one .git directory at the top level of your repository.1 This directory contains the entire history of your repository, all its branches, the objects that make up every file of every commit in your history, etc. (For example, the .git/objects directory contains the database that maps object names to files, commits, and so on; HEAD points to your current branch; etc.) You should never manually delete or change files in this directory, or you will risk corrupting your repository. Everything outside the .git directory is your working tree. You would just edit these files as normal when developing your project.

Perhaps the most surprising thing to people who are new to git is that if you switch from one branch to another, the files in your working tree may completely change. Although this may be alarming the first time you see it, this is a great feature - you almost never need to have more than one copy of a repository on your computer, since switching from one branch to another is so fast and easy. (To stop you from losing data, git will prevent you from switching branches like this if you have changes in your working tree that haven’t been recorded in a commit, and those changes are in files that would be altered in any way by the switch of branch. Once you have created a commit with your files at a particular state, git makes it very difficult for you to lose those files.)

The other type of repository is a bare repository, which is essentially like the .git directory but without a working tree. You would typically use this for a repository that many people will be pushing their changes to - you won’t be developing on this repository, so the working tree would just get in the way. Conventionally you would name the directory that contains the bare repository with the project name and the .git extension. For example, on a remote server you might have a bare repository for the toaster-simulator project that looks like this:

toaster-simulator.git/
    HEAD
    config
    index
    objects/
    refs/
    ...

When you’re first using git, you probably won’t need to use bare repositories, but it’s good to be aware of them. When you ask in your question about being able to have repositories outside your working tree, they might well be bare repositories that you're using to share code with other people.

I've described above the conventional repository layout, but in fact the git directory and the working tree can be any two directories on your filesystem, if you use certain environment variables or options to git - however, that's beyond basic git usage :)

Footnotes

1 In fact it is possible to have nested repositories, each with their own .git directory, using git's submodule feature, for example. However, given your question, you shouldn't need to worry about that for the moment.

Mark Longair
  • 446,582
  • 72
  • 411
  • 327
  • Not futile at all, and I'm accepting it as the answer. My confusion probably came from trying to go too fast: I had (per MediaTemple's instructions) created a bare repository, outside of my root folder, to push to a remote server where I would be pushing changes from my local repository. I thought that was also the repository on my local machine. Now that that bare repo has been pushed to the remote server, I can just delete it from my local machine, if I'm not mistaken. Thanks for taking the time to explain the details. – David Rhoden Apr 01 '11 at 13:52
5

The git repo is created in the same location as your source code. Remember that git is not like Subversion where you have a single repository at a central location (on a server, for example). Instead, your source code directory is your git repo, like this:

$ cd mysources
$ git init . 
$ git add ...

Now mysources/.git will contain the git object database, and you can add/commit/branch/etc.

JesperE
  • 63,317
  • 21
  • 138
  • 197
  • So, to contrast this answer with Darhuuk's, if I create the repo in my root folder, it will work normally, but if I create the repo outside of the root folder, it would also work, but it will make a separate copy of the source code? – David Rhoden Apr 01 '11 at 09:17
  • You don't create it outside your source folder, period. You can "clone" the repo if you want a separate copy of the repo, but that's another thing. – JesperE Apr 01 '11 at 10:06
2

git init will create a git repository inside the root directory of your project. As far as i know the git repository is always created in the root directory of the project(or folder you want to version control) you are working on.

git makes a .git folder in the root directory with all the versions/branches/commits etc

Michael Koper
  • 9,586
  • 7
  • 45
  • 59
  • That is assuming I run the command when I am in that directory, right? What if I don't run it there? I'm guessing this is a best practice, though. – David Rhoden Apr 01 '11 at 08:43
  • Also, related: If I am using a client that has a command like "Create New Local Repository", if I browse to my root directory, that would be the same as running `git init` in the root folder, right? – David Rhoden Apr 01 '11 at 08:47
  • yes you have to be in the directory you want to be the git repository. Create new Local Repository is indeed the same as git init. It is easy right? :-) – Michael Koper Apr 01 '11 at 09:02
  • It's easy enough, but I think it helps to ask the "obvious" questions. This is actually what I was doing that made me ask the question--using the Tower command "Create New Local Repository", I didn't know whether to browse to my root directory or to create an adjacent directory to hold the repository. – David Rhoden Apr 01 '11 at 09:18
  • I didnt mean to offend you :) Just appreciate how easy git is :) – Michael Koper Apr 01 '11 at 10:08
  • No offense taken. I'm just trying to get extremely basic concepts covered for the benefit of those coming along later who may see this question and answer. Voted up. – David Rhoden Apr 01 '11 at 15:31
  • And I am one of those people. Watching videos on git but was still unsure of where to run 'git init' until I came across this thread. So thank you David for starting the thread. – Eggs May 16 '17 at 17:38
2

The git repository (.git folder at folder root) is by default created inside the folder to be version-controlled. You can create it outside of it, but it should not be needed and is a very special case.

CharlesB
  • 86,532
  • 28
  • 194
  • 218
  • Thanks. Why is it a special case? What is different if I do it outside of the root folder? – David Rhoden Apr 01 '11 at 08:44
  • @David it's just a pain to use since you have to specify its location on each git command. See [this question](http://stackoverflow.com/q/505467/11343). Why would you want to do this? – CharlesB Apr 01 '11 at 08:51
  • Thanks for the link and the explanation. I don't "want" to do anything, I'm just brand new to this and trying to figure out how it's supposed to work. I think my question is a good one, as it might seem obvious to experienced users, but I have gotten several good but contradictory answers so far. I need to know what a new user looking for the most typical setup would use. (Actually I thought the repository *had to* be outside the directory, so I have probably been given unclear advice.) – David Rhoden Apr 01 '11 at 09:07
1

The location of git repositories is not important, you can place them anywhere.

Although, placing repositories in other repositories is not very advisable, because the outer git repository would track the changes in the inner repository too.

What you can do, is using submodules. You basicly import other existing repositories in to you repository, and track a certain commit from it.

Ikke
  • 99,403
  • 23
  • 97
  • 120
  • Thanks, interesting answer. I read an article about submodules in Mercurial, and wondered if something similar existed in Git. I think you should clarify though: you say "the location of git repositories is not important", then you say "Placing repositories in other repositories is not very advisable". This is either a contradiction or a very advanced answer, and I'm looking for an answer that would be useful to a person who is inexperienced with Git. – David Rhoden Apr 01 '11 at 08:52
1

Either is possible, but to be concise, yes, it does matter. In my explanation is will call the repository where you push to and pull from the super repository. This is just to make it more clear.

Here's your 2 options:

  1. super repository outside folder being version controlled: if you do this on your local PC, you will of course incur the cost of storing everything more than once. In fact, you will store your super repository somewhere, plus a checked out version (your working directory), plus the files for the currently checked out branch. Generally however, storage is not that much of a concern these days. The big advantage of this method is that you can clone/pull/push to your super repository from no matter where you are.

  2. super repository inside folder being version controlled: you don't use extra storage. There is a big drawback to doing this though: your repository will not be a bare one. What this means is that it has got checked out files. If you are currently in branch A, it will be impossible to push to this branch A from a remote location. You will first have to change your working branch to branch B, before someone else can work with branch A.

So, if you just want version control, but don't plan on working on your project on any other PC, creating the super repository inside your project folder is fine. If you do plan on working it somewhere else, create a bare super repository somewhere else on your PC. A bare repository does not have any checked out branch.

The following commands will create a new bare git repository and push your current data to it. You should from then on be able to git push, git pull, ... as you wish.

cd
mkdir myproject.git
cd myproject.git
git init --bare
cd
cd project_folder
git init
git add *
git commit -m "Initial push"
git remote add origin ~/myproject.git
git push origin master

[Edit] Made explanation more clear.

AVH
  • 11,349
  • 4
  • 34
  • 43
  • Since master is also the default branch name, you might want to avoid the word when describing repositories :) When people are first starting with git remembering the conventional meanings of `origin` and `master` isn't that easy... – Mark Longair Apr 01 '11 at 09:01