Sync directories containing git repository with unison
Asked Answered
E

2

11

I want to sync a directory containing a git repo of my dotfiles on two machines. Both machines will make changes to the files in the repo. Normally I use unison for syncing directories but in this case the files in the .git directory diverge even when the directory contents are ostensibly the same. Unison throws up its hands and quits when it sees this.

$ unison dotfiles
changed  <-?-> changed    .git/FETCH_HEAD
changed  <-?-> changed    .git/ORIG_HEAD
changed  <-?-> changed    .git/index
changed  <-?-> changed    .git/logs/HEAD
changed  <-?-> changed    .git/logs/refs/heads/master
changed  <-?-> changed    .git/logs/refs/remotes/origin/master

A byte-by-byte sync here doesn't work because even with the same files and git state the internal git files may be different. How can I sync these directories? After the sync, all non-git files and the git state should be identical on the two machines. By git state I mean commit histories and staging but not necessarily every byte of every internal git file (e.g. .gitignore, .git). I don't know enough about git to go into more detail on what I mean by that but if that's unclear just comment.

I don't want to make any git commits as part of syncing. I see version control and synchronization as two separate issues here.

Putting the words git and sync into google gives results describing how to clone a repo. Just to be clear, none of the uses of "sync" above are referring to git actions.

Elimination answered 25/7, 2015 at 16:57 Comment(0)
E
9

Based on VonC's advise, I'm going to relax the requirement of live syncing the entire git state and simply ignore the .git directory with unison and just use git fetch.

Relevant part of my .unison/dotfiles.prf:

root = /home/khouli/dotfiles
root = ssh://other_machine//home/khouli/dotfiles
ignore = BelowPath .git

Note that BelowPath matches exactly the path .git. So depending on the project structure ignore = Name .git may be better suited. More details on pathing in Unison here.

Relevant part of my sync script:

unison dotfiles
(cd $HOME/dotfiles && git fetch)
ssh other_machine 'cd dotfiles && git fetch'

This syncs the files themselves and the commit history. It doesn't sync staging but that's not too important and it might not even be desirable. This also requires that both machines have an appropriate network connection for a git fetch. Otherwise git bundle like VonC suggests could be used.

This is just here incase anyone comes here from google and finds it useful. I'm not marking it as accepted because it'd be interesting if an answer showed up with a way to live sync a git repo.

Elimination answered 25/7, 2015 at 18:39 Comment(0)
S
2

A byte-by-byte sync here doesn't work because even with the same files and git state the internal git files may be different.

That is why you don't synchronize a .git folder (other have tried with dropbox, the result was not satisfactory)

I would recommend using git bundle, but the process can be a bit convoluted.

There are other tools for managing and synchronizing dotfiles. One very good one is RichiH/vcsh, presented in GitMinutes #13, and in this blog post.

Sequestrate answered 25/7, 2015 at 17:32 Comment(4)
Are you saying the whole thing is a no-go for live sync?Elimination
@Elimination not with git repo anyway. Git isn't mean't to be live sync'd, but has been used to managed dotfiles.Sequestrate
I should have clarified this originally but is live syncing a git repo and all the git state across machines inherently impossible as of now? By that, I mean does something about git make that task itself non-sensical or do satisfactory solutions just not exist? Thanks.Elimination
@Elimination yes, this is still a no-go for live sync. If "all git states" covers hooks and configuration, then it definitively is not possible, as hooks and config remain local to the repo.Sequestrate

© 2022 - 2024 — McMap. All rights reserved.