Git Basic - WheatonCS/Lexos GitHub Wiki
This tutorial will teach you about the basic concepts of Git
.
- Tutorial
When you have a code base, you are constantly making changes to it such as:
- adding new functions
- adding documentation to functions
- fixing a bug
- removing deprecated functions
When you make such changes you must also save them and make note of what you changed.
Commit is like a saving point in video games, you can save your changes with a description:
- File Changed: the file that you changed that you want to track in this commit
- Commit Message: a message to describe your changes
Let's think of our code as a simple time line consisting of three commits: A, B and C.
A ---> B ---> C
In this example A is your branch with B being the updated version of A with changes having been made to the branch and C being the current version of B with even more changes having been made to the branch. Each of them will have their own corresponding File Changed and Commit Messages.
For technical details about how to commit see Commit.
A good rule of thumb is to commit as often as possible; whenever you can describe your changes clearly, you need to make a commit.
A good commit will serve the following purposes:
- It works like a saving point; if the current version is not working correctly, we can always go back.
- We will know who to blame when something is not working correctly.
- We can easily visualize what we are doing with our code because each commit has a message associated with it.
The cloud, or the remote, allows us to share code with others, to edit code with others, and to save our code in a secure place.
Git
provides us a sync (or push in PyCharm) feature to backup our commits into the remote (in our case, the remote server is provided by GitHub).
- Remote: The server that stores your code (commits). In our case, GitHub.
- Sync (or Push in PyCharm): The operation to sync up your local commits with the remote commits.
Let's add a remote line to our previous example:
remote: A ---> B
local: A ---> B ---> C ---> D
This time we can see that our local is 2 commits ahead of (has 2 more commits than) the remote. When we do a sync, our local change got pushed onto the remote:
remote: A ---> B ---> C ---> D
local: A ---> B ---> C ---> D
Notice that commit C
and commit D
got pushed onto the remote.
Now let's make our model a little more realistic.
remote: A ---> B ---> E
local: A ---> B ---> C ---> D
This time there is one commit E
on the remote, but not on the local. This picture is a much more realistic view of what happens when your are working with others.
Because you are not the only one that pushes to the remote, it is very likely that there is new code on the remote written by your co-worker.
What should I do now?!
DON'T PANIC, our good friend Git
will take care of it for you!
When you execute sync, Git
will put your commit and your co-workers commit in place on the remote:
remote: A ---> B ---> C ---> D ---> E
local: A ---> B ---> C ---> D ---> E
For technical details about how to sync, see Push.
It is recommended to push when possible, which means you should push when you meet all of the following criteria:
- You have access to the internet. (Obviously you cannot push to the remote server if you do not have internet access.)
- You made a commit. (Because sync only syncs new commits; therefore your local needs to be at least 1 commit ahead of the remote.)
We have actually already encountered the idea of a branch. In the last section, we saw remote and local which are in fact both branches because they belong to the same code base and can be synced together.
Branch: refers to a pathway of the code base; different branches can be synced together.
Let's start with Example 2
from the previous section.
remote: A ---> B ---> E
local: A ---> B ---> C ---> D
Below this is drawn to look more like branches:
remote: A ---> B ---> E
\
local: ---> C ---> D
Because they both share commit A
and commit B
, there is no point in drawing them twice. Now we can see that the remote and local are actually branches of the same code base tree.
When we sync the local branch with the remote branch, it should look something like this:
remote (local): A ---> B ---> C ---> D ---> E
We see that remote and local are actually two branches, but can we create more branches? Of course, we can always create new local branches, and sync them to the remote.
Once we create our new branch, we probably want to work on this new branch (make commits on it). Git
provides us with a function called Checkout
, to change from working on a file on the disk to working on a file on the branch.
Create a branch: creates a new branch to keep track of our source code on.
Checkout branch b: changes the local code base to branch b
Let's continue with the example from the previous section. I will reduce some commits for simplicity's sake:
remote: A ---> B
local: A ---> B
Below I have created a new branch on the local, called new
. Notice that we are still on the local branch:
remote: A ---> B
local: A ---> B <- We Are Here
new: A ---> B
In order to get to our new branch we need to checkout to the new
branch on local:
remote: A ---> B
local: A ---> B
local/new: A ---> B <- We Are Here
Now, let's just create a commit like we did before (Notice the notation has been switched to branch notation):
remote: A ---> B
local: A ---> B
\
local/new: ---> C <- We are Here
But now we want to checkout back to local:
remote: A ---> B
local: A ---> B <- We are here
\
local/new: ---> C
Now if you look at your code base, you will see all the changes you made in commit C
magically disappeared because you are on the local branch. This behavior is what we mean by "changing the code base to branch local".
For technical details about how to create a branch, see Create a branch.
For technical details about how to checkout a branch, see Checkout a branch
Typically a branch is created when you want to do a bug fix or add a new feature (you can think of this as a larger commit). We will talk about how to use branches to manage code even more in the next section.
First, we need to introduce the term master
branch: the master
branch is the common name for the default branch in the repository. So realistically our local
should really be called local/master
and our remote
should really be called remote/master
.
Every different project uses the master
branch differently, but they all have some things in common:
- Code in the
master
needs to be good enough to be trusted. - Commits in the
master
branch need to be good enough to be included in the next release.
(Lexos will require everyone to review the code before the code reaches the remote master
; see the Pull Request section for more information.)
Second, we need to know another concept called merge
which is a functionality that brings the commits from other branches to the current branch.
Typically we will merge
the master
branch onto our current working branch to make sure we are up-to-date on our current development.
Master branch: Typically means the default branch. This branch only should contain code that has been reviewed and is stable. (Good criteria would be that all the commits in master should be able to go to the next release.)
Merge: Gets all the commits from the selected branch onto the branch that is currently being worked on.
Let's start small by first substituting our branches with their correct names:
remote/master: A ---> B
local/master: A ---> B
\
local/new: ---> C <- We are Here
Now, let's suppose another worker has pushed to the remote/master
.
remote/master: A ---> B ---> D ---> E
local/master: A ---> B
\
local/new: ---> C <- We are Here
There are now two new commits on remote/master
: D
and E
. So, when we merge our branch with the remote/master
, Git
will get the commit from remote/master
to our current branch (local/new
).
remote/master: A ---> B ---> D ---> E
local/master: A ---> B
\
local/new: ---> C ---> D ---> E <- We are Here
For technical details about how to merge, see Merge
Here are two things you should watch out for when you merge:
- You will probably always want to merge with the
remote/master
, not thelocal/master
. - It is always nice to merge as often as possible, but you cannot merge when you have any changes that haven't been committed (haven't been saved). So commit your changes before doing a merge.