2016-04-06
Dropbox isn’t version control.
If you use git to version control your files, and
have co-authors that use Dropbox
then here is a way to use the two
systems together.
I’d like my shared Dropbox folder to be a full fledged git repository, and
version control all relevant files there via git. However, git repositories
usually contain a special .git/
folder in the root. Storing this special
.git/
folder in a shared dropbox folder is a recipe for disaster. A
non-git aware collaborator will certainly wreak havoc on it. Further, doing
most git operations (even if they are simply checking the status) will push
notifications to all your collaborator saying that a few git files have
changed.
This can be annoying (and disastrous). A better alternative is to set up your
shared Dropbox folder to be a git repository, but store the git repository (the
.git/
folder) in a separate (non-dropbox) directory.
$ mkdir -p $HOME/.separate-gitroots $ cd ~/Dropbox/shared/foo $ git init --separate-git-dir=$HOME/.separate-gitroots/foo.git Initialized empty Git repository in /home/gautam/.separate-gitroots/foo.git
This creates the git repository in $HOME/.separate-gitroots/foo.git
instead
of in ./.git/
as is customary. Now ./.git
will be a plain text file (not
folder) that contains the location of the foo.git
directory above.
Obviously ./.git
will be truly useless to anyone else sharing your Dropbox
folders, so I recommend excluding it from the list of synchronized files. The
asking your collaborators not to modify this file.dropbox exclude
command above does this using Dropbox’s Selective sync feature
I set up a local copy, away from Dropbox, to work on. This way a collaborator who makes changes while I’m working will not overwrite mine, and I can tell the two changes apart easily. I also use a centralized remote (so I can share it with git-aware co-authors), but you can do without it (if you know what you’re doing.)
Let’s assume you have a git server and created an empty repository on it at git@yourserver.com:foo
.
We first add this remote into Dropbox, and put your shared files in it:
$ cd ~/Dropbox/shared/foo $ git remote add origin git@yourserver.com:foo $ git add paper.tex ... # (or use git add -Av .) $ git commit --author 'Coauthor <who@doesnt.use.git>' [master a484503] Blah blah (commit subject) 1 file changed, 10 insertions(++++++) $ git push -u origin master Branch master set up to track remote branch master from origin. Counting objects: 5, done. Delta compression using up to 4 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 6.80 KiB | 0 bytes/s, done. Total 5 (delta 3), reused 0 (delta 0) To yourserver.com/foo 9996b2d..f9d5e30 master -> master
Now set up a local copy by cloning this repository into ~/foo
. Type:
$ git clone git@yourserver.com:foo ~/foo Cloning into 'foo'... remote: Counting objects: 545, done. remote: Compressing objects: 100% (542/542), done. remote: Total 545 (delta 341), reused 0 (delta 0) Receiving objects: 100% (545/545), 691.49 KiB | 0 bytes/s, done. Resolving deltas: 100% (341/341), done.
or use your favorite GUI client.
You should now have your work in the remote repository git@yourserver.com
, one clone in Dropbox (for your coauthors to edit) and one local clone in ~/foo
for you to edit.
(Of course, if you had local files you were already working on in ~/foo
, you could have done the git remote add
in ~/foo
, committed, pushed and then pulled in Dropbox instead.)
When a collaborator make changes in Dropbox, you have to commit and push it for them, and pull it into your local copy.
$ cd ~/Dropbox/shared/foo $ git commit -a --author 'Coauthor <who@doesnt.use.git>' [master a484503] Blah blah (commit subject) 1 file changed, 10 insertions(++++++) $ git push Counting objects: 5, done. Delta compression using up to 4 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 6.80 KiB | 0 bytes/s, done. Total 5 (delta 3), reused 0 (delta 0) To yourserver.com/foo 9996b2d..f9d5e30 master -> master $ cd ~/foo $ git pull Updating 9996b2d..f9d5e30 Fast-forward paper.tex | 141 +++--- refs.bib | 5 +- 3 files changed, 140 insertions(+), 6 deletions(-)
After the first commit as your co-author, you can just use --author Coauthor
without typing the whole email address every time. Also, if you have only one
co-author who will commit in Dropbox, then you can use git config
to set
user.name
and user.email
in the Dropbox repository, and not use --author
above.
When you make changes:
$ cd ~/foo $ git commit -a && git push [master a484503] Blah blah (commit subject) 1 file changed, 10 insertions(++++++) Counting objects: 5, done. Delta compression using up to 4 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 6.80 KiB | 0 bytes/s, done. Total 5 (delta 3), reused 0 (delta 0) To yourserver.com/foo 9996b2d..f9d5e30 master -> master $ cd ~/Dropbox/shared/foo $ git pull Updating 9996b2d..f9d5e30 Fast-forward paper.tex | 141 +++--- refs.bib | 5 +- 3 files changed, 140 insertions(+), 6 deletions(-)
No problem. Git handles it painlessly. (I’m omitting the console output of git below for brevity.)
$ cd ~/Dropbox/shared/foo $ git commit -a --author Coauthor && git push $ cd ~/foo $ git commit -a $ git pull --rebase
The last command may warn you about conflicts (if you and your co-author edited similar portions of the same file). Follow the instructions displayed by git. Once you’re done, push your changes and pull them into Dropbox as shown in the previous section.
Often when when I’m editing my local copy my collaborator makes changes in Dropbox simultaneously. For simple changes you can merge them quickly as above. If there have been more elaborate changes, I usually create a branch and merge it as follows.
Commit and push your collaborators changes to a new branch
$ cd ~/Dropbox/shared/foo $ git checkout -b coauthor-b1 $ git commit --author Coauthor -a $ git push --all
Merge your co-authors changes in your local copy. (Or rebase it, if you know what you are doing.)
$ cd ~/foo $ git commit -a $ git fetch origin coauthor-b1 $ git merge coauthor-b1 $ git push
Pull them in the shared Dropbox folder.
$ cd ~/Dropbox/shared/foo $ git checkout master $ git pull
Ricardo Lima (2017-12-20 07:56:17 EST)
Hey Gautam,
Nice post. Thank you.
I do not understand this part “This creates the git repository in $HOME/foo/.dropbox.git
instead of in ./.git/
as is customary. Now ./.git
will be a plain text file (not folder) that contains the location of the true git repository.”
How does the file $HOME/foo/.dropbox.git
is created? With the commands above?
Isn’t it created in $HOME/.separate-gitroots/shared.git
?
Also when you say “Now ./.git
will be a plain text file (not folder) that contains the location of the true git repository.”, do you mean “… of the true .git directory?
Best,
Ricardo
Gautam Iyer (2017-12-20 12:29:41 EST)
On 2017-12-20 at 07:56:17 EST, Ricardo Lima wrote
How does the file
$HOME/foo/.dropbox.git
is created? With the commands above? Isn’t it created in$HOME/.separate-gitroots/shared.git
?
Apologies, this was a typo which I just fixed.
Also when you say “Now
./.git
will be a plain text file (not folder) that contains the location of the true git repository.”, do you mean “… of the true .git directory?
Yes. If you do cat .git
, you should see something like
gitdir: /home/gautam/.separate-gitroots/foo.git
I fixed it above as well, thanks for pointing it out.
GI
SSJ (2019-02-25 15:56:00 EST)
Hi, Any idea how to get $ dropbox exclude add .git to work with windows? I have the windows dropbox app installed but cant seem to get the dropbox command to work in command line or gitbash Thanks
Gautam Iyer (2019-02-27 15:11:59 EST)
Any idea how to get
$ dropbox exclude add .git
to work with windows?
I don’t know how to do this on windows. But I’m guessing the windows Dropbox
client has a way to exclude files. You just need to get it to exclude the file
.git
from being synced. But if you don’t, it’s not such a big deal – the
file will be a plain text file which Dropbox can happily sync. Just ask your
collaborators to avoid modifying / deleting this file.
Anonymous (2020-04-25 03:57:49 EDT)
To answer SSJ, it appears that the windows version does not have an “equivalent” (in terms of Linux) command line version. The GUI however lets you untick “.git” (chanced on this blog, so this may be dated)
Pete (2020-12-27 03:15:57 EST)
If you save following line below as a snippet.ps1 file under windows and run it in powershell you might be able to exclude it from syncing.
Set-Content -Path “C:\example_repository.git” -Stream com.dropbox.ignored -Value 1
Dr.Feng (2021-08-05 06:00:16 EDT)
Pete’s solution works very well in windows. Actually the command comes from dropbox official help doc here: https://help.dropbox.com/files-folders/restore-delete/ignored-files
Gautam Iyer (2021-08-06 09:45:02 EDT)
Initially I recommended excluding the .git
file from dropbox using dropbox exclude
or the selective sync feature. As of today (Aug 2021), this doesn’t work for me on Linux. If I exclude a file, dropbox prevents a file with that name being created locally. It’s simpler to just tell your collaborators to not modify that file…
Dr.Feng (2021-08-11 08:47:03 EDT)
Hi, Prof. Iyer. Thank you for the update.
Aaron (2022-06-16 11:29:25 EDT)
This looks absolutely great, thanks for this guide! It seems to be the best out there.
Have you ever tried this approach when most of your coauthors don’t use git, but one of them does? The issue seems to arise that the .git
file specifically references my personal home directory when pointing to the separate git repo. Dereferencing it using $HOME
in the .git
file does not work. So I imagine that the other git user will run into an issue when they try to clone the repo, since their home dir is different.
Is this something you have run into or have a solution for? Thanks in advance!
Gautam Iyer (2022-06-16 12:39:43 EDT)
Have you ever tried this approach when most of your coauthors donโt use git, but one of them does? The issue seems to arise that the .git file specifically references my personal home directory when pointing to the separate git repo.
Ideally the best way to deal with this is to exclude the .git
file from Dropbox, and let each git savvy co-author will have their own personal .git
file pointing to their local git repository. Unfortunately, this stopped working: The last I tried, when I excluded a file from Dropbox, it deleted it from the disk ๐.
There is a way around this. Once your repository is setup, delete the .git
file. Now run the command
export GIT_DIR=$HOME/.separate-gitroots/foo.git
before running your git commands in that directory. Alternately add --git-dir=$HOME/.separate-gitroots/foo.git
as an option to all your git commands.
GI