about summary refs log tree commit diff stats
path: root/dev/git/branch.html
blob: 89ac8a98aaa2d3b7f6eaf030b94500cb1131be28 (plain) (blame)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
    <meta charset='utf-8'>
    <title>Git branches</title>
</head>
<body>

    <a href="index.html">Git Index</a>

    <h1>3. Git branches</h1>

    <p>Branches in git are "cheap" and easy, they allow to help maintain the information, both locally and remotely.</p>

    <h2 id="teamwork">3.1. Team workflow</h2>

    <p>This work flow is based on
    <a href="http://nvie.com/posts/a-successful-git-branching-model/">Vicent Driessen</a> and <a href="http://www.bitsnbites.eu/a-stable-mainline-branching-model-for-git/">Marcus Geelnard</a> branch strategies, it defines rules how branches are forked, merged and tagged. By having well defined set
    of branches, the project structure is used as a communication
    tool, allowing to work simultaneously on different stages of the development.</p>

    <p>Main Branches;</p>

    <pre>
    ___A___________AB_____ Master
        \___B_____/ \____  Develop
    </pre>

    <p>A represents a commit, then code forked into develop and a commit B was made, develop was the merged back to master AB.</p>

    <dl>
        <dt>master</dt>
        <dd>Current stable release history, it only contains merges, develop, hot-fix and release branches.</dd>
        <dt>develop</dt>
        <dd>Where new features are merged and tests are performed, if all tests pass is to forked to release.</dd>
    </dl>

    <p>Development branches;</p>

    <pre>
    _A_______________________AF_______________ Master
      \                    /   \_AFHBH_/       Hotfix
                   __AFHB_/                    Release
       \__________/___________________________ Develop
         \_F_/                                 Feature
    </pre>

    <dl>
        <dt>feature (f-)</dt>
        <dd>Feature only contain isolated features, improvement proposal, code review, integration tests, etc.</dd>
        <dd>Only fork and merge from/to develop, when only local use rebase to keep update with develop branch.</dd>
        <dt>hotfix (h-)</dt>
        <dd>Hotfix only contain isolated bugfixes.</dd>
        <dd>Only fork from master, merges back to master and develop.</dd>
    </dl>

    <p>Code support branches;</p>
    <pre>
    _______________________________AFHB___ Stable-X.Y
    __AF_________________________/________ Master
           \_AFH_/ \            /\         Hotfix
                    \   __AFHB_/  \        Release
    _________________\_/___________\______ Develop
    </pre>

    <dl>
        <dt>release (r-)</dt>
        <dd>Next release, only bug fix's are allowed to be merged.</dd>
        <dd>Major releases fork from develop, merges to master and develop.</dd>
        <dt>stable (stable-)</dt>
        <dd>Sable major (X) and minor (Y) release branch, each commit correspond to patch level (Z) with a tag name-(X.Y.Z). Only cherry pick hotfixes from master or next branched security patch level.</dd>
    </dl>

    <h3 id="feature">3.2. Feature</h3>

    <p>Create a branch featurex from develop and checkout;</p>
    <pre>
    $ git checkout -b featurex develop
    </pre>

    <p>Initial feature commit;</p>

    <pre>
    $ git commit -m "added new feature X"
    </pre>

    <p>Other feature commit;</p>

    <pre>
    $ git commit -m "better implementation and tests."
    </pre>

    <p id="rebase">Prepare for testing and merge back;</p>

    <pre>
    $ git checkout featurex
    $ git rebase -i develop
    </pre>

    <p>Run test's, fixes are implemented;</p>

    <pre>
    $ git commit -m "feature X tests fix's."
    </pre>

    <p>Rebase strategy is cleaner than merge. When pushed to remotes merge strategy can be used or use force push. To run remote tests, code review etc, push branch to server;</p>

    <pre>
    $ git push -u origin featurex
    </pre>

    <p>Rename a branch, if all feature branches start by "f-" is easy and quick to type and easy to spot;</p>

    <pre>
    $ git branch -m featurex f-xpto
    </pre>

    <p id="push">Rename remote branch;</p>

    <pre>
    $ git push origin :featurex f-xpto
    $ git push origin -u f-xpto
    </pre>

    <p id="merge">Merge branch feature into develop, first make sure is update with develop and history is clean;</p>

    <pre>
    $ git checkout featurex
    $ git rebase -i develop
    </pre>

    <pre>
    $ git checkout develop
    Switched to branch 'develop'
    $ git merge --no-ff f-xpto
    Updating ea1b82a..05e9557
    (Summary of changes)
    $ git push origin develop
    </pre>

    <p>Delete Remote</p>

    <pre>
    $ git push origin :f-xpto
    </pre>

    <p>Delete Local;</p>

    <pre>
    $ git branch -D f-xpto
    </pre>

    <h3 id="release">3.3. Release</h3>

    <p>Software release numbers follow <a href="http://semver.org/">Tom Preston-Werner</a>
    description;</p>

    <pre>
    projectname-X.Y.Z.tar.xz
    </pre>

    <dl>
        <dt>X</dt>
        <dd>Major version, backwards incompatible API changes.</dd>
        <dt>Y</dt>
        <dd>Minor version, backwards-compatible changes.</dd>
        <dt>Z</dt>
        <dd>Patch level, backwards-compatible bug and security fixes.</dd>
    </dl>

    <p>There are patch level or minor new features and major releases. New features releases and major releases fork from develop, code is freeze to let keep adding new features to develop while preparing the code to merge to master and back to develop.</p>

    <pre>
    $ git checkout -b r-1.2.0 develop
    Switched to a new branch "release-1.2.0"
    $ ./bump-version.sh 1.2.0
    Files modified successfully, version bumped to 1.2.0.
    $ git commit -a -m "Bumped version number to 1.2.0"
    [release-1.2 74d9424] Bumped version number to 1.2.0
    1 files changed, 1 insertions(+), 1 deletions(-)
    </pre>

    <p>Only documentation or bugfixes are allowed in this
    branch. When release is ready for production tests merge
    and push to master;</p>

    <pre>
    $ git checkout master
    Switched to branch 'master'
    $ git merge --no-ff r-1.2.0
    Merge made by recursive.
    </pre>
    <h3 id="tags">3.4. Tags</h3>

    <p>There are two main types of tags, lightweight and
    annotated. Lightweight tag is a pointer to a specific commit,
    much like cheap branches. Annotated tags are stored as full objects
    and allow to sign with <a href="gnupg.html">gnupg</a>, making it ideal
    for distributing releases.</p>

    <p id="tag">Tags are used to mark patch releases, get back in time to make security patches or to mark a new major or minor new release. Tag new release with projectname-version, this allows meaningful ports <a href="../linux/ports.html">distfiles</a> when downloading releases from git archives;</p>

    <pre>
    $ git tag -a projectname-1.2.0 -m "project 1.2.0 release"
    $ git push origin projectname-1.2.0
    </pre>

    <p>To push all local tags;</p>

    <pre>
    $ git push --follow-tags
    </pre>

    <p>Update branch develop with bugfixes from last release,
    conflict will happen in next step</p>

    <pre>
    $ git checkout develop
    Switched to branch 'develop'
    $ git merge --no-ff r-1.2.0
    Merge made by recursive.
    (Summary of changes)
    $ git push
    </pre>

    <p>Delete local and remote;</p>

    <pre>
    $ git tag -d projectname-0.0.12
    $ git push origin :refs/tags/software-name-0.8
    </pre>

    <p>List local tags;</p>

    <pre>
    $ git tag --list
    </pre>

    <h3 id="hotfix">3.5. Hotfix</h3>

    <p>Hotfix are done in master, the only exceptions are release and stable branches. When hot fix is applied to a stable branch is not included in future releases, only needed when cherry pick is hard or impossible. When hot fixes are done on release branches, as described on this document, they have short duration, hot fixes should relate only to new code. To create a hot/bug fix;</p>

    <pre>
    $ git checkout -b h-error-name master
    </pre>

    <p>Merge the branches with bug fixes;</p>

    <pre>
    $ git merge --no-ff b-error-xpto
    ...
    $ git commit -m "Commit severe fix"
    ...
    $ git merge --no-ff b-error-xpto
    ...
    $ git commit -m "Commit severe fix"
    ...
    $ git rebase -i master
    </pre>

    <p>Merge the hotfix back to master;</p>

    <pre>
    $ git checkout master
    Switched to branch 'master'
    $ git merge --no-ff h-error-name
    Merge made by recursive.
    </pre>

    <p>On stable branches cherry pick the commit;</p>

    <pre>
    $ git checkout stable-1.1
    $ git checkout -b r-1.1.2
    $ ./bump-version.sh 1.1.2
    Files modified successfully, version bumped to 1.1.2
    $ git commit -a -m "Bumped version number to 1.1.2"
    $ git cherry-pick h-error-name
    $ git checkout stable-1.1
    $ git merge --no-ff r-1.1.2
    $ git tag -a projectname-1.1.2
    </pre>

    <p>Conflicts happen in previews and next step;</p>

    <pre>
    $ git checkout develop
    Switched to branch 'develop'
    $ git merge --no-ff h-error-name
    Merge made by recursive.
    (Summary of changes)
    </pre>

    <pre>
    $ git -D r-1.1.2
    $ git -D h-error-name
    </pre>

    <p id="cherry-pick">Some times is useful to pick the last commit that affected a path on other branch. To achieve this first get last commit that affected the path;</p>

    <pre>
    $ git checkout upstream
    $ git log -n 1 -- path/dir/or/file.c
    $ git checkout stable-3.4
    $ git cherry-pick 9ce8b280e7081ec3c122b228cfa76600251ea6c9
    </pre>

    <a href="index.html">Git Index</a>
    <p>This is part of the LeetIO System Documentation.
    Copyright (C) 2021
    LeetIO Team.
    See the file <a href="../../fdl-1.3-standalone.html">Gnu Free Documentation License</a>
    for copying conditions.</p>
</body>
</html>