我可以将 .git 文件夹存储在我想要跟踪的文件之外吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/505467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:08:33  来源:igfitidea点击:

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

git

提问by Rory

I have an unusual idea to use git as a backup system. So let's say I have a directory ./backup/myfiles and I want to back that up using git. To keep things clean I don't want to have a .git directory in the myfiles folder, so I thought I could create ./backup/git_repos/myfiles. From looking at the git docs, I've tried doing this:

我有一个不寻常的想法,即使用 git 作为备份系统。所以假设我有一个目录 ./backup/myfiles 并且我想使用 git 备份它。为了保持干净,我不想在 myfiles 文件夹中有一个 .git 目录,所以我想我可以创建 ./backup/git_repos/myfiles。通过查看 git 文档,我尝试这样做:

$ cd backup/myfiles
$ mkdir ../git_repos/myfiles
$ git --git-dir=../git_repos/myfiles init
Initialized empty Git repository in backup/git_repos/myfiles/
$ git --git-dir="../git_repos/myfiles/" add foo
fatal: pathspec 'foo' did not match any files

You can see the error message I get there. What am I doing wrong?

您可以看到我到达那里的错误消息。我究竟做错了什么?

采纳答案by Bombe

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.

这将执行您想要的操作,但是当您必须使用您曾经使用的每个 git 命令指定它时,显然会很糟糕。

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

你可以导出GIT_WORK_TREE=.GIT_DIR=../backup并且 Git 会在每个命令上选择它们。但是,这只会让您轻松地在每个 shell 中的单个存储库中工作。

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

我宁愿建议将 .git 目录符号链接到其他地方,或者从主备份目录创建到 .git 目录的符号链接。

回答by niks

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

要让存储库知道工作树的位置,请设置配置值core.worktree。为了让工作树知道它的 git 目录在哪里,添加一个名为 .git 的文件(不是文件夹!)并添加一行

gitdir: /path/to/repo.git

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

从 git 1.7.5 开始,init 命令为此学习了一个额外的选项。

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.

这将在单独的目录中初始化 git 存储库,并在当前目录中添加 .git 文件,该文件是新存储库的工作目录。

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

在 1.7.5 之前,您必须使用稍微不同的参数并自己添加 .git 文件。

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.worktreevalue as specified with the --git-dirparameter.

您的当前目录将是工作树,git 将使用位于/path/to/repo.git. init 命令将自动设置参数core.worktree指定的值--git-dir

You could even add an alias for this:

您甚至可以为此添加别名:

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

Use git version control on a read-only working directory

在只读工作目录上使用 git 版本控制

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-diron 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在每个 git 命令上使用或从存储库(而不是工作目录)中执行每个命令,则可以省略 .git 文件,因此不需要在工作目录中创建任何文件。另见狮子座回答

回答by Fryer

The --separate-git-diroption 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.

(and )的--separate-git-dir选项可用于在我的 git ( )版本上完成此操作。该选项将 git 存储库与工作树分开,并在工作树的根目录中创建一个与文件系统无关的 git 符号链接(以名为 的文件的形式)。我认为结果与niks 的答案相同。git initgit clone1.7.11.3.git

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

回答by Leo

I find it simpler to reverse the --work-treeand --git-dirdirectories used in niks' answer:

我发现反转niks 答案中使用的--work-tree--git-dir目录更简单

$ 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 .gitfiles. 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.
  • 它不需要任何命令行选项或.git文件。您只需从存储库的根目录中正常操作即可。
  • 即使您不拥有它,它也允许您对文件系统进行版本控制。Git 只会写入存储库位置。

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

我遇到的唯一警告是,不是使用.gitignore文件,而是编辑info/exclude.

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

read_only_repos/foo即使原始文件不受版本控制,您也可以将存储库用作您自己存储库中的远程存储库。

回答by CB Bailey

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.

通常将目录命名为 git 存储库,该目录的工作树位于带有“.git”扩展名的不寻常位置,很像裸存储库。

mkdir ../git_repos/myfiles.git

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

