20 回答
我认为 Dropbox 上的 Git 很棒。我用它所有的时间。我有多台计算机(两台在家里,一台在工作),我使用 Dropbox 作为中央裸存储库。由于我不想将其托管在公共服务上,而且我无法访问始终可以通过 SSH 访问的服务器,因此 Dropbox 通过在后台同步(非常快)来解决这个问题。
设置是这样的:
~/project $ git init
~/project $ git add .
~/project $ git commit -m "first commit"
~/project $ cd ~/Dropbox/git
~/Dropbox/git $ git init --bare project.git
~/Dropbox/git $ cd ~/project
~/project $ git remote add origin ~/Dropbox/git/project.git
~/project $ git push -u origin master
从那里,您可以克隆该~/Dropbox/git/project.git
目录(无论它属于您的 Dropbox 帐户还是在多个帐户之间共享)并执行所有正常的 Git 操作——它们将自动同步到您的所有其他计算机。
我写了一篇博文“<a href="http://corrupt.net/2009/08/01/On-Version-Control/" rel="nofollow noreferrer">On Version Control”,其中介绍了背后的原因我的环境设置。它基于我的Ruby on Rails开发经验,但实际上它可以应用于任何事物。
正确的方法是使用 git-remote-dropbox:https ://github.com/anishathalye/git-remote-dropbox
在 Dropbox 中创建自己的裸仓库会导致很多问题。Anish(图书馆的创建者)解释得最好:
这些问题的根本原因是 Dropbox 桌面客户端是为同步文件而设计的,而不是 Git 存储库。如果不对 Git 存储库进行特殊处理,它就不会保持与 Git 相同的保证。远程存储库上的操作不再是原子的,并发操作或同步的不幸时机可能导致存储库损坏。
传统的 Git 遥控器在服务器端运行代码以使其正常工作,但我们不能这样做。
解决方案:可以正确解决此问题。可以将 Git 与 Dropbox 一起使用,并具有与传统 Git 远程相同的安全性和一致性保证,即使有多个用户和并发操作!
对于用户来说,它就像使用 git-remote-dropbox 一样简单,它是一个 Git 远程助手,它充当 Git 和 Dropbox 之间的透明双向桥梁,并保持传统 Git 远程的所有保证。与共享文件夹一起使用甚至是安全的,因此它可以用于协作(是的,无限的私人回购与无限的合作者!)。
使用远程助手,可以将 Dropbox 用作 Git 远程,并继续使用所有常规 Git 命令,如 git clone、git pull 和 git push,一切都会按预期工作。
此答案基于Mercurial经验,而不是 Git,但此经验表明,如果您甚至有可能在不同时间从不同机器更新同一个基于 Dropbox 的存储库(Mac、 Unix,在我的情况下是 Windows)。
我没有可能出错的事情的完整列表,但这里有一个让我很痛苦的具体例子。每台机器都有自己的行尾字符概念以及文件名中大小写字符的处理方式。Dropbox 和 Git/Mercurial 处理这个略有不同(我不记得确切的区别)。如果 Dropbox 更新 Git/Mercurial 背后的存储库,那么很快,损坏的存储库。这会立即且不可见地发生,因此在您尝试从中恢复某些内容之前,您甚至都不知道您的存储库已损坏。
在以这种方式从一团糟中挖掘出来之后,我一直在使用以下食谱并取得了巨大的成功,并且没有任何问题的迹象。只需将您的存储库移出 Dropbox。将 Dropbox 用于其他一切;文档,JAR 文件,任何你喜欢的东西。并使用GitHub (Git) 或Bitbucket (Mercurial) 来管理存储库本身。两者都是免费的,所以这不会增加成本,现在每个工具都发挥了自己的优势。
在 Dropbox 上运行 Git/Mercurial 只会增加风险。不要这样做。
我不想将我的所有项目都放在一个 Git 存储库下,也不想进入并为每个项目运行这段代码,所以我制作了一个Bash脚本来自动化该过程。您可以在一个或多个目录上使用它——因此它可以为您执行本文中的代码,也可以一次在多个项目上执行。
#!/bin/sh
# Script by Eli Delventhal
# Creates Git projects for file folders by making the origin Dropbox. You will need to install Dropbox for this to work.
# Not enough parameters, show help.
if [ $# -lt 1 ] ; then
cat<<HELP
projects_to_git.sh -- Takes a project folder and creates a Git repository for it on Dropbox
USAGE:
./projects_to_git.sh file1 file2 ..
EXAMPLES:
./projects_to_git.sh path/to/MyProjectDir
Creates a git project called MyProjectDir on Dropbox
./projects_to_git.sh path/to/workspace/*
Creates a git project on Dropbox for every folder contained within the workspace directory, where the project name matches the folder name
HELP
exit 0
fi
# We have enough parameters, so let's actually do this thing.
START_DIR=$(pwd)
# Make sure we have a connection to Dropbox
cd ~
if [ -s 'Dropbox' ] ; then
echo "Found Dropbox directory."
cd Dropbox
if [ -s 'git' ] ; then
echo " Dropbox Git directory found."
else
echo " Dropbox Git directory created."
mkdir git
fi
else
echo "You do not have a Dropbox folder at ~/Dropbox! Install Dropbox. Aborting..."
exit 0
fi
# Process all directories matching the passed parameters.
echo "Starting processing for all files..."
for PROJ in $*
do
if [ -d $PROJ ] ; then
PROJNAME=$(basename $PROJ)
echo " Processing $PROJNAME..."
# Enable Git with this project.
cd $PROJ
if [ -s '.git' ] ; then
echo " $PROJNAME is already a Git repository, ignoring..."
else
echo " Initializing Git for $PROJNAME..."
git init -q
git add .
git commit -m "Initial creation of project." -q
# Make the origin Dropbox.
cd ~/Dropbox/git
if [ -s $PROJNAME ] ; then
echo " Warning! $PROJNAME already exists in Git! Ignoring..."
else
echo " Putting $PROJNAME project on Dropbox..."
mkdir $PROJNAME
cd $PROJNAME
git init -q --bare
fi
# Link the project to the origin
echo " Copying local $PROJNAME to Dropbox..."
cd $PROJ
git remote add origin "~/Dropbox/git/$PROJNAME"
git push -q origin master
git branch --set-upstream master origin/master
fi
fi
done
echo "Done processing all files."
cd $START_DIR
关于使用 Dropbox 的小型团队:
如果每个开发人员在 Dropbox 上都有自己的可写裸存储库,并且只对其他开发人员进行拉取,那么这有助于代码共享而没有损坏的风险!
然后,如果您想要一个集中的“主线”,您可以让一位开发人员从他们自己的仓库管理所有推送。
现在是 2015 年,截至三天前,已经创建了一个基于Dropbox API v2的新工具,可以在 Dropbox 上安全地使用 git。它适用于 API 而不是使用桌面客户端,并且可以正确处理多个同时推送到托管在共享文件夹中的存储库。
配置完成后,它允许您像设置任何其他 git 远程一样设置 git 远程。
git clone "dropbox::/path/to/repo"
git remote add origin "dropbox::/path/to/repo"
我不认为使用 Git 和 Dropbox 是要走的路……想想两者的特点:
吉特:
- 允许您拥有一个中央存储库
- 允许您拥有自己的存储库并进行自己的更改
- 允许您从中央存储库发送和接收更改
- 允许多人更改相同的文件,然后他们合并它们,或者如果它不能这样做,请您合并它们
- 具有 Web 和桌面客户端以允许访问中央存储库
保管箱:
- 将所有内容保存在中央存储库中
- 允许您在服务器中拥有自己的文件版本
- 强制您从中央存储库发送和接收更改
- 如果多人更改同一个文件,第一个提交的文件会被后面的提交替换,并且不会发生合并,这很麻烦(这绝对是它最大的缺点)
- 具有 Web 和桌面客户端以允许访问中央存储库。
如果您担心共享一些文件,为什么不加密它们呢?然后你可以获得 Dropbox to Git 的最大优势,即拥有公共和私人文件......
我使用 Mercurial(或 Git)+ TrueCrypt + Dropbox 进行加密远程备份。
最酷的是,如果您修改一小部分代码,Dropbox 不会同步整个 TrueCrypt 容器。同步时间大致与变化量成正比。即使它是加密的,TrueCrypt + Dropbox 的组合也可以很好地使用块密码 + 块级同步。
其次,单片加密容器不仅增加了安全性,还减少了存储库损坏的机会。
注意:但是你必须非常小心不要在 Dropbox 运行时挂载容器。如果 2 个不同的客户端将不同的版本签入到容器中,那么解决冲突也可能会很痛苦。因此,它仅适用于将其用于备份的单个人,而不适用于团队。
设置:
- 创建一个 Truecrypt 容器(多个 Gigabyte 即可)
- 在 Truecrypt 首选项下,取消选中
preserve modification timestamp
*. - 如上所述创建一个由 Dan (https://stackoverflow.com/a/1961515/781695)提到的仓库
用法:
- 退出 Dropbox
- 挂载容器,推送更改,卸载
- 运行保管箱
PS取消选中preserve modification timestamp
告诉Dropbox该文件已被修改并且应该同步。请注意,即使您不更改其中的任何文件,安装容器也会修改时间戳。如果您不希望发生这种情况,只需将卷挂载为read-only
我们在共享文件夹上使用这种方法(在 Dropbox 中创建一个裸存储库)。
一小部分开发人员可以从该裸同步存储库中提取并创建本地克隆。一旦工作单元完成,我们就会推回原点。
我缺少的一件事是,一旦发生推送到源,发送一封包含变更集信息的电子邮件的好方法。我们正在使用 Google Wave 手动跟踪更改。
我喜欢 Dan McNevin 的回答!我现在也同时使用 Git 和 Dropbox,并且在我的.bash_profile中使用了多个别名,所以我的工作流程如下所示:
~/project $ git init
~/project $ git add .
~/project $ gcam "first commit"
~/project $ git-dropbox
这些是我的别名:
alias gcam='git commit -a -m'
alias gpom='git push origin master'
alias gra='git remote add origin'
alias git-dropbox='TMPGP=~/Dropbox/git/$(pwd | awk -F/ '\''{print $NF}'\'').git;mkdir -p $TMPGP && (cd $TMPGP; git init --bare) && gra $TMPGP && gpom'
我一直在以推荐的方式使用 Mercurial,并敦促您谨慎行事,尤其是在任何机器不同的情况下。Dropbox 论坛上到处都是关于自发出现的神秘文件名问题的投诉。Hg(我猜是 Git)在例行检查期间不会注意到或抱怨,当您尝试真正使用它时,您只会在它抱怨损坏的 repo 时听到损坏。坏消息。希望我能更具体地了解问题及其解决方法;我仍在努力自己从这个烂摊子中挖掘出来。
还有一个开源项目(跨平台 [Linux、Mac、Win] 脚本的集合),它使用少数 (3-4) 个命令来完成存储库管理的所有细节。
https://github.com/karalabe/gitbox/wiki
示例用法是:
$ gitbox create myapp
Creating empty repository...
Initializing new repository...
Repository successfully created.
$ gitbox clone myapp
Cloning repository...
Repository successfully cloned.
之后正常使用 git:
$ echo “Some change” > somefile.txt
$ git add somefile.txt
$ git commit –m “Created some file”
$ git push
查看项目 wiki 和手册以获取完整的命令参考和教程。
我将我的非 Github 存储库存储在 Dropbox 上。我遇到的一个警告是重新安装后同步。Dropbox 会先下载最小的文件,然后再下载较大的文件。如果您从晚上开始并在周末后回来,这不是问题:-)
我的线程 - http://forums.dropbox.com/topic.php?id=29984&replies=6
现在是 2014 年,我已经使用 Git 和 Dropbox 大约一年半了,没有任何问题。不过有几点:
- 我所有使用 Dropbox 的机器都在 Windows 上,不同版本(7 到 8)+ 1 mac。
- 我不与其他人共享存储库,所以我是唯一一个修改它的人。
git push
推送到远程存储库,因此如果它被损坏,我可以轻松地恢复它。- 我必须在其中创建别名
C:\Users
,mklink /D link target
因为某些库指向绝对位置。
另一种方法:
到目前为止的所有答案,包括最流行的@Dan 答案,都解决了使用 Dropbox 集中共享存储库而不是使用像 github、bitbucket 等专注于 git 的服务的想法。
但是,由于最初的问题没有具体说明“有效地一起使用 Git 和 Dropbox”的真正含义,让我们采用另一种方法:“使用 Dropbox 仅同步工作树”。
操作方法有以下步骤:
在项目目录中,创建一个空
.git
目录(例如mkdir -p myproject/.git
)取消同步
.git
Dropbox 中的目录。如果使用 Dropbox 应用程序:转到首选项、同步和“选择要同步的文件夹”,.git
目录需要取消标记。这将删除.git
目录。git init
在项目目录下运行
如果它已经存在,它也可以工作.git
,那么只需执行第 2 步。不过,Dropbox 会在网站中保留一份 git 文件的副本。
第 2 步将导致 Dropbox 不同步 git 系统结构,这是此方法的预期结果。
为什么要使用这种方法?
尚未推送的更改将具有 Dropbox 备份,并且它们将跨设备同步。
万一 Dropbox 在设备之间同步时搞砸了,
git status
可以git diff
很方便地解决问题。它节省了 Dropbox 帐户中的空间(整个历史记录不会存储在那里)
它避免了@dubek 和@Ates 在@Dan 的答案的评论中提出的担忧,以及@clu 在另一个答案中的担忧。
其他地方(github等)的远程存在将适用于这种方法。
在不同的分支上工作会带来一些需要注意的问题:
一个潜在的问题是当一个人签出不同的分支时,Dropbox(不必要地?)可能会同步许多文件。
如果两个或多个 Dropbox 同步设备签出不同的分支,则对这两个设备的未提交更改可能会丢失,
解决这些问题的一种方法是使用git worktree
将分支结帐保存在单独的目录中。
我喜欢 Dan McNevin 投票率最高的答案。我最终执行了太多次 git 命令序列,并决定制作一个脚本。所以这里是:
#!/bin/bash
# Usage
usage() {
echo "Usage: ${0} -m [ master-branch-directory ] -r [ remote-branch-directory ] [ project-name ]"
exit 1
}
# Defaults
defaults() {
masterdir="${HOME}/Dropbox/git"
remotedir="${PWD}"
gitignorefile="# OS generated files #\n\n.DS_Store\n.DS_Store?\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db"
}
# Check if no arguments
if [ ${#} -eq 0 ] ; then
echo "Error: No arguments specified"
usage
fi
#Set defaults
defaults
# Parse arguments
while [ ${#} -ge 1 ]; do
case "${1}" in
'-h' | '--help' ) usage ;;
'-m' )
shift
masterdir="${1}"
;;
'-r' )
shift
remotedir="${1}"
;;
* )
projectname="${1##*/}"
projectname="${projectname%.git}.git"
;;
esac
shift
done
# check if specified directories and project name exists
if [ -z "${projectname}" ]; then
echo "Error: Project name not specified"
usage
fi
if [ ! -d "${remotedir}" ]; then
echo "Error: Remote directory ${remotedir} does not exist"
usage
fi
if [ ! -d "${masterdir}" ]; then
echo "Error: Master directory ${masterdir} does not exist"
usage
fi
#absolute paths
remotedir="`( cd \"${remotedir}\" && pwd )`"
masterdir="`( cd \"${masterdir}\" && pwd )`"
#Make master git repository
cd "${masterdir}"
git init --bare "${projectname}"
#make local repository and push to master
cd "${remotedir}"
echo -e "${gitignorefile}" > .gitignore # default .gitignore file
git init
git add .
git commit -m "first commit"
git remote add origin "${masterdir}/${projectname}"
git push -u origin master
#done
echo "----- Locations -----"
echo "Remote branch location: ${remotedir}"
echo "Master branch location: ${masterdir}"
echo "Project Name: ${projectname}"
该脚本只需要一个项目名称。它将~/Dropbox/git/
在指定名称下生成一个 git 存储库,并将当前目录的全部内容推送到新创建的 origin master 分支。如果给出了多个项目名称,将使用最右边的项目名称参数。
可选地,-r 命令参数指定将推送到源主服务器的远程分支。也可以使用 -m 参数指定项目源主机的位置。默认的 .gitignore 文件也放置在远程分支目录中。目录和 .gitignore 文件默认值在脚本中指定。
对于我的 2 美分,Dropbox 仅适用于您不想费心获得中央回购主机的个人用途。对于任何专业开发,您可能会产生比您解决的问题更多的问题,正如线程中已经多次提到的那样,Dropbox 不是为这个用例设计的。也就是说,在没有任何第三方插件或工具的情况下在 Dropbox 上转储存储库的一种完全安全的方法是使用捆绑包。我有以下别名.gitconfig
来保存输入:
[alias]
bundle-push = "!cd \"${GIT_PREFIX:-.}\" && if path=\"$(git config remote.\"$1\".url)\" && [ \"${path:0:1}\" = / ]; then git bundle create \"$path\" --all && git fetch \"$1\"; else echo \"Not a bundle remote\"; exit 1; fi #"
bundle-fetch = "!cd \"${GIT_PREFIX:-.}\" && if path=\"$(git config remote.\"$1\".url)\" && [ \"${path:0:1}\" = / ]; then git bundle verify \"$path\" && git fetch \"$1\"; else echo \"Not a bundle remote\"; exit 1; fi #"
bundle-new = "!cd \"${GIT_PREFIX:-.}\" && if [ -z \"${1:-}\" -o -z \"${2:-}\" ]; then echo \"Usage: git bundle-new <file> <remote name>\"; exit 1; elif [ -e \"$2\" ]; then echo \"File exist\"; exit 1; else git bundle create \"$2\" --all && git remote add -f \"$1\" \"$(realpath \"$2\")\"; fi #"
例子:
# Create bundle remote (in local repo)
$ git bundle-new dropbox ~/Dropbox/my-repo.bundle
# Fetch updates from dropbox
$ git bundle-fetch dropbox
# NOTE: writes over previous bundle. Thus, roughly equivalent to push --force --prune --all
$ git bundle-push
我遇到了类似的问题,并为此创建了一个小脚本。我们的想法是尽可能简单地将 Dropbox 与 Git 结合使用。目前,我已经快速实现了Ruby代码,我将很快添加更多。
该脚本可在https://github.com/nuttylabs/box-git
.
在不使用第三方集成工具的情况下,我可以稍微增强一下条件,并使用 DropBox 和其他类似的云盘服务,如 SpiderOak 和 Git。
目标是避免在这些文件修改中间进行同步,因为它可以上传部分状态,然后将其下载回来,从而完全破坏您的 git 状态。
为了避免这个问题,我做了:
- 使用 .将我的 git 索引捆绑在一个文件中
git bundle create my_repo.git --all
。 - 设置文件监控的延迟,例如 5 分钟,而不是瞬时。这减少了 DropBox 在更改过程中同步部分状态的机会。在即时修改云盘上的文件(例如使用即时保存的笔记应用程序)时,它也有很大帮助。
它并不完美,因为不能保证它不会再次弄乱 git 状态,但它有帮助,目前我没有遇到任何问题。
在 MacOS 上,您也可以停止 Dropbox,进行更改,然后重新启动 Dropbox。我正在使用以下组合并且对此非常满意:
在这两个(您的本地 git 管理项目目录和位于 Dropbox 上的远程 git 存储库)中,运行以下命令以禁用自动打包(这是 Dropbox 同步的主要问题)
git config --global gc.auto 0
然后不时地在禁用 Dropbox 的情况下压缩存储库。例如,每当我发布我的应用程序的新版本时,我都会在我的 bash-build-script 中执行以下操作。
osascript -e "tell application \"Dropbox\" to quit"
# Compress local
git gc --prune=now; git repack -a -d
# Compress remote
REPOS_DIR_REMOTE=`git remote get-url --push origin`
cd "${REPOS_DIR_REMOTE}"
git gc --prune=now; git repack -a -d
osascript -e "tell application \"Dropbox\" to launch"
osascript -e "display notification with title \"Compress Done\""