Home iOS & Swift Books Advanced Git

9
Feature Branch Workflow Written by Jawwad Ahmad

In the previous chapter, you learned how to work directly on the master branch using the Centralized Workflow, which is convenient in certain situations.

Most of the time, however, you’ll use some version of the Feature Branch Workflow. Before starting on a new feature, you’ll create a branch from master and work on it. Once you’re done, you’ll merge the feature branch back into master.

Creating a feature branch essentially gives you your own frozen version of the master branch. It also allows you to delay pushing your commits to master until your feature is complete, which keeps the master branch in a more stable state for everyone.

In previous chapters, you learned how to create branches, rebase branches, resolve conflicts and merge your branches back into master.

In this chapter, you’ll learn how to use these techniques effectively in a team setting — that is, when multiple developers are working on branches, which they’ll merge into master periodically.

You’ll also learn best practices around rebasing and merging, and will pick up a few tips and tricks along the way.

When to use the Feature Branch workflow

There are a few limited scenarios where the Centralized Workflow is a good fit. In all other situations, you’ll use some form of the Feature Branch Workflow.

The Feature Branch Workflow is the basis of all other Git workflows like Gitflow and the Forking Workflow.

Based on your team’s needs, you may choose to use a simple version of this workflow, or you may decide to adopt additional requirements, such as specifying that developers need to name feature branches a certain way or use a specific prefix with them.

The following are are a few scenarios in which you’d certainly need to use the feature branch workflow.

When developing features in parallel

When working in a team, it’s often not feasible to wait until one developer has completed their work before another developer starts. Developers need to work on multiple features, in parallel, within the same codebase.

When your code needs a review

Regardless of team size or how many features you work on at once, you must use feature branches if you need other developers to review your code.

When sharing code still in development

Feature branches allow you to share code before you merge it into master. For example, you might need code that another developer is currently working on, and so isn’t available in master yet. In this scenario, you can create your branch from another branch that has the code you need.

When collaborating on a feature

Branches allow you to collaborate with other developers while working on new features. Multiple developers can work on a shared branch, then merge that branch into development when they’ve completed the feature.

Getting started

As in the previous chapter, you’ll simulate working on a team by playing the role of different developers. However, you’ll switch roles a bit more in this chapter.

starter
└── repos
    ├── alex
    │   └── checklists
    ├── beth
    │   └── checklists
    ├── chad
    │   └── checklists
    └── checklists.git
cd path/to/starter/repos/alex/checklists  # 1st Tab
cd path/to/starter/repos/beth/checklists  # 2nd Tab
cd path/to/starter/repos/chad/checklists  # 3rd Tab
cd path/to/starter/repos/checklists.git   # 4th Tab

Initial project state

The team has been hard at work on two feature branches. Alex has been working on alex-feature, while Beth and Chad have been working together on a shared branch named beth-chad-feature.

Solid nodes are on the remote, dashed nodes are local commits
Duyud gayil ome ez rhu cubiqo, begmos qozus uwi kifow bejxotn

git log --oneline --graph --all
* b2deca5 (beth-chad-feature) C5: Added <footer> to <body>
* 4fbfda4 B5: Moved <h1> and <p> within <header>
| * 51bdc3c (HEAD -> master) C4: Updated section styling to u...
| * 6a52517 C3: Added "Introduction" section
| * fcb3dbc C2: Added background-color css for section
|/
* 6bc53bb C1: Added "Morning Routine Checklist" section
...

Project roadmap

As mentioned previously, you’ll be switching roles a bit more in this chapter — not just because Chad joined the team, but also because there’s a lot more to do. :]

Importance of updating branches with master

There are two main reasons to update your branches with new code in master.

How to update branches with master

There are two ways of updating your branches with master: You can either rebase your branch onto master or you can merge the master branch into your local branch.

Updating the two project branches

Since alex-feature hasn’t been pushed to origin yet, you’ll rebase it onto master. And since beth-chad-feature has been pushed to origin, and Beth and Chad share it, you’ll merge master into it instead.

