github-flow-course from web
credit to https://jkettmann.com
credit to https://jkettmann.com
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Use Git like
professional teams
A course about the GitHub Flow
Find an interactive version of this course at ooloo.io
"I have no idea how to use
Git in a professional dev
team."
You've been coding for a while now and feel somewhat comfortable with it. But
when it comes to using Git you still fumble around.
You know how to commit your code. Maybe you have worked with branches
here and there. But for the most part, you've been working on the "master"
branch on your own.
And to be honest, you've been fine.
At the same time, you know that you'll have to work with a team of
developers eventually. You'll have to collaborate with other professionals on
a common code-base. So there's the question:
How do real dev teams in real companies use Git?
You know there should be best practices and workflows. But the tutorials you
find are just too basic or abstract. How are you supposed to learn the Git
workflows of the pros?
What if you could experience a
professional Git workflow?
You read correctly. What if you could not only learn how to use Git in a team,
in theory, but experience it hands-on? And what if you had the help of
resources that go into depth and cover edge cases on top of that?
You could get your Git knowledge on par with your coding skills. And once you
need it in real life you could navigate through the Git workflow with a clear
head.
You'd be independent of the help of the senior devs.
At least a bit. But how can you get real experience in a Git workflow used by
teams without the essential ingredient: a team?
An interactive Git course to learn
the GitHub flow
Learn how to use Git in a team with a workflow that is used in many companies
around the world: the GitHub flow.
Unlike other interactive Git tutorials you won't work inside the browser in a
fake environment but rather in a real developer environment:
on your machine inside your editor
using the command line
with a repository on GitHub
with professional branch protection rules.
Don't worry, you don't need to know all of this already. You'll get resources and
a roadmap so you can guide yourself through the process during the course.
And in real life.
Now, where exactly does the team
part come into play?
This is where it gets really interesting. You will have a bot teammate who
helps you along the way. She will collaborate with you by reviewing your
code, requesting changes, and implementing features.
You as well will have to review the code so you can see both sides of the table.
You'll work on multiple branches at the same time and run into merge conflicts.
Just like in a real team.
This way you will really experience what it feels like to work in a team of
developers using a professional Git workflow.
This course is completely free
You don't have to pay and you don't need to subscribe to anything. I'd
appreciate it if you could share this course with your friends though.
Also, if you're a React developer and enjoy this experience have a look at
my other course. It has a similar approach but teaches many more professional
skills by building a guided project based on designs and tasks. Just like a realworld
project.
Note that this course doesn't cover the very basics of Git. You're
expected to know at least a bit about commits and branches. More advanced
topics like merging, squash merging, and rebasing are covered in the course
material though.
Ready to learn how professional teams use Git?
Who am I?
Hi, I'm Johannes Kettmann, the creator of this course.
I'm a self-taught fullstack JS developer and know the struggle of learning how to
work professionally with Git first-hand.
When I started to code I had no clue about version control. At first, everything
was simple. I wrote tiny programs that fit into a single file. Once my files grew
larger and larger and I started breaking existing code keeping track of previous
versions seemed smart.
The perfect solution at the time was to create folders with names like "2010-04-
23 15:23" to host the corresponding version of my code.
Didn't work out that well of course.
Finally, I realized there was an existing tool called Git that can help with
versioned code. I was excited.
I happily committed to the master branch and pushed to my custom Git server.
Better, but still not the smartest idea.
At some point, I landed my first professional job. And it was overwhelming. I had
to understand the code base and figure out how to work with other developers.
And last but not least, using Git in a team was totally different from what I was
used to.
I wasn't allowed to commit to the sacred master branch anymore. Instead:
Atomic commits, feature branches, releases, code reviews, merge, rebase...
It took me years to get fully used to that. And honestly, I'm still learning.
I hope that this course can help you to get up to speed much faster and in a
safe environment. Maybe you don't have to experience the same stress and
anxiety I had to go through back in the days.
Mindset
To get into the right mindset think of this course the following way:
You are a developer in a company that wants to build a new project. A product
manager already created a handful of tasks that you need to implement.
You have a teammate called ooloo-bot who is there to support you. She will
help you with code reviews and also implement a task or two. But since she's a
senior developer she has a lot on her plate.
You know, meetings and so on.
Since you work for a serious company they require you to use a professional
Git workflow that can also be used by larger teams and ensures code quality
by utilizing code reviews.
Now it's your turn to kick off the project
Note: If you're stuck somewhere or find something difficult to
understand I most probably didn't explain myself very well. It would
help me if you could let me know by contacting me on Twitter.
Git workflows
In this course, you will learn and use the GitHub flow. You might be asking: Why
this workflow and not another one?
Good question.
Two very popular Git workflows out there are:
1. Git flow
2. GitHub flow
I won't go into the details of Git flow. The quick answer why we don't use it here
is
it's quite complicated with a lot of branching conventions
it's most useful for versioned software like desktop applications.
Since a lot of the software that's written today doesn't require strict versioning
(e.g. web applications) Git flow is often overkill. Even the original author
discourages developers to use it in most situations.
GitHub flow on the other hand is much more lightweight. Thus it's a great
starting point to get into using Git in a team environment.
The Flow
As mentioned the GitHub flow is relatively lightweight. This is what it looks like
in a nutshell:
1. Create a new branch to implement the feature (or bugfix...).
2. Implement the code and add commits to the branch.
3. Push the code to the remote repository on GitHub.
4. Open a Pull Request on GitHub.
5. The code gets reviewed and discussed.
6. Merge the branch to the main branch (aka master ).
This may look very simple at first. But it can get quite complicated when
used in a team. More on that on the next page.
For now, here's some lingo explanation:
When you build a feature on a branch it is called feature branch.
A Pull Request or PR is a place where your team can review and discuss the
code changes.
GitHub replaced the default master branch with main . Mental note: main
= master
You can see a more interactive description of the GitHub flow here. I
left out the Deploy step since it's different for every team and depends
on their setup.
These are only 6 steps and only a couple of them require you to use Git
yourself. The most basic Git commands you need are
git branch to create a branch
git checkout to switch branches
git commit to add changes
git push to update the remote repository
git pull to sync your local repository with the remote
You don't even need to merge yourself in the command line since you'll simply
press a button in the Pull Request.
By the way, no worries if you're not used to working on branches yet.
You'll get there. But I hope you heard of most of these commands. Otherwise,
make yourself familiar with a bit of research.
Note: Even though it's called GitHub flow you can use this flow on
GitLab or BitBucket as well. The important thing is that you use Pull
Requests to merge your code to the main branch (also called Merge
Requests on GitLab)
When it gets complicated
Until now the GitHub flow seems relatively straightforward. But there wouldn't
be a whole course about it when it wouldn't get a bit more complicated.
The problem starts when you use it in a team. That's because software
development in a team is not a sequential process. In a team, you don't work on
one feature until it's done and merged and only then continue with the next
task.
Usually, several developers are working on different branches at the same time.
But even a single developer is often working on multiple branches.
For example, this is a typical situation: You implement a feature on one branch.
Once you're done you request a review. But it might take hours or even days
until the code is reviewed. In the meantime, you have to continue working on
something else and create another branch while the first one is still active.
This quickly gets complicated. Especially, if there are multiple open Pull
Requests at the same time which might even depend on each other.
To summarize: When you work on a project alone this workflow is still easy.
But when you're in a team a lot of the headache and confusion are related to
keeping everything in sync.
A Roadmap
When using Git professionally for the first time you might feel a bit lost in the
process.
That's why I created this roadmap. To be honest, it might look a bit
intimidating at first. But no worries. We'll use it together throughout this
course. I'll explain it step by step so you can slowly get used to it.
Feel free to download the roadmap or open it in another browser tab. Keep it at
hand since we'll need it soon.
Design & Tasks
Remember? You're a developer working for a company that wants to create a
project.
Admittedly the project isn't very exciting. It's a very basic website with only a
handful of elements.
But this course is about the Git workflow and not about the code. So no worries,
you don't need any HTML or CSS skills. I'll give you all the code ready to be
copy & pasted.
Here is the beautiful design. Could win awards, huh?!
Let's quickly break this down into tasks that we can then implement one
by one. Just as if we were in a professional team
Tasks
We can see a header and a footer as well as two content sections in between.
Let's create one task per element. So that's four in total.
Additionally, we can add one task to create a container around the content
sections. This container will be responsible for centering its content.
To summarize, we have 5 tasks
1. Header
2. Footer
3. Content Container
4. Top Section
5. Bottom Section
Great! Now it's time to get our hands dirty
The Repository
As mentioned before you'll work with a real repository that is hosted on GitHub.
You'll change the files on your local machine and commit and push the code
changes to GitHub. You'll open real Pull Requests and your teammate ooloo-bot
will write comments and create code reviews.
You'll get access to your personal repository on GitHub. But since we want to
pretend that you work in a real team the repo will be created under the oolooio
account. You will have restricted access and there will be certain rules in
place. The main branch will be protected so you can't
push directly to the main branch (aka master)
merge a PR without approval from ooloo-bot
create merge commits.
You'll see what that means in detail later on.
These rules are very common in real teams. They enforce that all the code is
reviewed before it's merged to the main branch. They are thus essential for
keeping code quality and security high.
Create your repository
Before we start implementing the tasks create your repository. First, you have
to login with your GitHub account by clicking the button below.
No worries, I don't store any personal data besides your GitHub username which
is required to set up the repo. I won't contact you in any way.
Once you're logged in click the button again to create the repository. This
will take a moment. You'll be invited to the repo and see a link below the button
to accept the invitation.
Note: I might remove old repositories from time to time. If you'd like to
have yours transferred to your account once you're done with the
course please contact me on Twitter.
Once that's done clone the repository on your local machine. You can find the
repository URL when you click the green button on the main page as shown in
the screenshot. Or you simply fill in your username in the command below.
Now run the git clone command with that URL in a terminal on your local
machine.
git clone git@github.com:ooloo-io/github-flow-{YOUR_USERNAME}.git
The repo only contains a few files. During this course, we will just touch the
index.html and styles.css files in the src folder.
If you want to have a look at the website while we're adding the code you can
make use of the local development server that comes with the repo. You need
npm on your machine though.
This is not required. So feel free to skip the following steps.
npm install
npm start
Now you should be able to see a placeholder text when you visit localhost:5000.
Great, we're ready to start with the first task.
Planning
As you probably remember we have 5 tasks to implement in total:
1. Header
2. Footer
3. Content Container
4. Top Section
5. Bottom Section
The first task is to implement the header as you can see in this image.
Fair enough. Shouldn't be too complicated.
But what are we supposed to do in the context of the GitHub flow? That's where
the roadmap you saw earlier comes in. Let's start by taking a look at it and
getting some orientation.
Now it's your turn
Where are we on the roadmap? Try to answer the following questions:
1. Which path will we take on the roadmap to implement the header?
2. What is the next Git command we will use?
Got the answers?
Implementation
We want to develop a new feature. That means we are on the left side below
Feature Implementation.
We start the new feature Header. Since it's the first feature there aren't any
open PRs it could depend on.
So the first thing we do is create a new branch from main .
Note: When working with Git you might be used to the name master
as the main branch. GitHub, like other companies, decided to rename
the master branch to main to remove references to slavery. So if
you're confused just make a note in your head
main = master
Create a new branch
As a branch name, it's always good to choose something descriptive. Most
teams have some convention that involves the name or ID of the task they work
on in some form. In this course, we will use the name of the task.
Go ahead, open the command line, and create a new branch called header
with the following command.
git checkout -b header
The checkout command in combination with the -b option creates a new
branch from the current branch ( main ) and checks it out.
Note: We use the command line in this course because it's most
flexible. Using the CLI can seem a bit scary at first but you'll get used
to it with a bit of practice. I personally often use a combination of the
VS Code Git integration plus the command line.
The next step on the roadmap is commit and push changes.
Commit and push changes
Before we can commit anything we need to write some code. Since this course
is not about learning or using a particular language I'll provide the code here.
You just have to copy & paste it.
Note: Please make sure that the files on your machine have the same
content as shown here. Some lessons will only work correctly if the
files are identical.
First, open the file src/index.html in your favorite editor and adjust the
content of the body tag as shown in the highlighted lines. You can also copy
the whole code.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GitHub Flow Course</title>
<meta name="description" content="GitHub Flow Course">
<meta name="author" content="Johannes Kettmann">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/norm
alize.min.css">
<link rel="stylesheet" href="styles.css">
</head>
<body>
+ <header class="header">
+ Header
+ </header>
</body>
</html>
We'll add some styles in a bit. Usually, it would make more sense to commit the
changes in the markup and the styles together. But for the sake of the practice
let's create a commit with this small code change already.
git add .
git commit -m "Add header markup"
Next, we add the styles. Open the file src/styles.css and add the
highlighted lines.
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
+
+.header {
+ height: 50px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-bottom: 1px solid black;
+}
Let's create another commit for the styles.
git add .
git commit -m "Add header styles"
Perfect. We're done with the implementation. Let's have another look at the
roadmap to see where we're at.
We're currently at the step commit and push changes. We committed already
so we only need to push to GitHub.
git push origin header
origin in the above command is the remote repository we want to push to.
Here, that's our repo on GitHub.
Hint: You can list all remote repositories including their URLs by
running git remote -v .
Open a Pull Request
We committed and pushed our code changes. So the next step on our roadmap
is to open a PR.
There are multiple options to create a Pull Request. Two of them are
using the link in the terminal output after pushing the code
via the GitHub website
After pushing your code you should see an output like in the screenshot below
inside the terminal. When you read the text carefully you can see that it
includes a link that you can click to create a PR.
Alternatively, you can open your repository on GitHub. You should see a banner
like the one in the following screenshot.
Either way, you'll be directed to a page with a form to create the Pull Request.
The title is already filled in. If the branch has multiple commits GitHub uses the
branch name as the default title (like here). If there's only a single commit it
uses the commit message. In that case, you might want to adjust the title.
Most teams have naming conventions for Pull Requests. Often it's the name of
the task, a task ID, or a combination of both. Here we use the task name.
Your responsibility as a teammate is to add a descriptive body to the PR so that
your co-workers can understand what your code is about. But honestly, I
couldn't think of anything more creative than "Implements the header task.
Adds markup and styles." at this time.
Finally, click the green Create pull request button on GitHub. Once you're
done come back here and continue on the next page.
Request a review
Let's take a last look at our roadmap to see what's next.
On the last page you opened your first Pull Request. That means our next and
final step is to request a review.
Great! Head back to your newly created PR on GitHub. You can find a section
called Reviewers inside the right-side menu. Click the gear icon ⚙.
This is what you should see.
You can see your dear friend and teammate ooloo-bot there as a suggestion.
Go ahead. Don't be shy and request a review. You should hear back from her in
a few seconds.
Note: At the bottom of the page you can also see that you can't merge
the Pull Request without getting a review first. That's because the
settings of the repository on GitHub require a code review.
Geat! We're done with this part of the roadmap. The final step leads us back to
the beginning so we're free to start the next feature.
But before we can start with the next feature you might have seen already that
there are some news.
PR is approved
A few seconds after you requested the review you should see this on the Pull
Request page.
Wow, that was quick. ooloo-bot already approved the PR without any
complaints.
Lucky you.
How do we continue now? Have another look at the roadmap and try to answer
the following questions:
1. Which path will we take on the roadmap now that the PR is approved?
2. What is the next Git command we will use?
Got the answers?
Merging the PR
Once the Pull Request has been approved we're on the right side of the
roadmap below the Code Review box.
Since the PR is already approved we can answer the first question with No. So
we continue with merging the branch by clicking the green button in the PR.
When you click the button you'll be asked for a title and a description. Every
team has different conventions here. In our case you can leave the default
Header (#1).
Note: The advantage of having the number of the PR in the commit
message is that you always know which changes on the main branch
belong to which PR.
Go ahead and click the green Squash and merge button. Once you're done
come back and continue on the next page.
Update the local repository
We clicked the merge button in the Pull Request. So the next step on the
roadmap is pull main.
By merging the Pull Request on the GitHub website we added all the code
changes from the header branch to the main branch. But we don't have
these changes on our local machine yet.
To update our local repo with the latest changes we need to run the git pull
command on the main branch.
So open your terminal again, check out the main branch, and pull the changes.
git checkout main
git pull origin main
The output that you see from the pull command should look something like
this.
Great. Now our local branch is up-to-date. We're ready to continue with the next
feature.
But before we dive into the code again let's have a quick theory lesson to
understand what just happened.
Merge vs. Squash Merge
If you're familiar with working on branches you probably know the git merge
command already. With this command, you can incorporate commits from one
branch into another.
For example, if we wanted to have the commits from the header branch in our
main branch we could run the following commands.
Note: Don't run the commands on your machine since the branch is
already merged.
git checkout main
git merge header
This is what the commit history in our case would look like before and after the
merge.
Before the merge, we only have the "Initial commit" on the main branch and
two additional commits "Add header markup" and "Add header styles" on
header . The two commits on the header branch are the ones you added.
After the merge, the two commits from the header branch have been copied
on to the main branch. Both branches now contain the exact same commits.
Note: we might have an additional merge commit in case of conflicts
between the branches.
By default, GitHub does a merge as described above. But not in our case.
You may have realized already that the button in the PR didn't just say Merge
but rather Squash and merge.
Squash Merge
Many professional teams use a different setup for their GitHub repositories.
They require a linear history which means that they don't allow merge commits
in the main branch.
One option to prevent merge commits to appear is to run the git merge
command with the squash option . This is what happened when you clicked
the green button.
Note: Don't run the commands on your machine since the branch is
already merged. This is to illustrate what GitHub does behind the
scenes.
git checkout main
git merge --squash header
Now, what does it mean to run git merge --squash ?
It means that all the commits from the header branch are combined (or
squashed) into a single commit and then added to the main branch. This is
what it looks like visually.
Here you can see that the commits b and c from the header branch are
combined into one commit b' on the main branch. The commit message of
the combined commit is Header (#1) .
That's the title that was suggested by GitHub when you merged the PR. Here
the screenshot again as a reminder.
The advantage of squash merging
In a typical team environment with code reviews, you often see small commits
with messages like fix xyz or update according to code review . These
are not great commit messages. But realistically, that's what you encounter
often.
The advantage of squash merging is that you don't have these
commits in your main branch. Instead you have only one commit per Pull
Request or feature. This makes it a lot easier to reason about the commit
history later on and attribute changes to tasks.
See for yourself
If you want to see the history on your local machine for yourself run the git
log command on both branches. I like to use the oneline option to have a
more concise output.
git log --oneline header
The commit history on my header branch looks like this
Now check out the main branch and run the git log command there again.
You should see something like this.
That's exactly what we saw in the squash merge diagram above.
Great, after this piece of theory let's get our hands dirty again and start the
next task: the footer.
Planning
As you probably remember we have 5 tasks to implement in total:
1. Header
2. Footer
3. Content Container
4. Top Section
5. Bottom Section
The header is done already which means the next task is implementing the
footer.
Looks basically the same as the header, right?
It's time to have a look at the roadmap again. Try to answer the following
question:
Which path will we take on the roadmap to implement the footer?
Got the answer?
Implementation
The answer is simpler than you might think. I didn't try to trick you. We'll follow
the same path as before in the header task.
Again we want to develop a new feature that doesn't depend on any open PRs.
So we start on the left side below Feature Implementation.
Since you already have some experience follow the path until the step
commit and push changes by yourself.
Reminder: The name of the branch should correspond to the name of
the task.
First commit
Once you're at the step commit and push changes open the file
src/index.html in your editor and adjust its content like follows.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GitHub Pull Request Flow Course</title>
<meta name="description" content="GitHub Pull Request Flow
Course">
<meta name="author" content="Johannes Kettmann">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/norm
alize.min.css">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="header">
Header
</header>
+ <footer class="footer">
+ Footer
+ </footer>
</body>
</html>
As in the header task, let's already create a commit that only contains the
markup changes.
Note: If you can't commit the code and see an error message like the
below in the terminal the name of your branch is not accepted.
I added this check to ensure that the bot is working correctly. You can
see the list of accepted branch names in the output. If you need to
rename your branch you can use this command
git branch -m NEW_BRANCH_NAME
Second commit
Once you committed the changes open the file src/styles.css and adjust it
as follows.
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
.header {
height: 50px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
}
+
+.footer {
+ height: 50px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-top: 1px solid black;
+}
Again commit the changes to your feature branch. Finally, push the changes to
GitHub.
Now follow the next steps on the roadmap.
Once you requested a review you should get feedback by ooloo-bot in a
couple of seconds. She'll tell you what to do next.
The Fix
At this point, you probably saw the new Pull Request by ooloo-bot that
includes a bug fix for the header.
Now you can see the process from the other side and be the code reviewer
yourself.
Review the file changes
To review the changes click on the Files changed drawer. Here you can see all
the changes included in the PR.
You can click on one of the line numbers and add a comment to give feedback.
Try it out if you like but don't expect anyone to answer
Finally, if you're pleased with the code changes (which I hope you are) click the
green Review changes button.
Select the Approve option in the radio button group and optionally add a
comment. Finally, click the green Submit Review button at the bottom.
Merge the PR
Now the merge button should turn green. Go ahead and press on Squash and
merge.
Since the Pull Request contains only a single commit, the commit message is
used to prefill the form field.
Let's stick to our convention and use the PR title instead. Replace Decrease
header height (#3) by Fix: Header (#3).
Finally, confirm the merge.
Recap
Congrats, you reviewed your first Pull Request. By now you have seen the
GitHub Flow in it's simplest form from both perspectives: as the author and the
reviewer of a PR.
You already started to get a taste of some real teamwork. And soon the GitHub
Flow will become a bit more complicated.
Continue with footer
Now that the fix of the header is merged we can continue working on the footer
task.
Check your PR. ooloo-bot should have reviewed your code by now.
This time we didn't get an immediate approval. ooloo-bot found something to
complain about. That means we have some more work to do on the footer task.
Before we start implementing the change requests let's have a quick look at the
roadmap again to see where we're at. And one more time, try to answer the
following questions:
Which path will we take on the roadmap to implement the footer?
Got the answer?
Change Requests
We received a code review so we're again on the right side of the roadmap. The
first question changes requested? can be answered with yes.
As for the second question: There's currently no active branch beside the
footer branch. That means no branch can depend on the code inside the
footer branch. So the answer to does a branch depend on the new
changes? is no.
Thus the flow looks like this.
The first step is to check out the PR branch (meaning footer ). At this point,
you should still be on that branch. Otherwise, check it out.
Note: if you're not sure which branch you're on you can run git
status or git branch and check the output.
The next step on the roadmap is commit and push changes.
Change 1: Show footer at the
bottom
Your teammate is right. When you run the development server with npm start
and visit the page you can see that the footer is directly below the header.
Doesn't look good, right?
Let's fix this. Open the file src/index.html . We'll add an element between the
header and footer that takes up the required space to place the footer at the
bottom.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GitHub Pull Request Flow Course</title>
<meta name="description" content="GitHub Pull Request Flow
Course">
<meta name="author" content="Johannes Kettmann">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/norm
alize.min.css">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="header">
Header
</header>
+ <main class="content"></main>
<footer class="footer">
Footer
</footer>
</body>
</html>
Next, open the file src/styles.css and add the .content class.
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
.header {
height: 50px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
}
.footer {
height: 50px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid black;
}
+
+.content {
+ min-height: calc(100vh - 100px);
+}
Now commit these changes before you continue.
Change 2: Fixing the footer height
We've seen it already in the fix for the header. The height of the footer has to be
1px less since it has a top border.
Open the file src/styles.css again and change the footer height to 49px .
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
.header {
height: 50px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
}
.footer {
+ height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid black;
}
.content {
min-height: calc(100vh - 100px);
}
Great. Now commit this change as well.
Finally, push the new commits to GitHub.
Re-request a review
The last step on the roadmap is request new review.
Inside the Pull Request on GitHub, you can see a refresh icon that you can
click to re-request a review.
You should get feedback by ooloo-bot after a few seconds.
Note: Feel free to resolve the conversations here by clicking the button
in the screenshot below. In a real team I'd leave that up to the
reviewer though.
Update the local repository
At this point, the footer PR should be merged. You may not have realized but we
already started another round on the roadmap.
We requested a new review and ooloo-bot already approved. That means
we're again on the right side of the roadmap. She didn't request any changes
and we already merged the branch.
So the next step on the roadmap is pull main.
The changes from the footer branch are inside the main branch on GitHub
but not in our local repository yet.
So go ahead, checkout the main branch and pull the latest changes. When
So go ahead, checkout the main branch and pull the latest changes. When
you have a look at the history you should see two new commits on main : one
for the header fix and one for the footer.
Once you're done, it's time for the next task: the content container.
Planning & Implementation
By now we implemented two tasks: the header and footer. Three more are left:
3. Content Container
4. Top Section
5. Bottom Section
The content container will be the element that is responsible for setting a
maximum width to the content and center it horizontally.
You're on your own
You've been through this process a couple of times now. For this task, I'll only
provide the code. You can use the roadmap to navigate through the process.
Once you request a code review ooloo-bot will tell you what to do next.
The code
The code change is very small. Since we already added a content container in
the markup we just have to work on the styles.
Add the two highlighted lines to the file src/styles.css .
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
.header {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
}
.footer {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid black;
}
.content {
min-height: calc(100vh - 100px);
+ width: 720px;
+ margin: auto;
}
These lines set a fixed width to the container and center it horizontally.
Now use the roadmap and your Git magic. We'll see each other after the code
review
Note: If you need some help feel free to check out the next page. But
give it a try yourself first
Hint
In case you're unclear about what to do now here's the path on the roadmap
you need to take.
It's the same path as in the tasks before. You need to
Create a new feature branch. (The branch name should be the name of the
task, words separated by a dash)
Implement the changes
Commit and push the code.
Create a Pull Request.
Request a review.
Follow these steps before continuing on the next page. ooloo-bot will
Follow these steps before continuing on the next page. ooloo-bot will
give you feedback a few seconds after you requested the review.
Planning
You just opened a PR for the Content Container task, right? Now that we're
waiting for the review we can start with the next task.
There are only two tasks left.
4. Top Section
5. Bottom Section
As you saw in the comment that ooloo-bot left in the Pull Request she would
like to take over the Top Section task.
So the only thing left for us is to implement the bottom section.
You know the drill
It's time to answer some questions again.
1. Which path will we take on the roadmap to implement the bottom section?
2. What is the next Git command we will use?
Got the answers?
Implementation
We're about to start the task Bottom Section which is a new feature. So we're
on the left side of the roadmap.
The only difference to the tasks before is, that the bottom section depends on
a task that is still in review: the content container. The reason is that the
bottom section is a child of the content container. So all changes in the content
container may affect the bottom section as well.
That's why we need to answer the question does it depend on an open PR?
with yes.
Seems like a small difference from the path we used before. But it will make
things much more complicated.
Create a new branch
The code of the content container task is not yet merged and thus not in the
main branch. But we need it to start with the bottom section.
The solution is to create a new feature branch from content-container . This
way we can start building the bottom section on top of the existing commits for
the content container.
Make sure the branch content-container is checked out and run the same
command as always:
git checkout -b bottom-section
Now let's write some code.
Note: If you want to verify that everything went fine you can have a
look at the commit history.
git log --oneline
You should see the commits from the main branch as well as the one
from the content-container branch.
You can find the code changes to both files below.
I leave you alone again. Follow the roadmap and ooloo-bot will tell
you how to continue.
The code changes
Let's start with the markup again. Open the file src/index.html and add the
bottom section to the content container.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GitHub Pull Request Flow Course</title>
<meta name="description" content="GitHub Pull Request Flow
Course">
<meta name="author" content="Johannes Kettmann">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/norm
alize.min.css">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="header">
Header
</header>
+ <main class="content">
+ <section class="section">
+ Bottom section
+ </section>
+ </main>
<footer class="footer">
Footer
</footer>
</body>
</html>
Next, open the file src/styles.css and add the highlighted lines.
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
.header {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
}
.footer {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid black;
}
.content {
min-height: calc(100vh - 100px);
width: 720px;
margin: auto;
}
+
+.section {
+ height: 450px;
+ width: 100%;
+ margin-top: 20px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: 1px solid black;
+}
Please create a single commit with the message "Add bottom section"
this time. It'll make it easier for you to follow along in a bit.
Now use the roadmap and your Git magic. Once you request a code review
ooloo-bot should give you feedback in a matter of seconds. She'll tell you
what to do next.
See you then
Note: If you need some help feel free to check out the next page. But
give it a try yourself first
Hint
In case you're unclear about what to do now here's some help. You need to run
the same commands as in the tasks before.
Implement the changes.
Commit and push the code.
Create a Pull Request.
Request a review.
Follow these steps before continuing on the next page. ooloo-bot will
give you feedback a few seconds after you requested the review.
Change Requests
At this point, you requested a review for the Bottom Section Pull Request that
you just opened. In the meantime, ooloo-bot already reviewed the Content
Container PR and left a change request.
The change doesn't seem to take a lot of effort. But what do we have to do
in terms of Git?
Another look at the roadmap
Have a look at the roadmap again and try to find the right path to implement
the change request for the Content Container.
Did you find the path?
Update Pull Request
You received a code review by your teammate ooloo-bot . That means we're
on the right side of the roadmap.
The answer to the first question changes requested? is yes so we take a turn
left. The first part of the path looks like this.
That means the next step is to checkout the PR branch contentcontainer
.
Implementing the changes
ooloo-bot explained that the content-container is not responsive. We should
set a max-width .
No problem. Simply add the highlighted line to the file src/styles.css .
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
.header {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
}
.footer {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid black;
}
.content {
min-height: calc(100vh - 100px);
width: 720px;
+ max-width: 100%;
margin: auto;
}
Great! Now commit and push the change. Finally, request a new review and
wait for feedback by ooloo-bot .
Incorporate changes
On the previous page, we only had a look at the first part of our path on the
roadmap to update the Content Container PR.
As a reminder: these are the steps we already took.
But what is the answer to the second question: does a branch depend on the
new changes in the content-container branch?
The answer is yes because we created the bottom-section branch from the
content-container branch.
This is what our complete path looks like.
The next few steps that we need to take are
1. check out the bottom-section branch
2. push the branch
3. rebase the bottom-section on the content-container branch
Don't worry if you don't know what rebase means. We'll get into that on the
next page.
For now, check out the bottom-section branch and push it (shouldn't have
any effect but just to be sure).
Rebase
It's time for another round of Git theory. This time we'll have a closer look at the
git rebase command.
When you rebase one branch b on another branch a Git changes the commit
history of branch b by
1. applying all commits from branch a
2. applying all commits from branch b .
Then all commits from branch a are included in branch b .
This may sound a bit abstract and might be hard to understand. So let's see
some more images of the Git history.
The current commit history
visualized
In our case, we currently have three active branches: main , contentcontainer
, and bottom-section . The current commit history looks like this.
Note: your commit messages might be different than the ones in the
image below.
The main branch contains a couple of commits with the last being the squashmerge
commit from the Footer PR ( a in the above image).
The content-container branch contains everything from main plus two
additional commits: b from before the code review and c that implements the
change requests.
The bottom-section branch was created from content-container when
there was only one commit ( b ). Then we implemented the feature in the
commit d .
Now the goal is to incorporate the commit c in our bottom-section branch.
Commit history after rebase
visualized
Once we rebase the bottom-section branch on the content-container
branch we should have a commit history like this.
After the rebase we have all the commits from the content-container branch
in our bottom-section branch as well.
Note: the commit on the bottom-section branch is called d' now
instead of d . That's because it's technically a newly created commit
with a new ID (or hash).
Confirm your current commit
history
First of all, let's have a look at the commit history on your local machine to
confirm the first image. Run the git log command for each branch. The
output on my machine looks like this.
That looks like the visualization of the commit history before the rebase above. I
hope yours does as well.
From theory to practice
After all this theory the practice is surprisingly simple. We just have to run the
following command while we're on the bottom-section branch.
Note: before you rebase always make sure that you pushed the code.
As I said, the rebase command changes the commit history. If
something goes wrong you might lose parts of your code.
git rebase content-container
When you run this command you should see the following output in the
terminal.
Finally, let's double-check our commit history by running git log again. This
is what my output looks like.
You can see here that the bottom-section branch now includes all the
commits of the content-container branch.
So we achieved our goal.
Also, have a close look at the hash of the Add bottom section commit.
Compare it to the one you saw before the rebase. For me, the hash before the
rebase was be19827 but now it's c53f370 . That means that Git didn't just
copy this commit on top of the new commit history. It replaced the old commit
with a newly created one.
Double-check
The rebase worked without any problems. So the next step on our roadmap is to
double-check that everything is working.
Making sure that everything still works as expected is important because we
still have an old copy of the branch on GitHub. In the next step, we will
overwrite the remote version. If something went wrong we can't undo the
changes anymore at that point.
The commits from the content-container branch as well as from the
bottom-section branch are only changing the src/styles.css file.
Open this file and check that the max-width is still set on the content
container and that the .section class is present as highlighted below.
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
.header {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
}
.footer {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid black;
}
.content {
min-height: calc(100vh - 100px);
width: 720px;
+ max-width: 100%;
margin: auto;
}
+.section {
+ height: 450px;
+ width: 100%;
+ margin-top: 20px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: 1px solid black;
+}
If everything is alright you can continue with the next step on the roadmap:
force push.
Force Push
After the rebase the bottom-section branch in our local repository contains
one commit with a new hash (for me c53f370 on the previous page). But the
branch in the remote repository on GitHub still has the old version of the
commit (hash be19827 for me).
Git doesn't know how to handle this situation. If you try to push the branch via
git push origin bottom-section
you should see an error in the terminal. You can try it for yourself.
The git push command has an option -f to force the push. This means we
force GitHub to overwrite the remote branch with our local version.
Note that it's only safe to force push this way if you're the only developer
working on the branch. Otherwise, you might overwrite changes that another
developer created. That might result in some angry reactions.
In general, it's a better idea to use the lesser known force-with-lease
option.
Run the following command to update the remote repository.
git push --force-with-lease origin bottom-section
Note: If you still had the Pull Request on GitHub open in your browser it
might look a bit weird now with duplicated commits. Once you refresh
the duplicates should be gone.
Great! We're at the end of the review path of the roadmap.
News in the Content Container PR
Maybe you received a notification already? By now ooloo-bot has reviewed
the Content Container Pull Request again.
Go ahead and open it on GitHub before you continue.
Interactive Rebase
By now ooloo-bot should have approved your Content Container Pull
Request. If you haven't done yet please go ahead and merge the PR.
Once you merge the PR the situation gets a bit more complicated. The main
and the bottom-section branch both contain the code from the contentcontainer
branch you just merged. But because of the squash merge, they
have different commits.
To get a better understanding let's have a look at the commit history again.
The current commit history
Before the merge we had two commits on the content-container branch,
remember? Now that it is merged the two commits were squashed into a single
commit on the main branch.
The problem is now that we still have the two commits from contentcontainer
inside the bottom-section branch. They are the purple
commits in the below image. Only the orange commit actually belongs to the
bottom-section branch.
Let's confirm that by quickly looking at the commit history of the main and
bottom-section branches.
Note: you have to pull the latest changes from the main branch to
your local repo first.
Why is this a problem?
We have commits in the bottom-section that don't belong there. You may
ask: "So what? We'll squash the commits anyway. They won't appear in the
main branch."
The problem becomes clear when you view the File changes in the Pull
Request on GitHub.
See that GitHub highlighted the changes in the .content class as if they
belonged to the Bottom Section PR? But we never touched the .content
class in this PR. These changes originated from the content-container
branch.
The reviewer might be confused: "Didn't I already review this code
before?"
Now in a real team, you typically would have larger PRs with many more code
changes. Your teammates would have to review parts of the code twice which is
very time-consuming and annoying. They might even refuse to review the PR.
Better get rid of these two commits
Great idea. But how do we remove specific commits from our history?
This is where the git rebase command comes in again. It has a powerful
This is where the git rebase command comes in again. It has a powerful
option -i or --interactive which makes it a Swiss Army knife for editing
the commit history.
Let's see how we would like our commit history to look like first. Instead of the
current history
the cleaned-up version should look like this:
Here you don't see the purple commits that belonged to the content-
Here you don't see the purple commits that belonged to the contentcontainer
branch anymore. The corresponding code is now in the commit
Content Container (#4).
That looks like a clean commit history.
Interactive Rebase
Altering the commit history is always a bit exciting. It may feel like working
without a safety net since we change the history for good.
That's why it's again important to push the branch to have a backup in case
something goes wrong.
Next, make sure you're on the bottom-section branch.
git checkout bottom-section
And finally, we run the magic command.
git rebase -i main
Once you run this command an editor will open inside your terminal.
Note: If you're unlucky the editor might be VIM. Nothing against VIM, it
can be very powerful. But a lot of beginners don't even know how to
close it again. I remember the first time I came in contact with VIM I
thought I had to shut down my computer to exit!
If that's the case for you have a look here to end the nightmare and
see this page to see how you can select another editor.
When you run the interactive rebase you should now see something like this.
You see the list of commands below the commits!? Quite a lot of things you can
do. From editing commit messages over squash merging to executing bash
commands (!!).
We simply want to remove the top two commits though. That's pretty easy by
replacing the pick at the beginning of the lines with drop or d . It's even
easier to just remove the lines altogether (which is mentioned in the second last
line).
I simply remove the lines with the top two commits that belonged to the
content-container branch.
Now save and exit the editor. You can just overwrite the existing file if you're
asked.
This is what you should see.
Great! Everything seems to have worked fine.
Double-check
Let's quickly verify that the commit history looks as expected. Run the git
log command on the bottom-section branch. This is how my output looks
like.
This looks as expected. Only one commit is left on the bottom-section
branch.
Finally, let's have a quick look at the file src/styles.css to see if the
.content and .section classes are still correct.
.content {
min-height: calc(100vh - 100px);
width: 720px;
max-width: 100%;
margin: auto;
}
.section {
height: 450px;
width: 100%;
margin-top: 20px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid black;
}
For me, everything is still in place. Hopefully for you too.
Force push
The last step on the roadmap is again to force push our changes to update the
remote repository.
Once you pushed you can check the file changes in the Bottom Section PR on
GitHub. Inside the styles, you should only see changes in the .section class
and not the .content class as before.
Recap
Great job! You learned about the awesome interactive rebase command and
used it in practice. Seems like we're done for now.
Another PR
But wait. Have you seen it already? ooloo-bot created a new PR.
Maybe you remember that she wanted to take over the Top Section task.
Well, she finished the feature and wants your review.
Have a look at the code changes. They look pretty similar to what we have in
the bottom-section branch. With slight differences though in the markup and
the .content class. These will lead to merge conflicts later on.
Before you continue with the next page quickly approve and merge the Top
Section PR on GitHub.
Merge Conflicts
Since you're here you merged the Top Section Pull Request that ooloo-bot
created. Those changes are now included in the main branch.
Unfortunately, we have a problem. When you have a look at the Bottom
Section PR you'll see that there are merge conflicts.
This means that the files that are listed as Conflicting files have been touched in
the main branch as well as in the bottom-section branch. They have been
changed in a way that Git doesn't know what to do. We'll understand the reason
later on.
Note: GitHub gives two options to resolve the merge conflict: the web
editor or the command line. The web editor might seem like the easier
choice but I would refrain from using it. Even for small conflicts, you
might introduce an error that is easily caught by a Linter or other
tooling.
How do we continue now with our Git workflow? Let's have another look at the
roadmap.
We didn't have any change requests and already merged the PR. So the next
step is to pull main.
When you're done with that we'll continue with the next question: does a
branch depend on the new changes?
Merge conflicts in a PR are always a good indicator that this question should be
answered with yes. The Top Section PR touched the same files and lines as the
Bottom Section PR so it makes sense that there is some kind of dependency.
That means the next steps are
check out the bottom-section branch
push it
rebase on main.
Go ahead and take the first two steps.
But before you rebase try to answer the following question and continue to the
next page.
Do you need to run a normal or interactive rebase?
Final Rebase
The question was: Do you need to run a normal or interactive rebase?
When you're in doubt you can always use the interactive option. But it's
only required when you want to manually edit the commit history in some way.
So let's have a look at our commit history.
Quick look at the commit history
To get a clear picture of what we want to achieve let's have another look at a
visualization of the current commit history. You can confirm this on your local
machine using the git log command.
We would like to rearrange the commits slightly to get this image.
Do you think we need the interactive rebase or not?
Rebase
As you can see above we don't need to remove any commits. We just want to
rearrange them so that the commits from main appear before the commit from
the bottom-section branch.
That's what rebase does by default. Thus we can use a simple rebase without
the interactive option.
Go ahead and rebase the bottom-section branch on top of the main
branch.
If everything went as planned... you see an error!
A merge conflict
This looks scary! At least that's what I thought the first times I encountered
merge conflicts.
But it doesn't have to be. Let's take a deep breath and read the output line by
line.
The first line seems fine. But then it says
CONFLICT (content): Merge conflict in src/styles.css.
And there's a second line which is similar:
CONFLICT (content): Merge conflict in src/index.html.
Another important piece of information is this line:
error: could not apply 625e99d... Add bottom section.
What does this all mean?
Being able to read and understand error messages is one of the most important
skills of a software developer. So let's try to understand what this means.
The output says that there was a problem when applying the commit Add
bottom section . Remember that Git first takes all the commits from the main
branch and adds each commit of the bottom-section branch one after
another. Basically, Git didn't know how to do that.
The reasons are the files src/styles.css and src/index.html as
mentioned in the first two lines. But we don't know yet what exactly the
problem is.
We'll find out soon.
Resolving the Conflicts
Resolving merge conflicts can be hard. Especially when there are multiple or
large conflicts that involve changes from different developers. Sometimes you
might even need to resolve them as a team.
Luckily, in our case, it won't get so complicated. We'll start simple.
Resolving the conflict in index.html
Open the file src/index.html . This is what I see.
Note: I'm using VS Code and the GitLens extension. I guess that's
where some of the fancy stuff comes from.
Again looks a bit scary or confusing at least. So let me quickly explain.
The code between <<<<<<< HEAD and ======= belongs to the last successful
commit. Which is the Top Section (#6) commit from the main branch. You
can confirm this by running git log in the terminal.
The code between ======= and >>>>>>> belongs to the failed commit
(meaning the Add bottom section commit from the bottom-section
branch).
Maybe you remember: In both commits, there's one <section> element as a
child of the <main> HTML element. This is from the top section.
<main class="content">
<section class="section">
Top section
</section>
</main>
And this from the bottom section.
<main class="content">
<section class="section">
Bottom section
</section>
</main>
The code is almost the same. But the content of the <section> element is
different.
So Git doesn't know which one it should take. Should it take the text Top
Section or rather Bottom Section . And Git is right to complain.
What we actually need is to have two section elements. One for the top and
one for the bottom section. So, replace the current content of src/index.html
with this
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GitHub Pull Request Flow Course</title>
<meta name="description" content="GitHub Pull Request Flow
Course">
<meta name="author" content="Johannes Kettmann">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/norm
alize.min.css">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="header">
Header
</header>
<main class="content">
+ <section class="section">
+ Top section
+ </section>
+ <section class="section">
+ Bottom section
+ </section>
</main>
<footer class="footer">
Footer
</footer>
</body>
</html>
Resolving the conflict in styles.css
When you open the file src/styles.css you should see something like this.
There are two conflicts. One in the .content class and one in the .section
class.
In the top-section branch we saw that ooloo-bot added the padding:
20px to the .content class. The padding ensures that we have some empty
space around the content on mobile devices. So this has to stay.
In the bottom-section branch we added the margin-top: 20px to the
.section class. We used the margin to have vertical space between two
sections. Otherwise, the sections would stick together. This is not covered by
the padding so the margin has to stay as well.
This is the new content of the file src/style.css .
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
.header {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
}
.footer {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid black;
}
.content {
min-height: calc(100vh - 140px);
width: 760px;
max-width: 100%;
margin: auto;
+ padding: 20px;
}
.section {
height: 450px;
width: 100%;
+ margin-top: 20px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid black;
}
Continuing the rebase
To mark the conflicts as resolved we have to stage them. Run the following
command
git add .
To continue the rebase use the --continue option.
git rebase --continue
An editor should open and ask for a commit message.
You can simply save and exit. This way we use the original commit message
Add bottom section .
The rebase should now continue without problems.
Perfect. Seems like we're done.
But before we pop the champagne and call it a day let's do a last check.
Uncovering a Problem
We're almost done. But there are a few steps left. Here is our path on the
roadmap one last time.
We successfully rebased the bottom-section branch on main . So the next
step is double-check that everything is working.
Double-check
First, let's have a look at the commit history. This is what mine looks like.
That looks as expected. The Top Section (#6) commit is the last on the
main branch and there's only one commit on the bottom-section branch.
Let's also make sure that the website looks fine. Run the following command if
you have npm installed on your machine. Otherwise, trust me with the
screenshot below.
npm start
Now visit localhost:5000 and you should see this.
This looks almost right. But there's a small problem:
The empty space below the header is too large. It should be the same as
above the footer.
The explanation is that ooloo-bot added a padding: 20px to the .content
class in the Top Section PR. We added a margin-top: 20px to the .section
class in the Bottom Section PR.
Either one of them was working fine. But the combination of both
introduces a bug and leads to twice the space above the first section.
That's why we should always double-check the functionality.
Final fix
Open the file src/styles.css and add the highlighted lines.
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
}
.header {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid black;
}
.footer {
height: 49px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid black;
}
.content {
min-height: calc(100vh - 140px);
width: 760px;
max-width: 100%;
margin: auto;
padding: 20px;
}
.section {
height: 450px;
width: 100%;
margin-top: 20px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid black;
}
+
+.section:first-child {
+ margin-top: 0;
+}
Now everything looks great
You only need to commit the changes.
Update the PR
We're on the homestretch. Your boss is happy and your teammate ooloo-bot
is cheering you
Go ahead and force push the branch to the remote repository on GitHub.
Finally, open the Bottom Section PR and request a new review.
Note: you first have to unselect ooloo-bot as a reviewer and then
request a review again. It's important to close the dropdown after
unselecting the reviewer as shown in the video below.
ooloo-bot should approve the PR in a matter of seconds.
The last step is to click the merge button (and update your local main
branch if you like).
Final Words
Congrats! You succesfully finished this course about using Git in a professional
team. I hope you learned a thing or two.
If you found this course valuable please don't forget to share it with your
friends on Twitter or elsewhere. It would mean a lot to me.
Finally, let's quickly recap what we covered:
a Git workflow using Pull Requests and code reviews
merging and squash merging
using rebase to incorporate changes from other branches
using interactive rebase to edit the commit history
resolving merge conflicts
force pushing (with the force-with-lease option)
This is a great foundation to start using Git in a professional team.
Last but not least, don't forget to get your guide.