Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the updraftplus domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/frankliuao/frankliuao.com/wp-includes/functions.php on line 6114

Warning: Cannot modify header information - headers already sent by (output started at /home/frankliuao/frankliuao.com/wp-includes/functions.php:6114) in /home/frankliuao/frankliuao.com/wp-includes/rest-api/class-wp-rest-server.php on line 1893

Warning: Cannot modify header information - headers already sent by (output started at /home/frankliuao/frankliuao.com/wp-includes/functions.php:6114) in /home/frankliuao/frankliuao.com/wp-includes/rest-api/class-wp-rest-server.php on line 1893

Warning: Cannot modify header information - headers already sent by (output started at /home/frankliuao/frankliuao.com/wp-includes/functions.php:6114) in /home/frankliuao/frankliuao.com/wp-includes/rest-api/class-wp-rest-server.php on line 1893

Warning: Cannot modify header information - headers already sent by (output started at /home/frankliuao/frankliuao.com/wp-includes/functions.php:6114) in /home/frankliuao/frankliuao.com/wp-includes/rest-api/class-wp-rest-server.php on line 1893

Warning: Cannot modify header information - headers already sent by (output started at /home/frankliuao/frankliuao.com/wp-includes/functions.php:6114) in /home/frankliuao/frankliuao.com/wp-includes/rest-api/class-wp-rest-server.php on line 1893

Warning: Cannot modify header information - headers already sent by (output started at /home/frankliuao/frankliuao.com/wp-includes/functions.php:6114) in /home/frankliuao/frankliuao.com/wp-includes/rest-api/class-wp-rest-server.php on line 1893

Warning: Cannot modify header information - headers already sent by (output started at /home/frankliuao/frankliuao.com/wp-includes/functions.php:6114) in /home/frankliuao/frankliuao.com/wp-includes/rest-api/class-wp-rest-server.php on line 1893

