mirror of
https://github.com/foo-dogsquared/website.git
synced 2025-01-31 07:58:02 +00:00
379 lines
20 KiB
Markdown
379 lines
20 KiB
Markdown
---
|
|
layout: post
|
|
title: "Git: Concepts and Mechanics"
|
|
date: 2018-05-28 7:03:34 +0800
|
|
author: foo-dogsquared
|
|
categories: git
|
|
tags: [programming-notes, git]
|
|
---
|
|
|
|
So... after a mishap happened on my site weeks ago (HINT: it is a page build failure from a file that list all of my posts that
|
|
GitHub Pages decided to not accept it for some reason), I decided to write this as a way for level up my version control skills
|
|
(or at least, review them for my sake). *sigh*
|
|
|
|
Well, IDK how to write an introduction for this, so let's get on to the main branch of this post but first, let us be familiar
|
|
what Git really is.
|
|
|
|
<img src="{{ 'assets/pictures/git-logo.png' | relative_url }}" alt="Git Logo" width="250px">
|
|
*Git Logo (as of 2018)*{: .caption}
|
|
|
|
## Primary Primer on Version Control Systems
|
|
Version control, it may sound fancy, but it is a simple thing. You probably have done some form of version control in some
|
|
way or another like the good ol' copying of file in another directory, saving it in a cloud storage, and storing it in a USB.
|
|
Yeah, you get the idea, it is a form of file backup but that is not what version control is all about.
|
|
|
|
As said by the *About Version Control* section on the official Git book, *Pro Git* (in which you can download it from this
|
|
[link](https://git-scm.com/book)), a version control system (VCS) is:
|
|
> a system that records changes to a file or set of files over time so that you can recall specific versions later
|
|
|
|
Well, it usually revolves around the changes happened on the files. That's how version control systems help you manage your
|
|
files. As said by probably a thousand of articles and posts about Git (and other VCS), think of version control system as some
|
|
kind of an EPIC save button that allows you to epically save things in case of an epic fail. Also, keep in mind that VCS are
|
|
not only used for managing code files but also for other files as well whether it's a text file, a document file, or a spreadsheet
|
|
so even a non-programming project (whatever that is) can utilize a VCS.
|
|
|
|
And as such tool with such usability, it is used mostly on big projects especially for those that requires multiple person (which
|
|
composes of probably 95% out of those projects). In programming world, well, it is quite used extensively everywhere unless you
|
|
are in one of those groups that hate using VCS possibly from traumatic events while using it.
|
|
|
|
This is why most of the recommended suggestions when entering the chaotic world of programming includes learning a version control
|
|
system. This is a very helpful tool to be included in your toolkit and in your career since most tech group uses VCS, particularly
|
|
Git.
|
|
|
|
Well, yes, there are [other version control softwares](https://en.wikipedia.org/wiki/List_of_version_control_software) out there,
|
|
but most of them really uses either [Subversion](https://subversion.apache.org/) or [Git](https://git-scm.com/)
|
|
(also keep in mind that they have a difference in terms of how they are being used).
|
|
|
|
If you want to have an overview on different version control systems, you can take a look in the *About Version Control* section
|
|
on *Pro Git* where they will obviously glorify the system Git uses. Also, if you have the time to do so, you can refer to
|
|
[this list of common vocabulary](https://en.wikipedia.org/wiki/Version_control#Common_vocabulary) to have a slight idea in case
|
|
I've mentioned words such as *commit*, *branch*, and other words in advance.
|
|
|
|
And speaking of Git... Yeah, now we are going to talk how to Git... (HA! You thought I am going to include 'good/gud', eh?)
|
|
|
|
## History Lesson on Git
|
|
Well, before we *really* discuss Git. Let's have a little history lesson with Git, shall we? *(Of course, it's already set and
|
|
you can do nothing about it [maybe except skipping this part but whatever])*
|
|
|
|
As you might have read on your own research with our quick reference teacher, Wikipedia-*sama*, Git was designed by Linus Torvalds
|
|
(yes, the guy that developed the Linux kernel) from his need of distributing source code in his own way ever since the
|
|
VCS that the Linux community uses ceases from becoming a free-of-charge tool.
|
|
|
|
After that incident, the Linux community (in particular, Torvalds) decided to write their own VCS that is similar to the ones they
|
|
have used, however with additional criteria that makes Git to be what it is today. Such criteria that they wanted to be for Git
|
|
are:
|
|
- simple
|
|
- easy to use
|
|
- fully distributed
|
|
- highly performant
|
|
- difficult to lose data
|
|
|
|
And within 2005, Git was born. Two months after Torvalds created the thing, he passed the maintenance duty to
|
|
[somebody else](https://en.wikipedia.org/wiki/Junio_Hamano) and became a major contributor to the project, seeing as he is the
|
|
one who managed to get Git to be in its version 1.0, then maintained the project many months after.
|
|
|
|
Then in 2008, GitHub (and the [octocat](https://assets-cdn.github.com/images/modules/logos_page/Octocat.png)) was born to
|
|
be an accomplice to Git until it became the largest web hosting site for source code or something.
|
|
[Then the rest is history, I guess](https://github.com/ten).
|
|
|
|
Now onto the main branch of this post...
|
|
|
|
## What is Git?
|
|
Git is a version control system with a command line interface (mainly) that uses a [distributing version control system (DVCS)](https://en.wikipedia.org/wiki/Distributed_version_control).
|
|
Which means everyone involved will have a clone of the project to revise it in their own way then merge them when necessary into
|
|
the server computer.
|
|
|
|
DVCS also makes use of your local resources instead of relying on a network, meaning you can do some version control-related stuff
|
|
offline. Compared to other CVS, this is a very huge advantage and it is one of the reasons why Git (and other DVCS) are quite fast
|
|
in terms of doing an operation.
|
|
|
|
If you have read *About Version Control* section on *Pro Git* and understood what version control is and what are some ways to
|
|
implement this system, you'll figure out that what makes Git different from other VCS is the way how Git treats its files.
|
|
|
|
## How do I use it?
|
|
If you're on a Windows OS or Mac OS, you would have to download Git [here](https://git-scm.com/downloads) and install it.
|
|
Else if you are on a Linux-based OS, chances are Git is already installed --- makes sense as Git was developed for Linux. But
|
|
in case that you did not have Git for some reason, you can download and install it through the installed package manager of
|
|
the OS.
|
|
|
|
Anyway, the thing we need to know about when using Git is that it is uses CLI, that means we just have to get the command
|
|
line to utilize it and be comfortable with seeing just text (although there are GUI version of it).
|
|
|
|
Git has a plethora of commands so I would recommend to memorize a handful of important and useful commands and do make good use of
|
|
the man page of git and `git --help` a lot. Being a decent programmer does not mean they know all of the commands and syntax of
|
|
the language, they usually refer to documentation since there are other things other than syntax to worry about and there just a
|
|
ton of them --- just a self-reminder.
|
|
|
|
While speaking of Git, we cannot really avoid not talking about GitHub, a web hosting site that implements Git as a source version
|
|
control tool and what makes Git to be a rising star in the version control industry.
|
|
|
|
And while at on the subject of GitHub, I would suggest creating a GitHub account for it, if you do not have one already.
|
|
|
|
### Setting up Git
|
|
Now you have Git, it is time to configure Git which will be explained later. For now just run this command and fill it with
|
|
appropriate values:
|
|
{% highlight bash %}
|
|
git config --global user.name "Your Name"
|
|
git config --global user.email mail@example.com
|
|
{% endhighlight %}
|
|
|
|
This command sets the name and email for all and upcoming repositories to be filled each time you commit.
|
|
|
|
If you want to have a different configuration of name and email in a single repository, you can go to the directory of the project
|
|
of your choice then run the command without the `--global` option.
|
|
|
|
Why do you want to do this? Because each time you would send the updated files on a remote repository, it would ask you to
|
|
fill the commit with the needed information such as your name and email to be associated. Also, it is obviously tiring, so there's
|
|
that.
|
|
|
|
### Obtaining a repository
|
|
OK! Let's get into actually using Git. For starters, you can get a Git repository by either making your current directory to
|
|
be a Git repository or cloning one from some place. For now, let's use with the former which you can do that by:
|
|
{% highlight bash %}
|
|
git init
|
|
{% endhighlight %}
|
|
|
|
And now you have a Git repository that is ready. A more detailed explanation on `git init` is that it creates the necessary files
|
|
that basically serves as a local database to be referenced in case you want to push it to the remote repository (i.e. GitHub,
|
|
BitBucket).
|
|
|
|
Well, now that we have ourselves a Git repo, what now?
|
|
|
|
### Checking files
|
|
We add some files in it, of course! Just add whatever files to your desire (of course, consider what files are you going to
|
|
include). Next, run this command:
|
|
{% highlight bash %}
|
|
git status
|
|
{% endhighlight %}
|
|
|
|
Assuming it is a new Git repository, you will see something like:
|
|
{% highlight git %}
|
|
On branch master
|
|
|
|
No commits yet
|
|
|
|
Untracked files:
|
|
(use "git add <file>..." to include in what will be committed)
|
|
|
|
dog.ods
|
|
folder-1/
|
|
poop.txt.txt
|
|
|
|
nothing added to commit but untracked files present (use "git add" to track)
|
|
{% endhighlight %}
|
|
*`git status` output example*{: .caption}
|
|
|
|
...that as your output.
|
|
|
|
'`On branch master`', '`Untracked files`'... Yeah, you may be wondering, presumably fellow newb developer. What are those?
|
|
What is this whole VCS thing about? What is your purpose? We'll go through them one concept at a time (maybe except the last one).
|
|
|
|
### Adding a file
|
|
For now, let's move on and do what the log says. Do run the said command:
|
|
{% highlight bash %}
|
|
git add .
|
|
{% endhighlight %}
|
|
|
|
Yes, `git add` must have a path as an argument. If you want to include them all, just go to the main location of your project and
|
|
type the above command. You can also add multiple files by just separating their path locations with a space.
|
|
{% highlight bash %}
|
|
git add ./file1.txt ./folder-1/file2.txt
|
|
{% endhighlight %}
|
|
|
|
What this does is that it adds the specified file(s) into the staging area.
|
|
|
|
### Commiting a file
|
|
Anyway, now what does that do? Run `git status` again and you'll the see a log with a list of the now tracked and untracked files.
|
|
{% highlight git %}
|
|
On branch master
|
|
|
|
No commits yet
|
|
|
|
Changes to be committed:
|
|
(use "git rm --cached <file>..." to unstage)
|
|
|
|
new file: folder-1/matter.txt
|
|
new file: poop.txt.txt
|
|
|
|
Untracked files:
|
|
(use "git add <file>..." to include in what will be committed)
|
|
|
|
dog.ods
|
|
|
|
{% endhighlight %}
|
|
|
|
OK! Now we have files that we can commit in which we can now commit those files with:
|
|
{% highlight bash %}
|
|
git commit
|
|
{% endhighlight %}
|
|
|
|
This will run an editor (*emacs* or *vim*) that let's you add a message. Since I find it hard to even *start to write* a
|
|
line (my shell opens *vim* as the editor), I'll just add an `-m` flag with the message instead to skip that part.
|
|
{% highlight bash %}
|
|
git commit -m "Your commit massage"
|
|
{% endhighlight %}
|
|
*Command for reference*{: .caption}
|
|
|
|
Which will be added to the local database and containing the reference to those files that you've added.
|
|
|
|
OK! What if I made a mistake to my commit message? You can just commit another one but that is quite ineffecient at best since
|
|
now you have two commits with identical stuff that appear on your log which renders one of them to be useless. You can do
|
|
a replacing of a commit with this:
|
|
{% highlight bash %}
|
|
git commit --amend -m "Your commit message"
|
|
{% endhighlight %}
|
|
|
|
With this command, you still created two commits but the other one that has been replaced will not appear into your commit
|
|
history. That means, less cluster needed for your work.
|
|
|
|
With each commit, there is also the hashstrings given to every one of them. This will also serve as your reference to those
|
|
commits and it will be more helpful if you added a helpful commit message to not only make those commit a bit more memorable
|
|
and easy to be referenced to but also helping towards other people not wasting their time finding that changes you've logged.
|
|
|
|
I think this [*xkcd* strip](https://xkcd.com/1296/) portrays a situation of writing not-good commit messages.
|
|
|
|
<img src="{{ 'assets/pictures/xkcd-git-commit.png' | relative_url }}" alt="A xkcd comic strip">
|
|
*Me when my site build failed*{: .caption}
|
|
|
|
If you have read a handful of tutorials and articles about the basics of Git, you probably minded about writing a good
|
|
commit message. The following rules are ripped from the book
|
|
*[Git Notes For Professionals](https://goalkicker.com/GitBook)* which was ripped from a
|
|
[post](https://chris.beams.io/posts/git-commit/#seven-rules):
|
|
- Separate the subject line from body with a blank line
|
|
- Limit the subject line to 50 characters
|
|
- Capitalize the subject line
|
|
- Do not end the subject line with a period
|
|
- Use the imperative mood in the subject line
|
|
- Manually wrap each line of the body at 72 characters
|
|
- Use the body to explain *what* and *why* instead of *how*
|
|
|
|
### Comparing commits
|
|
OK! Now what? Try to change the content of a file and run `git status` again and you will see some output that tells you what
|
|
tracked files are changed and what part of it has changed. This is useful but it is limited for that you can only see through it
|
|
if you did not commit yet (I think).
|
|
|
|
BUT! What if I want to compare two commits? That is quite possible thanks to this command:
|
|
{% highlight bash %}
|
|
git diff commit1 commit2 [--] path
|
|
{% endhighlight %}
|
|
|
|
You can omit one commit argument as it will be interpreted as the latest commit by default. You can also leave out the
|
|
path argument if you want to view the changes you've made throughout the working tree.
|
|
If you want to specify a file (or a directory), you must include two en dash (-) then the path of the file after a whitespace.
|
|
|
|
Keep in mind that the commits there are the long hashstrings associated with each commit. If you want a list of your commits
|
|
of your working tree, you can do...
|
|
{% highlight bash %}
|
|
git log
|
|
{% endhighlight %}
|
|
|
|
You can add a `--oneline` flag if it is too much of a pain to scroll through multitudes of lines just for each log. You can also
|
|
add a `-n` with *n* that stands for the number of logs that will appear from the (*n*th - 1) commit before the most recent
|
|
commit.
|
|
|
|
The output log you shall see is having two kinds of the changes you've made to the files specified.
|
|
|
|
### Pushing the project
|
|
If we are sure of the changes that we've made, you can now push that changes you've made to a remote repository with...
|
|
{% highlight bash %}
|
|
git push
|
|
{% endhighlight %}
|
|
|
|
Which will push the repository into the remote repository wherever the repository came from... except in our example, we don't
|
|
have a remote repository, yet.
|
|
|
|
Oh, and have you created a GitHub account? If so, GREAT! If not, CREATE ONE NOW!
|
|
|
|
OK, now that we have a GitHub account (presumably), we now have a reference to a remote server.
|
|
|
|
If you are just starting to use (or be familiar with) GitHub, you can view this video then go through the
|
|
[playlist](https://www.youtube.com/playlist?list=PLg7s6cbtAD15G8lNyoaYDuKZSKyJrgwB-) to be more intimate with GitHub.
|
|
|
|
<iframe width="560" height="315" src="https://www.youtube.com/embed/noZnOSpcjYY" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
|
|
|
|
Now that you are familiar with GitHub (presumably), we shall now push our test to the remote repository which is located
|
|
on the GitHub's server.
|
|
|
|
First, let's just create an empty repository then now we shall configure our local repository to be sent on that remote
|
|
repository by...
|
|
{% highlight bash %}
|
|
git remote add origin <project url>
|
|
{% endhighlight %}
|
|
|
|
...wherein we added a location of the remote repository and named it `origin`. You can replace `origin` with something, just
|
|
make sure you enter the correct value in the below commands.
|
|
|
|
For the project url, you can copy the link of your repository and add a `.git` at the end.
|
|
|
|
Next, run the `git push origin master` command and most likely you will see an error saying the push cannot be forwarded
|
|
because some content are not found on the local repository.
|
|
|
|
To do this, we can *pull* the remote repository by
|
|
{% highlight bash %}
|
|
git pull origin master --allow-unrelated-histories
|
|
{% endhighlight %}
|
|
|
|
After, that you shall see some files have been added (if you added some files over GitHub) and the Git repository has now
|
|
been configured. Then go right ahead and run `git push origin master` if you are pushing the local repository for the first
|
|
time and if you go the url of your repository, you will see the files from your local repository has been added.
|
|
|
|
-----
|
|
|
|
Well, hopefully that's enough for you to be ready for using Git in its basic level. If you still want some practice (or
|
|
if this post done a horrible job of explaining things), you can put some practice time to it in this
|
|
[page](https://try.github.io/levels/1/challenges/1) that is offered by GitHub.
|
|
|
|
Anyway, there are still some things to talk about Git so let's immediately get on to that.
|
|
|
|
## File States
|
|
Like life, files has states. This, of course, open up different functions and different interactions whenever the files is in
|
|
one of the particular states. In this topic, I consider that files in a Git repository have four states:
|
|
|
|
### Untracked Files
|
|
This is not a concise explanation of this thing but let's just say that the local database contains the reference of the files.
|
|
Being a new Git repository (presumably), the local database does not contain any reference to the files and any files that is
|
|
detected by Git in the Git repository will be considered as *untracked*.
|
|
|
|
Any untracked files will not be interrupted by Git. You cannot commit
|
|
those files, you cannot upload them to the central repository; basically, they will remain untouched by Git.
|
|
|
|
If you want to make a file to be not detectable by Git, you can add a <span class="fileName">.gitignore</span> file that contains
|
|
a list of the path of the files that you want to remain undetectable. This reduces the hassle of managing files that is
|
|
most likely be in a more error-prone way. So yeah, pretty useful if you want to stage all files except for those particular files
|
|
in one go.
|
|
|
|
### Unmodified & Modified Files
|
|
After you commit a file, it will be considered now as an unmodified file but this can also be changed into a modified file if
|
|
you... uh, modify the contents of it.
|
|
|
|
Whenever the file is considered modified, it is ready to be staged on the staging area in which you can do that by `git add`.
|
|
|
|
### Staged Files
|
|
Files that are on the staging area. This is where files will end up before a commit.
|
|
|
|
In a general sense, these are the files specified after you run `git add`.
|
|
|
|
This lets you to selectively choose files to be updated before you can be so sure of what you want for your next update of your
|
|
codebase.
|
|
|
|
### Commited Files
|
|
Basically files that have their data saved into the local database. Yeah, that's it.
|
|
|
|
## Git Integrations
|
|
Git has earned some technologies that is being implemented with it. Examples of some of it is [GitHub](https://github.com),
|
|
[BitBucket](https://bitbucket.com), and many others.
|
|
|
|
Usually, Git uses GitHub as its default remote repository. Whenever you finalize the update of your project, it will go to
|
|
GitHub to push that repository online.
|
|
|
|
To have your Git repository configured to be sent on a particular location other than GitHub, enter the `git remote add` command
|
|
with the appropriate values.
|
|
|
|
## (Re)Sources:
|
|
- [Distributed version control on *Wikipedia*](https://en.wikipedia.org/wiki/Distributed_version_control)
|
|
- [Git Basic Challenge on *CodeSchool*](https://try.github.io/levels/1/challenges/1) --- GitHub's offered training on basic Git
|
|
- [Git for Beginners on *SitePoint*](https://www.sitepoint.com/git-for-beginners/)
|
|
- [Git Notes For Professionals](https://goalkicker.com/GitBook) --- another recommended source
|
|
- [GitHub & Git Foundation Playlist --- GitHub Training & Guides *YouTube Channel*](https://www.youtube.com/playlist?list=PLg7s6cbtAD15G8lNyoaYDuKZSKyJrgwB-)
|
|
- [Pro Git](https://git-scm.com/book) --- the official Git book
|
|
- [Push existing project on GitHub on *Stack Overflow*](https://stackoverflow.com/q/17291995) |