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 = <path to files to backup>
不要使存储库文件夹成为此路径的子文件夹,这将是递归的。您可以尝试这个并简单地忽略存储库文件夹,但我认为 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 的 GUISourceTree、Fork、Tower、GitKraken、GitHub Desktop、GitAhead、SmartGit* 和 Git-Cola。使用 core.worktree 时,您需要坚持使用终端。
* SmartGit 将此功能与选项 2 混淆,并要求提供.git
文件。这对于 core.worktree 不是必需的。
选项 2:--separate-git-dir
使用初始化位置中的--separate-git-dir=<path to hold repository data>. This will use the specified path to hold the repository data and create a
.git`文件在您要备份的路径初始化存储库,该文件包含如下行:
gitdir: <path to hold repository data>
对你来说,命令看起来像这样:
cd backup/myfiles
git init --separate-git-dir=backup/git_repos/myfiles/
您在backup/myfiles/
中的.git
文件将包含gitdir: backup/git_repos/myfiles/
您现在运行 git,将 .git
文件的位置视为存储库位置。
【讨论】:
以上是关于git上面可以存储其他文件吗?我可不可以拿git当网盘用?里面存入个人好多文件,而且在哪都可以同步的主要内容,如果未能解决你的问题,请参考以下文章