git log --oneline --graph --all
* b2deca5 (origin/beth-chad-feature) C5: Added <footer> to <b...
* 4fbfda4 B5: Moved <h1> and <p> within <header>
| * 9f06a73 (HEAD -> alex-feature) A6: Added "Evening Routine...
| * 427b5ee A5: Added h2 color to style.css
| | * 51bdc3c (origin/master, origin/HEAD, master) C4: Update...
| | * 6a52517 C3: Added "Introduction" section
| |/
| * fcb3dbc C2: Added background-color css for section
|/
* 6bc53bb C1: Added "Morning Routine Checklist" section
...
git log --oneline --graph alex-feature master
* 9f06a73 (HEAD -> alex-feature) A6: Added "Evening Routine C...
* 427b5ee A5: Added h2 color to style.css
| * 51bdc3c (origin/master, origin/HEAD, master) C4: Updated ...
| * 6a52517 C3: Added "Introduction" section
|/
* fcb3dbc C2: Added background-color css for section
* 6bc53bb C1: Added "Morning Routine Checklist" section
...
Current position of the alex-feature branch
Wuyzogp rapataav ox kka abiw-coeteli pcipzw

git rebase master
Position of alex-feature after running: git rebase master
Cukomuap er ojic-qaujeko onlav yiscilt: wis sowiho hahrud

git log --oneline --graph alex-feature master
* 28d0ae5 (HEAD -> alex-feature) A6: Added "Evening Routine C...
* b0f7244 A5: Added h2 color to style.css
* 51bdc3c (origin/master, origin/HEAD, master) C4: Updated se...
* 6a52517 C3: Added "Introduction" section
* fcb3dbc C2: Added background-color css for section
* 6bc53bb C1: Added "Morning Routine Checklist" section
...
git log --oneline --graph --all
* 19f8c99 (HEAD -> beth-chad-feature) B6: Added <hr/> in <hea...
* b2deca5 (origin/beth-chad-feature) C5: Added <footer> to <b...
* 4fbfda4 B5: Moved <h1> and <p> within <header>
| * 51bdc3c (origin/master, origin/HEAD, master) C4: Updated ...
| * 6a52517 C3: Added "Introduction" section
| * fcb3dbc C2: Added background-color css for section
|/
* 6bc53bb C1: Added "Morning Routine Checklist" section
...
State of Beth’s local repository
Hzida og Wert’x koqil zitedemuqx

git merge master
git log --oneline --graph --all
*   fbffe40 (HEAD -> beth-chad-feature) Merge branch 'master'...
|\
| * 51bdc3c (origin/master, origin/HEAD, master) C4: Updated ...
| * 6a52517 C3: Added "Introduction" section
| * fcb3dbc C2: Added background-color css for section
* | 19f8c99 B6: Added <hr/> in <header>
* | b2deca5 (origin/beth-chad-feature) C5: Added <footer> to ...
* | 4fbfda4 B5: Moved <h1> and <p> within <header>
|/
* 6bc53bb C1: Added "Morning Routine Checklist" section
...
After merging master into beth-chad-feature
Azcof wewdilm mapmam arha futd-kheq-quozuxa

git push
After pushing beth-chad-feature to origin
Ugtux wuscugg qidj-nyab-raeguya ki azativ

git log --oneline --graph --all
* 347bcd3 (HEAD -> beth-chad-feature) C6: Removed "Routine" f...
* b2deca5 (origin/beth-chad-feature) C5: Added <footer> to <b...
* 4fbfda4 B5: Moved <h1> and <p> within <header>
| * 51bdc3c (origin/master, origin/HEAD, master) C4: Updated ...
| * 6a52517 C3: Added "Introduction" section
| * fcb3dbc C2: Added background-color css for section
|/
* 6bc53bb C1: Added "Morning Routine Checklist" section
...

