misc
[gitolite-doc.git] / locking.mkd
blob65bc6121f7ae9608fa59e56e6b3a02e109e7d008
1 <!-- options: toc -->
3 % locking binary files
5 include sidebar-toc
7 Locking is useful to make sure that binary files (office docs, images, ...)
8 don't get into a merge state.  (<font color="gray">If you think it's not a big
9 deal, you have never manually merged independent changes to an ODT or
10 something!</font>)
12 **When git is used in a truly distributed fashion, locking is impossible.**
13 However, in most corporate setups, there is a single central server acting as
14 the canonical source of truth and collaboration point for all developers.  In
15 this situation it should be possible to at least prevent commits from being
16 pushed that contains changes to files locked by someone else.
18 The two "lock" programs (one a command that a user uses, and one a VREF that
19 the admin adds to a repo's access rules) together attempt to achieve this.
21 Of course, locking by itself is not quite enough.  You may still get into
22 merge situations if you make changes in branches.  For best results you should
23 actually keep all the binary files in their own branch, separate from the ones
24 containing source code.
26 ----
28 # problem description
30 Our users are alice, bob, and carol.  Our repo is foo.  It has some "odt"
31 files in the "doc/" directory.  We want to make sure these odt files never get
32 into a "merge" situation.
34 # admin/setup
36 First, someone with shell access to the server must add 'lock' to the ENABLE
37 list in the rc file.
39 Next, the gitolite.conf file should have something like this:
41 .#! conf/vim-color
42     repo foo
43         ...other rules...
44         -   VREF/lock      =   @all
45 .end
47 However, see below for the difference between "RW" and "RW+" from the point of
48 view of this feature and adjust permissions accordingly.
50 # user view
52 Here's a summary:
54   * Any user with "W" permissions to any branch in the repo can "lock" any
55     file.  Once locked, no other user can push changes to that file, *in any
56     branch*, until it is unlocked.
57   * Any user with "+" permissions to any branch in the repo can "break" a lock
58     held by someone else if needed.
60 For best results, everyone on the team should:
62   * Switch to the branch containing the binary files when wanting to make a
63     change.
64   * Run 'git pull' or eqvt, then lock the binary file(s) before editing them.
65   * Finish the editing task as quickly as possible, then commit, push, and
66     unlock the file(s) so others are not needlessly blocked.
67   * Understand that breaking a lock require additional, (out of band)
68     communication.  It is upto the team's policies what that entails.
70 # detailed example
72 Alice declares her intent to work on "d1.odt":
74     $ git pull
75     $ ssh git@host lock -l foo doc/d1.odt
77 Similarly Bob starts on "d2.odt"
79     $ git pull
80     $ ssh git@host lock -l foo doc/d2.odt
82 Carol makes some changes to d2.odt (**without attempting to lock the file or
83 checking to see if it is already locked**) and pushes:
85     $ ooffice doc/d2.odt
86     $ git add doc/d2.odt
87     $ git commit -m 'added footnotes to d2 in klingon'
88     $ git push
89     <...normal push progress output...>
90     remote: FATAL: W VREF/lock testing carol DENIED by VREF/lock
91     remote: 'doc/d2.odt' locked by 'bob'
92     remote: error: hook declined to update refs/heads/master
93     To u2:testing
94      ! [remote rejected] master -> master (hook declined)
95     error: failed to push some refs to 'carol:foo'
97 Carol backs out her changes, but saves them away for a "manual merge" later.
99     git reset HEAD^
100     git stash save 'klingon changes to d2.odt saved for possible manual merge later'
102 Note that this still represents wasted work in some sense, because Carol would
103 have to somehow re-apply the same changes to the new version of d2.odt after
104 pulling it down.  **This is because she did not lock the file before making
105 changes on her local repo.  Educating users in doing this is important if this
106 scheme is to help you.**
108 She now decides to work on "d1.odt".  However, she has learned her lesson and
109 decides to follow the protocol described above:
111     $ git pull
112     $ ssh git@host lock -l foo doc/d1.odt
113     FATAL: 'doc/d1.odt' locked by 'alice' since Sun May 27 17:59:59 2012
115 Oh damn; can't work on that either.
117 Carol now decides to see what else there may be.  Instead of checking each
118 file to see if she can lock it, she starts with a list of what is already
119 locked:
121     $ ssh git@host lock -ls foo
123     # locks held:
125     alice   doc/d1.odt      (Sun May 27 17:59:59 2012)
126     bob     doc/d2.odt      (Sun May 27 18:00:06 2012)
128     # locks broken:
130 Aha, looks like only d1 and d2 are locked.  She picks d3.odt to work on.  This
131 time, she starts by locking it:
133     $ ssh git@host lock -l foo doc/d3.odt
134     $ ooffice doc/d3.odt
135     <...etc...>
137 Meanwhile, in a parallel universe where d3.odt doesn't exist, and Alice has
138 gone on vacation while keeping d1.odt locked, Carol breaks the lock.  Carol
139 can do this because she has RW+ permissions for the repository itself.
141 However, protocol in this team requires that she get email approval from the
142 team lead before doing this and that Alice be in CC in those emails, so she
143 does that first, and *then* she breaks the lock:
145     $ git pull
146     $ ssh git@host lock --break foo doc/d1.odt
148 She then locks d1.odt for herself:
150     $ ssh git@host lock -l foo doc/d1.odt
152 When Alice comes back, she can tell who broke her lock and when:
154     $ ssh git@host lock -ls foo
156     # locks held:
158     carol   doc/d1.odt      (Sun May 27 18:17:29 2012)
159     bob     doc/d2.odt      (Sun May 27 18:00:06 2012)
161     # locks broken:
163     carol   doc/d1.odt      (Sun May 27 18:17:03 2012)      (locked by alice at Sun May 27 17:59:59 2012)