Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I store the .git folder outside the files I want tracked?

Tags:

git

People also ask

Is .git folder tracked?

No, there isn't. But you can store in git a text files with the 2 or 3 commands you use to reconfigure each repository. You can make it a .

What do I do with a .git folder?

The . git folder contains all information that is necessary for the project and all information relating commits, remote repository address, etc. It also contains a log that stores the commit history. This log can help you to roll back to the desired version of the code.


You just need to ensure that the repository knows where the work tree is and vice versa.

To let the repository know where the work tree is, set the configuration value core.worktree. To let the work tree know where it's git directory is, add a file named .git (not a folder!) and add a line like

gitdir: /path/to/repo.git

Since git 1.7.5 the init command learned an extra option for this.

You can initialize a new separate repository with

git init --separate-git-dir /path/to/repo.git

This will initialize the git repository in the separate directory and add the .git file in the current directory, which is the working directory of the new repository.

Previously to 1.7.5 you had to use slightly different parameters and add the .git file yourself.

To initialize a separate repository the following command links the work-tree with the repository:

git --git-dir=/path/to/repo.git --work-tree=. init && echo "gitdir: /path/to/repo.git" > .git

Your current directory will be the working tree and git will use the repository at /path/to/repo.git. The init command will automatically set the core.worktree value as specified with the --git-dir parameter.

You could even add an alias for this:

[alias]
    initexternal = !"f() { git --work-tree=. --git-dir=\"$1\" init && echo \"gitdir: $1\" >> .git; }; f"

Use git version control on a read-only working directory

With the knowledge above, you can even set up git version control for an working directory without having write permissions. If you either use --git-dir on every git command or execute every command from within the repository (instead of the working directory), you can leave out the .git file and therefore do not need to create any files within the working directory. See also Leos answer


git --git-dir=../repo --work-tree=. add foo

This will do what you want but will obviously suck when you have to specify it with every git command you ever use.

You can export GIT_WORK_TREE=. and GIT_DIR=../backup and Git will pick them up on each command. That will only comfortably allow you to work in a single repository per shell, though.

I’d rather suggest symlinking the .git directory to somewhere else, or creating a symlink to the .git directory from your main backup directory.


The --separate-git-dir option for git init (and git clone) can be used to accomplish this on my version of git (1.7.11.3). The option separates the git repository from the work tree and creates a filesystem agnostic git symbolic link (in the form of a file named .git) in the root of the work tree. I think the result is identical to niks' answer.

git init --separate-git-dir path/to/repo.git path/to/worktree

I find it simpler to reverse the --work-tree and --git-dir directories used in niks' answer:

$ cd read_only_repos
$ git --work-tree=/some/readonly/location/foo/ --git-dir=foo init
$ cd foo
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        .file_foo
        bar
        ...

This approach has two advantages:

  • It removes the need to have any command-line options or .git files. You just operate normally from within the root of the repository.
  • It allows you to version a file system even if you don't own it. Git will only write to the repository location.

The only caveat I have encountered is that instead of using a .gitignore file, you edit info/exclude.

You can then use the repository read_only_repos/foo as a remote in your own repositories even if the original files are not under version control.


It's conventional to name a directory that is a git repository that has its working tree in an unusual place with a '.git' extension, much like a bare repository.

mkdir ../git_repos/myfiles.git

If you had provided the --work-tree option at init time then this would have automatically set up the core.worktree config variable that means that git will know where to find the working tree once you specify the git directory.

git --git-dir=../git_repos/myfiles.git --work-tree=. init

But you can set this variable after the fact as well.

git --git-dir=../git_repos/myfiles.git config core.worktree "$(pwd)"

Once you've done this, the add command should work as expected.

git --git-dir=../git_repos/myfiles.git add foo