git fetch
git log --oneline --graph --all
*   fbffe40 (origin/beth-chad-feature) Merge branch 'master' ...
|\
| * 51bdc3c (origin/master, origin/HEAD, master) C4: Updated ...
| * 6a52517 C3: Added "Introduction" section
| * fcb3dbc C2: Added background-color css for section
* | 19f8c99 B6: Added <hr/> in <header>
| | * 347bcd3 (HEAD -> beth-chad-feature) C6: Removed "Routin...
| |/
|/|
* | b2deca5 C5: Added <footer> to <body>
* | 4fbfda4 B5: Moved <h1> and <p> within <header>
|/
* 6bc53bb C1: Added "Morning Routine Checklist" section
...
State of Chad’s local repository after fetching Beth’s updates
Vcasa ij Fkuf’s zubiw vajigizoyn ovdal vayrlicw Yisl’q eccocuq

git pull --rebase
...
CONFLICT (content): Merge conflict in index.html
error: Failed to merge in the changes.
Patch failed at 0001 C6: Removed "Routine" from heading
hint: Use 'git am --show-current-patch' to see the failed patch
...
git am --show-current-patch
C6: Removed "Routine" from heading
...
       <section>
-        <h2>Morning Routine Checklist</h2>
+        <h2>Morning Checklist</h2>
       </section>
...
16     <main>
17 <<<<<<< HEAD
18       <section class="intro-section">
19         <h2>Introduction</h2>
20       </section>
21
22       <section class="checklist-section">
23         <h2>Morning Routine Checklist</h2>
24 =======
25       <section>
26         <h2>Morning Checklist</h2>
27 >>>>>>> C6: Remove "Routine" from headings
28       </section>
29     </main>
16     <main>
17       <section class="intro-section">
18         <h2>Introduction</h2>
19       </section>
20
21       <section class="checklist-section">
22         <h2>Morning Checklist</h2>
23       </section>
24     </main>
git add index.html
git rebase --continue
git show
C6: Removed "Routine" from heading
...
       <section class="checklist-section">
-        <h2>Morning Routine Checklist</h2>
+        <h2>Morning Checklist</h2>
       </section>
...
git push
State of Chad’s repository after rebasing and pushing
Wleki im Rjin’m seyomevumn uynaj cosojuww iwx fuczabn

Merging the branches into master

Alex is ready to push his branch up for review. He’ll do a final git fetch to see if anyone has pushed additional updates to master that he’ll need to rebase onto.

git fetch
...
From ../../checklists
 b2deca5..8aad97e  beth-chad-feature -> origin/beth-chad-feature
git log --oneline --graph alex-feature master
* 28d0ae5 (HEAD -> alex-feature) A6: Added "Evening Routine C...
* b0f7244 A5: Added h2 color to style.css
* 51bdc3c (origin/master, origin/HEAD, master) C4: Updated se...
* 6a52517 C3: Added "Introduction" section
* fcb3dbc C2: Added background-color css for section
* 6bc53bb C1: Added "Morning Routine Checklist" section
open index.html
index.html on the rebased alex-feature branch
uyxax.pkbh af mqa ritewux utoy-ruukete pwavwg

git show master
C4: Updated section styling to use a class
...
diff --git a/index.html b/index.html
     <main>
-      <section>
+      <section class="intro-section">
         <h2>Introduction</h2>
       </section>

-      <section>
+      <section class="checklist-section">
         <h2>Morning Routine Checklist</h2>
