git上面可以存储其他文件吗?我可不可以拿git当网盘用?里面存入个人好多文件,而且在哪都可以同步

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了git上面可以存储其他文件吗?我可不可以拿git当网盘用?里面存入个人好多文件,而且在哪都可以同步相关的知识,希望对你有一定的参考价值。

这个当然可以的,只是不适合用git来操作的 参考技术A 可以啊 git他就是一个分布式的管理系统,你只要推送上去就行了

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

【中文标题】我可以将 .git 文件夹存储在我想要跟踪的文件之外吗?【英文标题】:Can I store the .git folder outside the files I want tracked? 【发布时间】:2010-10-05 01:31:30 【问题描述】:

我有一个不寻常的想法,即使用 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

您可以看到我收到的错误消息。我做错了什么?

【问题讨论】:

除了你的备份想法外,这也可以用来将你的“dotfiles”(.bashrc、.vimrc 等)保存在主目录中,同时将 .git 文件夹保存在其他地方。 最直截了当的回答:***.com/a/19548676/170352(因旧票而被埋葬) 如果您没有写入权限或不想对工作目录进行任何更改(如添加 .git/ 等),this 下面由 Leo 回答(也由旧的赞成票)是最好的。 @Philip,除非您的 dotfiles 存储库还包含 Git 子模块。 Git 不支持子模块与外部工作树的结合。 【参考方案1】:

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

cd ~/backup
git init
git add myfiles

.git 目录将位于 backup,而不是 myfiles

【讨论】:

虽然这样可以解决我想要的问题,但我宁愿只将 myfiles 文件夹存储在 git 下,别无其他。 您可以使用.gitignore 文件选择您希望git 跟踪的文件。如果您将*!myfiles 添加到其中,则只会跟踪该目录。但是如果你想为另一个目录创建一个单独的 repo,你就会遇到问题......【参考方案2】:
git --git-dir=../repo --work-tree=. add foo

这会做你想做的事,但当你必须用你曾经使用的每个 git 命令指定它时,显然会很糟糕。

您可以导出GIT_WORK_TREE=.GIT_DIR=../backup,Git 会在每个命令中提取它们。不过,这只会让您轻松地在每个 shell 中使用一个存储库。

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

【讨论】:

您可以归档相同的内容,而无需在每个命令中指定 git-dir 和工作树,也无需任何符号链接。看我的回答。 符号链接的缺点是它存在于工作树中,如果其他进程清除了工作树,那么您就丢失了符号链接 此外,如果 OP 不想在他的工作树中添加一个 .git 子目录,他为什么要一个符号链接? @Jeff:进行权衡。 (在他的备用案例中,清除他的工作树可能并不比清除任何其他目录(例如 repo 本身)更重要。) 我将它与direnv 一起用于我的笔记。我的工作树在 Dropbox 的一个文件夹中,而我的 git 文件夹在外面的某个地方。这样,我可以轻松地在所有计算机上进行更改,但仍然能够检查更改的内容,并且仅在重大更改时才提交。谢谢【参考方案3】:

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

mkdir ../git_repos/myfiles.git

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

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

但是你也可以在事后设置这个变量。

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

完成此操作后,添加命令应该会按预期工作。

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

【讨论】:

我发现如果你先 cd 到 ../git_repos/myfiles.git,而不是在真正的工作树中,'git add foo' 就可以工作,你不需要一直指定 --git-dir。 确实如此,但我认为大多数人倾向于在他们的工作树中工作,而不是在他们的存储库中工作。当然,如果您使用的是分离的工作树,您可能正在做一些“特殊”的事情,并且很可能会使用一些宏来提供帮助。【参考方案4】:

你可以用 somet like 创建一个“nodgit”脚本(No Dot GIT)

