In part 1 and part 2 we've learned about how work locally with git, in part 3 we'll learn about the final piece: how to work with remote repository (aka Google Drive for developer).
Just like Google Drive and Dropbox probably are two of the most popular file storing services, in the developer world Github and Gitlab are two of the most popular services to upload your project to.
In this article I'll use Github. But since all of the "remote repository" services are very similar, you can apply what you learned in this article to any specific services you encounter.
Create a new repository on Github
First, if you don't have a Github account, create one. It's free! You only need an email and / or a phone number for it.
If you not yet in the right mood to signup for a new service, you can continue to read on, I'll draw a bunch of diagrams for you to understand what I'm doing!
After having a Github account, let's create a new repository.
You can click the green "New" button on the left or click on the + in the menu and then click on the "New repository" button like this:
After doing that, you'll enter the Create a new repository screen like this:
I'll name my repository simple-git-tutorial
, just use the default settings and click the green "Create repository" button at the bottom.
After that, you'll be greeting with this screen:
This means that your repository has been created successfully and Github now asks you to push your project into it. It's like you create a new folder in Google Drive and then Google Drive asks you to upload your files into that folder.
The first instruction part you see on the screen "...or create a new repository on the command line" is for when you create a new remote repository on Github before you create a new project on your computer.
The second instruction part you see on the screen "...or push an existing repository from the command line" is for when you already have a project on your computer and you want to upload this to this remote repository. It's like you already have a folder in your computer and you want to upload all of its content to a folder in Google Drive.
Since we already have a project in our computer, let's go with second part. But what are those strange commands:
git remote add origin https://github.com/**************
git branch -M main
git push -u origin main
...mean?
Let's explain the first command:
git remote add origin https://github.com/**************
git remote add origin
This command inform git about the remote repository that we want to push / pull (think upload / download) from it. We call it "origin" and provide the url to that remote repository.
Say if you want to name the remote repository "asdf" you'll run a command like this:
git remote add asdf https://github.com/**************
But by convention we'd call the remote repository "origin" so I'll stick to that:
git remote add origin https://github.com/**************
I mean copy and run this command that Github kindly provide us.
Just like you can upload one folder on your computer to multiple file storing service like Google Drive, Dropbox, OneDrive,..., you can also have many remote repositories.
If you run 3 commands like so:
git remote add origin https://github.com/**************
git remote add asdf https://gitlab.com/***************
git remote add qwer https://bitbucket.com/***************
...you'll now have 3 remote repositories: origin
, asdf
and qwer
.
To view all remote repositories in your project, run:
git remote -v
Here's an example of mine:
origin https://github.com/************** (fetch)
origin https://github.com/************** (push)
This means that git knows that I have a remote repository called "origin" at url https://github.com/**************
and I can fetch (imagine download) and push (imagine upload) to it.
git branch -M
This command is for renaming current branch. For example if you accidentally create a branch with a typo like this:
git checkout -b feature/printtt_1
...and now you want to rename it to feature/print_1
, you can use the git branch -M
command like so:
git branch -M feature/print_1
But that leaves us with the question, why do Github want us to rename our branch to main
?
Back to the analogy about group project. Nobody is allowed to change the original file. Instead one must create a copy of that file and then the leader review and merge back to it.
By default, the "original file" is equivalent to the master
branch on Git. But several years ago, Github want us to have the main
branch is the "official branch" instead of master
.
You can rename your master
branch into main
if you like but I'll ignore this command. After all master
and main
only different in name.
git push -u origin
This command is to create a new branch in the remote repository called "origin" with the same content and name as your local branch.
So the command in the instruction on Github:
git push origin main
means that Github want us to push the main
branch on our local computer into remote repository called "origin" on Github.
For example, if you want to push a branch called feature/print_1
into your remote repository on Github (that you named "origin"), you can use this command:
git push -u origin feature/print_1
The command git push -u origin [branch-name]
also equivalent to git push --set-upstream origin [branch-name]
.
But in my case since I want to push all branches into our new remote repository I'll use the following command:
git push origin --all
Now if you refresh your Github repository page, you'll see this:
So that's how you create a remote repository in Github and then push your branch (think upload) to it!
Finally on the topic of setup a repository is git clone
.
git clone
Imagine you're a new member join a team and you have to download the team's project to your computer. You can use git clone
and then provide the url to the remote repository like this:
git clone https://github.com/***********
On Github, you can find the url of a repository by click on the green button "<> Code" and then copy the url below.
The full workflow
Finally let's get to the meat of this series: the full workflow of what you would do if you're receive a new task.
Here are the steps:
- Switch to the main branch (imagine this branch is like the copy of the original file on your computer)
- Get the latest update
- Create a new branch from it
- Do the task
- Add and commit
- Push your newly created branch to the remote repository
- Create a Pull Request (or a Merge Request if you're using Gitlab)
Imagine you have a new task: add console.log(3)
to main.js
.
Here are the steps you'd do:
- Switch to the main branch (
git checkout master
) - Get the latest update
- Create a new branch from it (
git checkout -b feature/print_3
) - Do the task
- Add and commit (
git add main.js
andgit commit -m "add console log 3"
) - Push your newly created branch to remote repository (
git push -u origin feature/print_3
orgit push --set-upstream origin feature/print_3
) - Create a Pull Request
Let's go through this step by step.
First, let switch to the master
branch:
git checkout master
To get the latest update of the master
branch on remote repository, use the command git pull origin [branch-name]
like this:
git pull origin master
Remember to always pull the latest update to avoid conflict!
Next, let's create a new branch called feature/print_3
:
git checkout -b feature/print_3
Now, on main.js
, add the following:
console.log(3);
Let's add and commit this change:
git add main.js
then
git commit -m "[feature] add console log 3"
Next, let's push this branch to our remote repository on Github:
git push --set-upstream origin feature/print_3
If you head back to your repository on Github and refresh, you'll see this:
This means that you've push your branch into your remote repository on Github successfully! The next step is to create a Pull Request.
You can use the short way click on the green button "Compare & pull request" or use the long way I'll show below.
First, click on the Pull Request tab on the topbar. After that you'll see this screen:
Next, click on the green "New pull request" button. After that you'll see this screen:
Make sure to choose the base branch to master
and the compare branch to feature/print_3
as we want to create a pull request to merge branch feature/print_3
into master
.
Now click on the green "Create pull request" button. You'll see this screen:
After adding title and description, click on the green "Create pull request" at the bottom. Now you'll see this screen:
You've created a new Pull Request successfully! Congratulations! This is the final step to complete an assigned task as a member!
Optional: the develop
branch
In the "real world", one project has many "official" branches for many purposes, like master
or main
is for actual production deployment, staging
for deploy to staging server, and develop
as a "main" branch for developers to merge all their works into it. Usually you'll merge into the develop
branch instead of directly to master
.
Review and merge a Pull Request (or Merge Request)
Since we're the leader of ourselves, let's review and merge our own Pull Request.
To review a Pull Request, you can click on the Files changed tab to review what has changed.
You can see in line 3 of main.js
I add a new line console.log(3)
. This is exactly the task I was assigned and I completed it successfully. So I'll merge my own Pull Request!
To merge a Pull Request on Github, click back on the Conservation tab and click on the green "Merge pull request" button below.
After doing that, you'll see this screen:
This means that you've merge the Pull Request into the master
branch successfully! If you go to the "Code" tab, choose the master
branch, then click on the main.js
to view its content, you'll see the console.log(3)
at the line 3:
This means that you merged a Pull Request successfully!
Now you know the workflow of a member and understand what a leader do, here's a diagram explains how all things connected together:
Tasks that depends on each other
Another thing I think it's worth highlighting when you work at a real project is when you have tasks that are depends on each other (i.e you have to complete one before the next).
If all tasks you have are independent with each other, that's simple enough. Just follow the workflow above again and again. Switch to the master
(or develop
) branch, get the latest update, create a new branch from it, do the work, push to Github, create a Pull Request, wait for leader to merge, switch to master
,...
But what about tasks that depends on each other? What if you have to complete task #1 before task #2?
If you complete task #1, but your leader not yet review and merge that pull request, and switch to master
and pull from remote repository, the master
branch will not have the code needed to do task #2.
"Incorrect" ways
At first, you might tempt to do task #2 on the task #1 branch.
But if you do task #1 and task #2 on the same branch and then push, your Pull Request originally for task #1 now contains both code from task #1 and task #2. A Pull Request just care about the base branch and target branch, it does not care about a single task or a commit.
To explain why a Pull Request consists of 2 tasks is not good, let's imagine a situation that a little bit more extreme.
You create a Pull Request for a combination of 5 tasks. Now imagine you're the leader who review the code. Do you want to read one huge Pull Request consists of 1000+ changes across 5 tasks or 5 separate Pull Requests each one 200+ changes for an individual task?
Sometimes your task is so complicated that one Pull Request has thousands upon thousands of changes span across multiple files, but if possible try to make one Pull Request as small and simple (like one for each assigned task or bug at a time).
Back to our problem, you might also temped to wait for your leader to merge your Pull Request before continue to the next one like this:
But of course this is quite... inefficient. A leader might have to review multiple Pull Requests before yours.
Solution
So the "correct" way of solving this problem is quite simple: merge the task #1 branch into task #2 branch.
This way, when you push your task #2 branch to the remote repository and create a Pull Request from it, it'll be 2 Pull Requests, each for one task only.
But wait, you said. If I do so isn't that Pull Request #2 also contains code from both task #1 and task #2?
Correct. But your leader will review and merge your Pull Request #1 before Pull Request #2. After he merge Pull Request #1, when he open the "File changes" on Pull Request #2, he'd only see the difference between the task #2 branch and the master
branch, which is just the necessary code to complete task #2.
Conclusion
Congratulation for reading until the end of the series! I hope you find this series helpful.
Despite everyone using git and git was created for a decade now, I was quite surprise that there were not a lot of tutorials for absolute beginner teaching how everybody use git to work together.
When I was in university, each time we had a group project we'd sent zip file to each other because nobody knows how to use git. More correctly is nobody knows how to use git to work together. Somehow the workflow you see above is a secret that you can only know about if you work at a company. But if I worked at a company I'd not be there study at college. And my college despite loves to assign us group homework never taught about how to do that. They'd rather teach about stuffs like Math, theory of OOP, Linked List, Tree,... instead of teaching about how people do in their everyday life. And while they make a ton of money, a lot of us graduate feel like a burden for a team / company because we don't know the absolute basic of thing (if we lucky enough to have a job at all).
Despite the situation is hard out there (in fact, the US had more developers in 2018 than now, source), I hope this article is helpful for you to become a better at your job or finding a job. I also hope that this article will help good small businesses out there who don't have money or time to train a young, enthusiastic graduate but have no experience, can now find a graduate who'd more quickly get the hang of thing.
Credits
If you like the cute fish that I'm using, check out: https://thenounproject.com/browse/collection-icon/stripe-emotions-106667/.
Top comments (0)