...
diff --git a/style.css b/style.css
...
-section {
+.checklist-section {
     background-color: lightcyan;
 }
+
+.intro-section {
+    background-color: lavender;
+}
-      <section>
+      <section class="checklist-section">
         <h2>Evening Routine Checklist</h2>
git add index.html
git commit --amend --no-edit
git show
       </section>
+
+      <section class="checklist-section">
+        <h2>Evening Routine Checklist</h2>
+      </section>
     </main>
open index.html
index.html on the rebased alex-feature branch with the amended commit
oymad.flhl eh jdu lijisor uyun-veovafi rvohvh joys dza idinruy rutvis

git push -u origin head
git push --set-upstream origin alex-feature  # same as above
...
To ../../checklists.git
 * [new branch]      head -> alex-feature
Branch 'alex-feature' set up to track remote branch 'alex-
feature' from 'origin'.
git fetch
...
From ../../checklists
   fbffe40..8aad97e  beth-chad-feature -> origin/beth-chad-fe...
 * [new branch]      alex-feature      -> origin/alex-feature
git pull
git checkout alex-feature
git log -p master..
git checkout master
git merge alex-feature
git push
git branch -d alex-feature
git push origin --delete alex-feature
open index.html
index.html in the beth-chad-feature branch
ugnej.hqcx ip yco vorz-pvix-leucuqi tlamgn

       <section class="checklist-section">
-        <h2>Morning Routine Checklist</h2>
+        <h2>Morning Checklist</h2>
       </section>
git fetch
...
From ../../checklists
   51bdc3c..cca927c  master     -> origin/master

git checkout master
git pull
git checkout -
Switched to branch 'beth-chad-feature'
git merge master --no-edit
open index.html
Chad’s index.html after merging master into beth-chad-shared
Npeg’t uxmic.rlcq ovdoj vugjodr xihful oglo reyq-vhom-nqegib

       <section class="checklist-section">
-        <h2>Evening Routine Checklist</h2>
+        <h2>Evening Checklist</h2>
       </section>
git commit -am "C7: Removed Routine from heading"
open index.html

git push
git fetch
...
From ../../checklists
 8aad97e..cde0da3  beth-chad-feature -> origin/beth-chad-feature
 51bdc3c..cca927c  master            -> origin/master
git checkout master
git pull
git checkout beth-chad-feature

git checkout beth-chad-feature
git rebase master
First, rewinding head to replay your work on top of it...
Applying: B5: Moved <h1> and <p> within <header>
...
Applying: C5: Added <footer> to <body>
...
Applying: B6: Added <hr/> in <header>
Applying: C6: Removed "Routine" from heading
..
Applying: C7: Removed Routine from heading
git log -p -2
C7: Removed Routine from heading
...
       <section class="checklist-section">
-        <h2>Evening Routine Checklist</h2>
+        <h2>Evening Checklist</h2>
       </section>
...

C6: Removed "Routine" from heading
...
       <section class="checklist-section">
-        <h2>Morning Routine Checklist</h2>
+        <h2>Morning Checklist</h2>
       </section>
...
git rebase -i head~2
pick 0383368 C6: Removed "Routine" from heading
pick 4652fdc C7: Removed Routine from heading
pick 0383368 C6: Removed "Routine" from heading
f 4652fdc C7: Removed Routine from heading
git show
C6: Removed "Routine" from heading
...
       <section class="checklist-section">
-        <h2>Morning Routine Checklist</h2>
+        <h2>Morning Checklist</h2>
       </section>

       <section class="checklist-section">
-        <h2>Evening Routine Checklist</h2>
+        <h2>Evening Checklist</h2>
       </section>
...
git checkout master
git merge beth-chad-feature
git push
git branch -d beth-chad-feature
warning: not deleting branch 'beth-chad-feature' that is not yet
merged to 'refs/remotes/origin/beth-chad-feature', even though
it is merged to HEAD.
error: The branch 'beth-chad-feature' is not fully merged.
If you are sure you want to delete it, run 'git branch -D beth-chad-feature'.
git push origin --delete beth-chad-feature
git branch -d beth-chad-feature

Key points

  • In the Feature Branch Workflow, you create a branch any time you want to work on a new feature.
  • You should update your branch periodically with new changes in master.
  • You must update your branch with master before pushing it up for review.
  • You can incorporate changes from master by either rebasing your branch onto master or by merging master into your branch.
  • If you’re working on a local or private branch, it’s better to rebase your branch onto master.
  • Never rebase public branches; instead, merge master into the branch to prevent rewriting history.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2020 Razeware LLC

You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.