Answers:
我认为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操作,它们将自动同步到您的所有其他计算机。
我写了一篇关于版本控制的博客文章(旧链接已 失效),介绍了我的推理以及如何设置环境,该文章基于我的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的目的是要求是否有损坏的存储库,甚至您是否有机会在不同的时间从不同的机器更新相同的基于Dropbox的存储库(Mac, Unix,Windows)。
我没有可能出错的完整列表,但是这是一个让我感到困惑的具体示例。每台机器都有自己的行尾字符概念以及文件名中大写/小写字符的处理方式。Dropbox和Git / Mercurial对此的处理略有不同(我不记得确切的区别)。如果Dropbox更新了Git / Mercurial背后的存储库,则该存储库已损坏。这会立即发生并且无形,因此,您甚至不知道自己的存储库已损坏,直到您尝试从其中恢复某些内容为止。
用这种方法从一团糟中挖掘出来后,我一直在使用以下食谱,取得了巨大的成功,没有出现任何问题的迹象。只需将您的存储库移出Dropbox。使用Dropbox进行其他操作;文档,JAR文件或任何您喜欢的东西。并使用GitHub(Git)或Bitbucket(Mercurial)来管理存储库本身。两者都是免费的,因此不会增加任何成本,并且每种工具现在都能发挥自己的优势。
在Dropbox上运行Git / Mercurial不会增加任何风险。不要这样
对于使用Dropbox的小型团队:
如果每个开发人员在Dropbox上都有自己的可写裸存储库(仅可拉给其他开发人员),则这将促进代码共享而不会造成损坏!
然后,如果您想要一个集中的“主线”,则可以让一个开发人员从他们自己的存储库中管理所有推送到它的推送。
我不想将所有项目都放在一个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
我不认为使用Git和Dropbox是要走的路...只需考虑一下两者的功能:
Git:
投寄箱:
如果您担心共享某些文件,为什么不加密它们呢?然后,您可以获得Dropbox to Git的最大优势,即拥有公共文件和私有文件...
现在是2015年,从三天前开始,已经创建了一个基于Dropbox API v2的新工具,可以在Dropbox上安全地使用git。它针对API而不是使用桌面客户端,并且可以正确处理多次同时推送到共享文件夹中托管的存储库的操作。
配置完成后,它就可以像设置其他git远程服务器一样完全设置git远程服务器。
git clone "dropbox::/path/to/repo"
git remote add origin "dropbox::/path/to/repo"
我使用Mercurial(或Git)+ TrueCrypt + Dropbox进行加密的远程备份。
最酷的事情是,如果您修改代码的一小部分,Dropbox不会同步整个TrueCrypt容器。同步时间与更改量大致成比例。即使已加密,TrueCrypt + Dropbox的组合也可以很好地利用块密码+块级别同步。
其次,整体式加密容器不仅增加了安全性,而且还减少了存储库损坏的机会。
警告:但是,在运行Dropbox时不要安装容器必须非常小心。如果2个不同的客户端将不同版本签入到容器中,则解决冲突也可能会很痛苦。因此,它仅对使用备份进行备份的个人有用,对团队而言则不可行。
设定:
preserve modification timestamp
*。用法:
PS取消选中Tells preserve modification timestamp
Dropbox,该文件已被修改,应该进行同步。请注意,即使您不更改其中的任何文件,安装容器也会修改时间戳。如果您不希望发生这种情况,只需将卷挂载为read-only
我喜欢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)在例行签入期间不会注意到或抱怨,当您尝试将其实际使用时,只有在抱怨抱怨回购损坏时,您才会听到有关损坏的消息。坏消息。希望我可以更具体地说明问题及其解决方法;我本人仍在尝试从这种混乱中挖掘出来。
还有一个开源项目(跨平台[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会先下载最小的文件,然后再移至较大的文件。如果您从晚上开始然后在周末之后回来,这不是问题:-)
现在是2014年,我使用Git和Dropbox大约一年半没有问题。不过有几点:
git push
推送到远程存储库,以便一旦损坏就可以轻松恢复它。C:\Users
,mklink /D link target
因为某些库指向绝对位置。我喜欢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文件的默认值。
另一种方法:
到目前为止,所有答案(包括最受欢迎的@Dan答案)都解决了使用Dropbox集中共享存储库而不是使用专注于git的服务(例如github,bitbucket等)的想法。
但是,由于最初的问题并未指定“有效地结合使用Git和Dropbox”的真正含义,所以让我们尝试另一种方法:“使用Dropbox仅同步工作树。”
操作方法包括以下步骤:
在项目目录中,将创建一个空.git
目录(例如mkdir -p myproject/.git
)
.git
在Dropbox中取消同步目录。如果使用Dropbox App:请转到“首选项”,“同步”和“选择要同步的文件夹”,在该.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
将分支结帐保留在单独的目录中。
xattr -w com.dropbox.ignored 1 /path/to/somewhere
。
对于我的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和其他类似的云磁盘服务,例如带有Git的SpiderOak。
目标是避免在这些文件修改的中间进行同步,因为它可以上传部分状态,然后将其下载回去,从而完全破坏了git状态。
为避免此问题,我做了:
git bundle create my_repo.git --all
。它不是完美的,因为不能保证它不会再次破坏git状态,但是它很有帮助,目前我还没有遇到任何问题。
在MacOS上,您也可以停止Dropbox,进行更改,然后重新启动Dropbox。我正在使用以下组合,对此感到非常满意:
在两个目录中(您本地的git托管项目目录和位于Dropbox上的远程git存储库),运行以下命令以禁用自动打包(这是Dropbox同步的主要问题)
git config --global gc.auto 0
然后不时地在禁用保管箱的情况下压缩存储库。例如,每当我发布新版应用程序时,我都会在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\""