summaryrefslogtreecommitdiff
path: root/doc/bugs/git-annex_branch_corruption.mdwn
blob: 9c864d85f08fe35c832ae7e2263c3c7621713952 (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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
Below is a test case which shows a way that the git-annex branch
can become corrupted and lose data, including location log records and
uuid.log lines.

At the end, a commit on the git-annex branch removes one of the 2 lines
from the uuid.log; which should never happen.

The actual problem occurs earlier, at the "push point". Here a repo is
cloned from the main one, initialized (adding the last uuid.log line),
and then pushed back to the main one. That push is a fast-forward, so is
allowed to directly update the git-annex branch in the main repo:

	b884fe5..c497739  git-annex -> git-annex

Now the git-annex branch has a change that is not reflected in
`.git/annex/index`, so the next time a change is made, it's committed
using the out of date index, which causes a reversion of the changes
that were pushed to the branch.

---

## Thoughts

This is essentially the same reason why git blocks pushes to the checked-out
branch of a non-bare repository. 

This problem only affects workflows that involve pushing. Pulling workflows
do not directly update the local git-annex branch, so avoid the problem.

And while bare repos are pushed to, they rarely have changes made directly
to their git-annex branches, so while I think the same problem could
happen with pushing to a bare repo, it's unlikely.

None of which is to say this is not a bad bug that needs to be comprehensively
fixed. 

Probably git-annex needs to record which ref of the git-annex branch
corresponds to its index, and if the branch is at a different ref,
merge it into the index.

> And now that's [[done]]. I managed to do it with very little slowdown.
> 
> A side benefit is that users can now safely check out the git-annex
> branch and commit changes to it, and git-annex will notice them.
> Before, it was documented to ignore such changes.
> --[[Joey]] 

---

## Workaround

Users who want to prevent this bug from occuring when pushing to their
non-bare repositories can install this script as `.git/hooks/update`

<pre>
#!/bin/sh
if [ "$1" = refs/heads/git-annex ]; then
	exit 1
fi
</pre>

--[[Joey]] 

---

## Test Case
<pre>
#!/bin/sh
mkdir annextest
cd annextest

git init dir1
cd dir1
git annex init
touch foo 
echo hi > bar
git annex add
git commit -m add

cd ..
git clone dir1 dir2
cd dir2
git annex init otherdir
git annex get
# push point
git push

cd ..
cd dir1
echo "before"
git show git-annex:uuid.log
git annex drop foo --force
echo "after"
git show git-annex:uuid.log
</pre>