#!/bin/sh
gits=/usr/local/gits
    x=`pwd`
    testdir() ( cd $1; 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 ([ "$1" = "nodinit" ]); then
          mkdir -p "$GIT_DIR"
          git init --bare; exit $?
        elif ([ "$1" = "shell" ]); then
          bash; exit $?
        else
          exec git "$@"
        fi
      fi
      x=`testdir "$x/.."`
    done

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

哦,你也可以使用“nodgit shell”来获得一个设置了正确变量的 shell,这样你就可以使用普通的旧 git 命令了。

【讨论】:

【参考方案5】:

在 repo 中使用git

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

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

【讨论】:

这似乎是最好的答案,但我收到了warning: core.bare and core.worktree do not make sense 的消息,这是否意味着它没有工作? 我仍然认为是可行的,但它抱怨设置工作树时是裸露的。这就是为什么我之后将core.bare 设置为false 啊!这现在更有意义了。谢谢你。【参考方案6】:

您只需要确保存储库知道工作树的位置,反之亦然。

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

gitdir: /path/to/repo.git

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

你可以初始化一个新的独立仓库

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

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

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

要初始化单独的存储库,以下命令将工作树与存储库链接:

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

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

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

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

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

有了上面的知识,你甚至可以在没有写权限的情况下为工作目录设置 git 版本控制。如果您在每个 git 命令上使用 --git-dir 或从存储库(而不是工作目录)中执行每个命令,您可以省略 .git 文件,因此不需要在工作目录中创建任何文件。另见Leos answer

【讨论】:

您也可以对现有仓库执行此操作:将 .git 文件夹移动到您想要的任何位置,添加 .git 文件以指向它,然后您可以继续使用仓库作为你通常会 请注意,您只能从 repo 的根目录发出 git 命令。进入子文件夹会混淆它! (无论 gitdir 的给定值是相对的还是绝对的,都会发生这种情况。) 解决这个问题的方法是在实际的 git 配置文件中指定 'core.worktree',即您在 .git 中指向的文件夹中的那个。 是的,这就是我在回答的第二句话中所描述的。配置值core.worktree当然存放在.git文件夹的config文件中,.git文件指向的地方。 我发现当我使用这些说明时,生成的 repo 变成了一个裸存储库,它给出了错误 fatal: core.worktree and core.bare do not make sense。似乎只是更改配置,所以它不是裸解决的。【参考方案7】:

git init(和git clone)的--separate-git-dir 选项可用于在我的git 版本(1.7.11.3)上完成此操作。该选项将 git 存储库与工作树分离,并在工作树的根目录中创建与文件系统无关的 git 符号链接(以名为 .git 的文件的形式)。我认为结果与niks' answer 相同。

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

【讨论】:

+1 为init 使用命令行选项本身看起来更清晰 在 windows 中,repo.git 是使用其隐藏属性集创建的。然后我手动更改它。你知道这是否安全吗? +1 是的 git 在 1.7.5 版本中使用了这个命令行选项,当时不可用(如果我没记错的话)。我已更新我的答案以建议使用此参数。【参考方案8】:

我发现反转niks' answer: 中使用的--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
        ...

这种方法有两个优点:

它不再需要任何命令行选项或.git 文件。您只需在存储库的根目录中正常操作即可。 它允许您对文件系统进行版本控制,即使您不拥有它。 Git 只会写入存储库位置。

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

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

【讨论】:

嗯,这是完全相同的命令。我看到的唯一区别是您交换了 --work-tree 和 --git-dir 参数的顺序。当然,您不会在工作目录中创建 .git 文件,因为您没有对它的写入权限。尽管如此,对没有写访问权限的目录使用版本控制是一个很好的用例。 :-) 你明白了。关键是在工作目录之外创建 repo。 我喜欢这个 - 它允许我在与 Dropbox 共享的目录上使用 git,而其他参与者甚至不知道 git 正在使用中。【参考方案9】:

我创建的脚本看起来像

~/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 $?

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

上面的例子是用来跟踪cygwin系统文件的本地变化。

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

如果消除冗余,上面的内容足够小,可以创建一个 shell 别名或函数。

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

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

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

【讨论】:

【参考方案10】:

选项 1:core.worktree

在您要跟踪的路径之外初始化一个非裸存储库,并将core.worktree 设置为您要跟踪的路径。您可以使用终端命令设置此值或直接编辑存储库配置文件以添加:

worktree = &lt;path to files to backup&gt;

不要使存储库文件夹成为此路径的子文件夹,这将是递归的。您可以尝试这个并简单地忽略存储库文件夹,但我认为 git 不会允许这种情况。

在您的情况下,您将转到 backup/git_repos/ to run the initcommand and could use the--git-dir=./myfiles` 选项来覆盖默认存储库文件夹名称。命令如下所示:

cd backup/git_repos 
git init --git-dir=./myfiles
git config core.worktree backup/myfiles

注意:我最近测试了很多 Windows 的 git GUI,只有 Git 扩展支持使用 core.worktree 来移动主工作树。

不支持 core.worktree 的 GUI

SourceTree、Fork、Tower、GitKraken、GitHub Desktop、GitAhead、SmartGit* 和 Git-Cola。使用 core.worktree 时,您需要坚持使用终端。

* SmartGit 将此功能与选项 2 混淆,并要求提供.git 文件。这对于 core.worktree 不是必需的。

选项 2:--separate-git-dir

使用初始化位置中的--separate-git-dir=&lt;path to hold repository data&gt;. This will use the specified path to hold the repository data and create a .git`文件在您要备份的路径初始化存储库,该文件包含如下行:

gitdir: &lt;path to hold repository data&gt;

对你来说,命令看起来像这样:

cd backup/myfiles
git init --separate-git-dir=backup/git_repos/myfiles/

您在backup/myfiles/ 中的.git 文件将包含gitdir: backup/git_repos/myfiles/

您现在运行 git,将 .git 文件的位置视为存储库位置。

【讨论】:

以上是关于git上面可以存储其他文件吗?我可不可以拿git当网盘用?里面存入个人好多文件,而且在哪都可以同步的主要内容,如果未能解决你的问题,请参考以下文章

在 git 存储库中移动大量大文件

初次见面,Git请多关照!

git:存储库会自然膨胀吗?有啥好的做法可以缓解这种情况

我可以修改 git-add 的块大小吗?

所有git本地分支都共享同一个工作目录吗?

我可以“git commit”一个文件并忽略其内容更改吗?