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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
Branches are handy for developing larger features (especially if you
temporarily break muse and then fix it again). You might want to ask
why you shouldn't simply develop in your local working copy, and then
commit a huge chunk. Well, this has multiple reasons:
o with branches, you'll have a history, because there are many small
commits. this makes bisecting for finding a bug possible.
o when you develop your feature publicly, others can check out half-done
versions, and already test the one half. they also could fix bugs.
o another advantage of keeping it public is: others can see whether you
may exclude some use case and inform you about that in time. otherwise
you'd spend lots of work in a design which was obsolete from the
beginning.
o and it shows that there's something going on :)
also, branching makes "feature freezes" easier, for release planning.
General note: ^/trunk means [url of the repo]/trunk. when you're inside
a working copy, svn understands the ^/trunk notation.
i assume you're inside some working copy
whenever merging, make sure you're in the correct directory!
CREATING A BRANCH
the following command creates a branch called yourbranch in the branches
directory, which is built upon the current (NOT the checked out!) trunk
revision:
svn copy ^/trunk ^/branches/yourbranch
svn copy does a "light copy", that is, as long as you don't change files,
they don't occupy any disk space.
USING THE BRANCH
you might want to checkout every branch relevant to you into another local
copy. believe me, it makes life easier. alternatively, svn switch is your
friend.
just develop inside the working copy, then commit.
MERGING WITH THE PARENT BRANCH (in my example: the trunk)
from time to time, you want to update your branch to represent the
current trunk plus your changes (and not an ancient trunk plus your
changes). to be safe, only merge with the parent branch, and only
merge in one direction (usually from trunk into your branch), unless
you know what you're doing. if you're reading and not skimming this,
you're probably NOT knowing. svn help and google are your friends.
be in your branch'es working directory root (the dir which is containing
all the files/dirs also trunk (the parent) is containing as well.
svn merge ^/trunk --accept postpone
does the job for you. there might be conflicts, when both in your branch
and in trunk some file has been changes at a similar location. svn by
default asks you what to do then, which is annoying. --accept postpone
turns this off, and gives you a summary at the end of the merge.
If There Were Conflicts:
if any file in "svn status"'s output has a C in front of it, there are
conflicts. open the file in your editor, and look for markers like
"<<<<<", "=====" and ">>>>>". these show what code is in the trunk
(between <<<< and ====), and what code is in your branch (between
==== and >>>>) (or vice versa. svn tells you).
you have to make it work again and save the file.
with "svn resolved FILENAME" or "svn resolved -R some/directory" you
mark the conflicts for FILENAME or all files below some/directory as
solved.
Another word about conflicts: there may be conflicts, even if svn doesn't
note them. ALWAYS recompile the merged code and test it.
if done, you can commit the merge normally using "svn commit"
PUTTING YOUR WORK BACK INTO THE PARENT BRANCH (in my example: trunk)
do a final merge from your parent branch into your branch. compile and
test.
then there are several ways to proceed:
o use svn merge --reintegrate, which doesn't work with the old repo
version muse is using :(
o go into the trunk (or the parent branch'es directory), and issue
svn merge ^/branches/yourbranch --accept theirs-full
the problem with the merge is, that every previous merge from trunk
into your branch will be applied a second time, which doesn't work.
--accept theirs-full will basically use the files in your branch.
you might want to verify with diff:
diff -R /path/to/local/trunk /path/to/local/yourbranch
there should be no differences.
commit that to trunk: svn commit
then, "fake-merge" trunk into your branch again. otherwise, with the
next merge from trunk into your branch, we would have the duplicate
changes problem again. if you're _SURE_ that you aren't using the
branch any more, you can leave this step out.
svn merge ^/trunk ^/branches/yourbranch --record-only
svn commit
this solution is a bit hackish :( but it works
NOTES FOR RELEASE BRANCHES
after creating the release branch, ALL commits which are fixing bugs
must go into the release branch. ALL commits which are adding features
must go into trunk or other branches.
the team should focus on fixing bugs in the release branch.
to get the fixes into the trunk, from time to time run:
svn merge ^/branches/releasebranch ^/trunk
svn commit (in trunk's local copy)
when releasing the release branch, merge it into the trunk a last time,
and then never touch the release branch again.
for the next release, create a new one.
TAGGING
when there's any reason for tagging a revision, simply do
svn copy ^/whatever ^/tags/yourtagname
read the svn manual for details
GETTING HELP:
svn help <command> (usage notes, short explanations)
google (everything)
the svn book (->google) (long explanations)
|