Warning: Cannot modify header information - headers already sent by (output started at /home/frankliuao/frankliuao.com/wp-includes/functions.php:6114) in /home/frankliuao/frankliuao.com/wp-includes/rest-api/class-wp-rest-server.php on line 1893
{"id":72,"date":"2017-08-13T16:04:40","date_gmt":"2017-08-13T16:04:40","guid":{"rendered":"http:\/\/www.frankliuao.com\/blogs\/?p=72"},"modified":"2018-05-03T01:37:41","modified_gmt":"2018-05-03T01:37:41","slug":"using-github-and-gitlab-1","status":"publish","type":"post","link":"https:\/\/www.frankliuao.com\/using-github-and-gitlab-1\/","title":{"rendered":"Using Github and Gitlab (1) – About Git"},"content":{"rendered":"

Recently at work we encountered the choice between Github and Gitlab. I did some research and summarized their similarities and differences below.<\/p>\n

First of all, both of them are based on Git<\/strong>. Let’s first talk about Git itself. Git is standalone from any of the Git online servers: in principle you don’t need Internet to use Git. But, nobody else can see your project then. What’s the point?<\/p>\n

Check whether you have git first. If not, install it.<\/p>\n

git --version<\/pre>\n

How git works<\/h4>\n

Basically, Git is used to record the changes of a project, which contains folders and files. It stores all these information in a repository <\/strong>in each project folder. Each time some changes are done, and you want to record the status of the project (like you wanna take a selfie for your workout progress), it’s called a commit. <\/strong>Each\u00a0commit has a reference to it, called a head<\/strong>. The current head is capitalized as HEAD<\/strong>, and each repository can have multiple heads.<\/p>\n

Each commit includes 1. The project files; 2. parent commit; 3. a name for this commit (a head).<\/p>\n

initializing git and the first commit<\/h3>\n

Let’s start the demo now. I created a file “History.txt” and wrote “08\/09\/17 15:09: Ao Created History.txt”. I am ready for my very first commit. So, I initialize the repository by:<\/span><\/p>\n

git init<\/pre>\n

It will say Initialized empty Git repository in \/path\/to\/project\/directory\/.git\/<\/span>“<\/em>. Next you need to tell Git what files are relevant, i.e. which files you want to commit, i.e. you need to add the files to the commit list.<\/p>\n

git add file1 file2 file3<\/pre>\n

Or if you want to commit the whole directory, do<\/p>\n

git add .<\/pre>\n

Now you may do your first commit by:<\/p>\n

git commit -m \"Initial commit\"<\/pre>\n

You will see a bunch of notifications saying your first commit was successful. Alternatively<\/span>, you can also use<\/p>\n

git commit -a -m \"Initial commit\"<\/pre>\n

to automatically add all the files and commit (equivalent to git add . ; git commit -m “…”<\/em>)Now, let’s add another line to the file: “08\/09\/17 15:30: Ao Modified History.txt”. Before you do the next commit, you probably want to check which files were modified, and what are different. Use the following commands:<\/span><\/p>\n

git status<\/pre>\n

You will see “Modified: History.txt”, indicating the file was modified since last commit. Use<\/p>\n

git diff<\/pre>\n

to get the detailed changes between the current files and the last commit:<\/p>\n

\"\"<\/p>\n

Go ahead and do the next commit with git commit -m “Second commit”.<\/em> Now you have two commits.<\/p>\n

Reversing commits<\/h3>\n

Now say you realized that the changes in your last commit were really stupid\/unnecessary. You want to reverse it. There are basically two options: hard and soft. Before demonstrating this technique, let’s add another line in the file, and do another commit. Now you have three commits.<\/p>\n

\"\"<\/p>\n

Let’s say you want to go back to the 1st commit and do some changes. First we try the soft way. Each commit head, as you could see, has a unique name, called SHA1 name<\/strong>. You need the first 7 characters to describe a head, e.g. our first commit is 5d28811, but I found you can use more than that, up to the whole SHA1 name. We want to basically “reset” <\/em>to that commit. So the command is<\/p>\n

git reset --soft 5d28811<\/pre>\n

Also, you can use the name of the head, such as master<\/strong>, to refer to the commit.<\/p>\n

You will see the following Git status change:<\/p>\n

\"\"<\/p>\n

Oh BOY! There is only one commit left. But your file stays as it was at the 3rd commit. But Wait, you then again realized all you did for the 2nd and 3rd commits make sense! You want to go back to the 3rd commit (cancelling the “reset”). What should you do?<\/p>\n

Luckily, all these heads <\/strong>(references) are properly stored in Git. You just need to call another log file, reflog<\/strong>:<\/p>\n

\"\"<\/p>\n

For now we ignore the meaning of HEAD@{*}. You see your third commit is still there. Now you can go back by <\/span><\/span><\/p>\n

git reset --soft 3224034<\/span><\/span><\/pre>\n

\"\"<\/p>\n

Next, we will try the HARD way. Be very careful when using this option, as this will cause changes to both your commits and files<\/strong>. All right, now we are at the 3rd commit. We are sure we want to discard the 2nd and 3rd commits. Do:<\/p>\n

git reset --hard\u00a05d28811<\/pre>\n

\"\"<\/p>\n

As shown, each hard reset<\/em> can change both your commits and files. Although you may use hard reset to recover the files, as they are still recorded in reflog, I still recommend you be cautious when using it.<\/span><\/span><\/p>\n

Alternatively, we can use another method:\u00a0git revert<\/strong>. Revert also changes your file, but it’s different than reset. To demonstrate it let’s again start from the 3rd commit.<\/p>\n

git revert 3224034bf <\/span>7d9fd5cf80a7a<\/span><\/pre>\n

Each time a revert happens, there will be a notification file opened, looking like this<\/p>\n

\"\"<\/p>\n

It is basically a commit message on the first line. The document is opened with vim<\/a><\/strong>, so all you have to do is keep\/change the commit message (in this case default is: Revert “Second commit”), and press :wq<\/strong>\u00a0<\/span>and Enter to save and exit vim. After two reverts, the project looks like this:<\/p>\n

\"\"<\/p>\n

As shown, the reverts <\/strong>have been recorded in the log. The status is “up to date” (no unstaged changes), and the file has been reverted to the 1st commit. Now you probably understand: each revert<\/strong> is treated as a new commit, while reset<\/strong> just abandons changes made since then:<\/p>\n

\"\"\u00a04(2) means the 4th commit = 2nd, same for 5(1)<\/p>\n

Therefore, you may use reset when you are working on your own branch<\/strong>, but use revert when you are working on a shared branch<\/strong>.<\/p>\n

Now, since we have introduced this term, let’s talk about branch<\/strong>.<\/p>\n

Use branches to collaborate on a project<\/h3>\n

An example of why you should use branches: You have released a game to players for testing, and you are working on adding another character. You received a bug report from a player and it needs to be fixed immediately. Option 1, without branches, you commit the current version with the unfinished character (such as a hero with infinite HP or 1 HP), then you fix the problem and commit again. Now all the players will start reporting this unfinished character.<\/p>\n

The story of Nintendo’s Pokemon Go tells us a crashing game should not be seen by the players. BTW, I still couldn’t believe they made a fortune with that app.<\/p>\n

The solution is to have two branches, say, one named “new_character” and one named “release”. Players only see the “release” branch, and you commit to “new_character”, go back to “release”, debug, commit, go back again to “new_character”, and work on the HP issue.<\/p>\n

To start a new branch from a certain commit head, do<\/p>\n

git branch new-branch-name starting-head-reference<\/pre>\n

Branch is almost just another name for head. To show all branches, do either one of the following two:<\/p>\n

git branch -a\r\n\r\ngit show-branch -a<\/pre>\n

An example is given below. I have redone the whole repository to be clear<\/em> – the previous example generated too much trash information.<\/p>\n

\"\"<\/p>\n

As shown, there are two branches, master<\/strong>\u00a0and work_progress<\/strong>. Now you should be able to understand what “On branch master<\/span>” means. master<\/strong>\u00a0is the default HEAD<\/strong> name, also the default branch name if you create a new one. To switch to another branch, do<\/span><\/p>\n

git checkout head-name<\/pre>\n

(remember a branch is just a head?)<\/span> NOTICE: all files in your directory will be changed to that commit.\u00a0<\/span><\/span><\/p>\n

\"\"<\/p>\n

What we just did can be visualized as follows (remember HEAD<\/strong> is the current head):<\/p>\n

\"\"<\/p>\n

You can now work on the file and do another commit. Since this commit won’t be seen on the master<\/strong>\u00a0branch, let’s call it commit 3′. The change can be shown by the following:<\/p>\n

\"\"<\/p>\n

\"\"<\/p>\n

As shown, on master<\/span> branch the entry at 08\/13\/17 23:00 isn’t recorded. Vice versa, on the work_progress<\/span>\u00a0branch the entry at 08\/13\/17 15:13 isn’t recorded.<\/p>\n

Now you might wonder, Hey, the bug fix is useful for my ongoing work too, how may I add that in the master branch? That’s the idea of (very important!!)\u00a0merge<\/strong><\/span><\/p>\n

Merge files from other branches<\/h3>\n

Now imagine you added a file called addon.txt to fix the bug in the work_progress<\/span> branch, now you want that to appear in your master<\/span> branch. First, in work_progress<\/span>, you need to add the new file by git add<\/strong>, then you need to commit it, and switch to master<\/span>.\u00a0<\/span><\/span><\/p>\n

\"\"<\/p>\n

In branch master<\/span>, you do not see addon.txt<\/span>. Now do<\/p>\n

git merge work_progress<\/pre>\n

Now you see addon.txt<\/span>, but you also see a conflict:<\/p>\n

\"\"<\/p>\n

The addon.txt<\/span> showed up, however the History.txt<\/span> became like this, since work_progress<\/span> also changed it:<\/p>\n

\"\"<\/p>\n

This is a conflict<\/strong>. You need to resolve it. You may keep the current content (below <<<<<< HEAD) and also contents from work_progress<\/span> (below ====== and above >>>>>>). Then add it and commit. Now, from git log<\/strong>, you’ll realize that we have effectively combined the commits from work_progress<\/span> and master<\/span>.<\/p>\n

\"\"<\/p>\n

To visualize, what was done is basically:<\/p>\n

\"\"<\/p>\n

To delete a branch<\/strong>, just do<\/p>\n

git branch -d branch_name<\/pre>\n

Be sure not to leave a dangling commit<\/strong> when you delete a branch. For example, if you haven’t <\/em>merged the commit 3′<\/em>\u00a0from work_progress<\/span> to 4, then you can’t delete it, since 3′<\/em> will become a dangling commit<\/strong>.<\/p>\n

Now you know most things about the local usage of Git. It’ time to check Github and Gitlab<\/strong>: how to use Git online.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"

Recently at work we encountered the choice between Github and Gitlab. I did some research and summarized their similarities and differences below. First of all, both of them are based on Git. Let’s first talk about Git itself. Git is standalone from any of the Git online servers: in principle you don’t need Internet to …<\/p>\n

Using Github and Gitlab (1) – About Git<\/span> Read More »<\/a><\/p>\n","protected":false},"author":1,"featured_media":114,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-72","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"jetpack_featured_media_url":"https:\/\/www.frankliuao.com\/wp-content\/uploads\/2017\/08\/gitlab-github-comparison.png","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9S28u-1a","jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/posts\/72","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/comments?post=72"}],"version-history":[{"count":14,"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/posts\/72\/revisions"}],"predecessor-version":[{"id":223,"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/posts\/72\/revisions\/223"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/media\/114"}],"wp:attachment":[{"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/media?parent=72"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/categories?post=72"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.frankliuao.com\/wp-json\/wp\/v2\/tags?post=72"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}