如果您--work-tree在初始化时提供了该选项,那么这将自动设置core.worktree配置变量,这意味着一旦您指定了 git 目录,git 将知道在哪里可以找到工作树。

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

回答by To1ne

Use gitinside the repo:

git在 repo 中使用:

cd ./backup/git_repos/myfiles
git init --bare
git config core.worktree ../myfiles
git config core.bare false

From now on, you can use gitinside the ./backup/git_repos/myfilesdirectory, without setting any environment variables or additional parameters.

从现在开始,您可以git./backup/git_repos/myfiles目录内部使用,而无需设置任何环境变量或附加参数。

回答by Paul Hedderly

You could create a "nodgit" script (No Dot GIT) with somet like

您可以创建一个“nodgit”脚本(No Dot GIT),类似于

#!/bin/sh
gits=/usr/local/gits
    x=`pwd`
    testdir() {( cd ; pwd; )}
    while [ "$x" != "/" ]; do
      y=`echo $x|sed -e "s/\//__/g"`
      if ([ -d "$gits/$y" ]); then
        export GIT_DIR="$gits/$y"
        export GIT_WORK_TREE="$x"
        if ([ "" = "nodinit" ]); then
          mkdir -p "$GIT_DIR"
          git init --bare; exit $?
        elif ([ "" = "shell" ]); then
          bash; exit $?
        else
          exec git "$@"
        fi
      fi
      x=`testdir "$x/.."`
    done

You can call nodgit in place of git and it will set variables as necessary by looking for a git repo. For example say you have a (bare) repo in /usr/local/gits/__home__foo_wibbles and you are in in /home/foo/wibbles/one then it will find the correct working directory (/home/foo/wibbles) and repo.

您可以调用 nodgit 代替 git,它会根据需要通过查找 git repo 来设置变量。例如,假设您在 /usr/local/gits/__home__foo_wibbles 中有一个(裸)repo,并且您在 /home/foo/wibbles/one 中,那么它将找到正确的工作目录(/home/foo/wibbles)和 repo .

Oh you can also use "nodgit shell" to get a shell with the correct vars set so you can use plain old git commands.

哦,您还可以使用“nodgit shell”来获取设置了正确 vars 的 shell,以便您可以使用普通的旧 git 命令。

回答by Abie

Assuming your myfilesdirectories already exists and has some content, could you live with this:

假设你的myfiles目录已经存在并且有一些内容,你能接受这个:

cd ~/backup
git init
git add myfiles

The .gitdirectory will be in backup, not in myfiles.

.git目录将在 中backup,而不是在myfiles.

回答by Krazy Glew

I create scripts that look like

我创建的脚本看起来像

~/bin/git-slash:

~/bin/git-slash:

#!/usr/bin/sh

export GIT_DIR=/home/Version-Control/cygwin-root.git/
export GIT_WORK_TREE=/

git --git-dir=$GIT_DIR --work-tree=$GIT_WORK_TREE "$@"

exit $?

It's redundant to use --git_dir=$GIT_DIR, but reminds me that I can also set environment variables outside the script.

使用 --git_dir=$GIT_DIR 是多余的,但提醒我我也可以在脚本之外设置环境变量。

The above example is for tracking local changes to cygwin system files.

上面的示例用于跟踪对 cygwin 系统文件的本地更改。

Can make one such script for any major project that needs this - but / without /.git is my main use.

可以为任何需要它的主要项目制作一个这样的脚本 - 但 / 没有 /.git 是我的主要用途。

The above is small enough to make a shell alias or function, if you eliminate the redundancy.

如果消除冗余,上面的内容足够小,可以制作外壳别名或函数。

If I do this often enough, I would revive the workspace to repository mapping of

如果我经常这样做,我会恢复工作区到存储库映射

"Boxes, Links, and Parallel Trees: Elements of a Configuration Management System", 
in Workshop Proceedings of the Software Management Conference. 1989.

whose closest modern counterpart is Perforce mappings or views, supporting partial checkouts as well as non-colocation of workspace and repo.

其最接近的现代对应物是Perforce 映射或视图,支持部分结帐以及工作区和存储库的非托管。