aboutsummaryrefslogtreecommitdiff
path: root/doc/sync.mdwn
blob: 52beddf9a03857bd4e708ca4c2a4f5491b0e1872 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
The `git annex sync` command provides an easy way to keep several
repositories in sync. 

Often git is used in a centralized fashion with a central bare repository
which changes are pulled and pushed to using normal git commands.
That works fine, if you don't mind having a central repository.

But it can be harder to use git in a fully decentralized fashion, with no
central repository and still keep repositories in sync with one another.
You have to remember to pull from each remote, and merge the appopriate
branch after pulling. It's difficult to *push* to a remote, since git does
not allow pushes into the currently checked out branch.

`git annex sync` makes it easier using a scheme devised by Joachim
Breitner. The idea is to have a branch `synced/master` (actually,
`synced/$currentbranch`), that is never directly checked out, and serves
as a drop-point for other repositories to use to push changes.

When you run `git annex sync`, it merges the `synced/master` branch
into `master`, receiving anything that's been pushed to it. Then it
fetches from each remote, and merges in any changes that have been made
to the remotes too. Finally, it updates `synced/master` to reflect the new
state of `master`, and pushes it out to each of the remotes.

This way, changes propagate around between repositories as `git annex sync`
is run on each of them. Every repository does not need to be able to talk
to every other repository; as long as the graph of repositories is
connected, and `git annex sync` is run from time to time on each, a given
change, made anywhere, will eventually reach every other repository.

The workflow for using `git annex sync` is simple:

* Make some changes to files in the repository, using `git-annex`,
  or anything else.
* Run `git annex sync` to save the changes.
* Next time you're working on a different clone of that repository,
  run `git annex sync` to update it.

## automatic merge conflict resolution

The sync process involves merging a branch into your currently checked out
branch. This could lead to a merge conflict, perhaps because the same file
got changed in two different ways. An extra feature of `git annex sync` is
that it automatically resolves these merge conflicts, rather than leaving
git in the middle of a conflicted merge.

If this occurs, there will be several messages printed about the merge
conflict, and the file that has the merge conflict will be renamed, with
".variant-XXX" tacked onto it. So if there are two versions of file foo,
you might end up with "foo.variant-AAA" and "foo.variant-BBB". It's then
up to you to decide what to do with these two files. Perhaps you can
manually combine them back into a single file. Or perhaps you choose to
rename them to better names and keep two versions, or delete one version
you don't want.

The "AAA" and "BBB" in the above example are essentially arbitrary
(technically they are the MD5 checksum of the key).