Source control branches are an important feature that works great in team projects. A developer can create a new line of code from a specific point in time, revision, or tag. In this way, developing new features, creating releases, and making bugfixes or hotfixes can be done safely and subjected to team revision, and/or automatic integration tools (such as tests, code coverage, lint tools). A branch can be merged with other branches until it finally reaches the main line of code, called the master branch.
But let's get our hands on a practical exercise. Let's say that we want to develop a new feature. Our first chapter example displays the traditional "Hello World" message, but we want it to say "good morning" to the users. First, we create a branch from a special branch called the feature/good-morning that for now is a copy of the master branch, as shown in the following code:
# Display our branches
$ git branch
* master
# Create a branch called feature/good-morning from master
$ git branch feature/good-morning
# Display our branches again
$ git branch
feature/good-morning
* master
# Check out the new feature/good-morning branch
$ git checkout feature/good-morning
This could be resumed to the following:
$ git checkout -b feature/good-morning master
Now let's change our code to display good morning to the visitors of a certain URL, along with their names. To do this, we change main.py, which looks like the following code:
@app.route('/')
def home():
return '<h1>Hello world</h1>'
We change main.py to the following:
@app.route('/username')
def home():
return '<h1>Good Morning %s</h1>' % username
Let's look at what we have done:
$ git diff
diff --git a/main.py b/main.py
index 3e0aacc..1a930d9 100755
--- a/main.py
+++ b/main.py
@@ -5,9 +5,9 @@ app = Flask(__name__)
app.config.from_object(DevConfig)
# Changed to show the git diff command
[email protected]('/')
-def home():
- return '<h1>Hello World!</h1>'
[email protected]('/<username>')
+def home(username):
+ return '<h1>Good Morning %s</h1>' % username
if __name__ == '__main__':
app.run()
Looks good. Let's commit, as shown in the following code:
$ git commit -m "Display good morning because its nice"
[feature/good-morning d4f7fb8] Display good morning because its nice
1 file changed, 3 insertions(+), 3 deletions(-)
Now, if we were working as part of a team, or if our work was open source (or if we just wanted to back up our work), we should upload (push) our code to a centralized remote origin. One way of doing this is to push our code to a version control system, such as Bitbucket or GitHub, and then open a pull request to the master branch. This pull request will show our changes. As such, it may need approval from other team members, and many other features that these systems can provide.
For our example, let's just merge to the master, as shown in the following code:
# Get back to the master branch
$ git checkout master
Switched to branch 'master'
bash-3.2$ git log
commit 139d121d6ecc7508e1017f364e6eb2e4c5f57d83 (HEAD -> master)
Author: Daniel Gaspar
Date: Fri May 4 23:32:42 2018 +0100
Our first commit
# Merge our feature into the master branch
$ git merge feature/good-morning
Updating 139d121..5d44a43
Fast-forward
main.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
bash-3.2$ git log
commit 5d44a4380200f374c879ec1f7bda055f31243263 (HEAD -> master, feature/good-morning)
Author: Daniel Gaspar
Date: Fri May 4 23:34:06 2018 +0100
Display good morning because its nice
commit 139d121d6ecc7508e1017f364e6eb2e4c5f57d83
Author: Daniel Gaspar <[email protected]>
Date: Fri May 4 23:32:42 2018 +0100
Our first commit
As you can see from the output, Git uses the fast-forward strategy by default. If we wanted to keep an extra commit log message that mentions the merge itself, then we could have used the --no-ff flag on the git merge command. This flag will disable the fast-forward merging strategy.
Now imagine that we regret our change and want to revert the feature that we have just created back to an earlier version. To do this, we can use the following code:
$ git revert
With Git, you can actually delete your commits, but this is considered a really bad practice. Note that the revert command did not delete our merge, but created a new commit with the reverted changes. It's considered a good practice not to rewrite the past.
What was shown is a feature branch simple workflow. With big teams or projects, the use of more complex workflows is normally adopted to better isolate features, fixes, and releases, and to keep a stable line of code. This is what is proposed when using the git-flow process.
Now that we have a version control system, we are ready to cover Python's package management system.