topics #fedora #git #linux #ruby

Learn Ruby: 7. Git and GitHub Basics

GitHub

GitHub is a source-control hosting service where code is stored. Register and create a new public repository named my_project. Leave the Initialize this repository with section empty.

Git

Git is a version control system that records changes to a file or set of files over time so you can recall specific versions later. Git was created by Linus Torvalds, who also created Linux.

Almost every operation is performed locally — internet access is only needed when downloading a new version or pushing local changes.

Git has three states:

  • Modified files that are not yet staged
  • Staged files
  • Committed changes

git config

First, run a few commands in the terminal:

git config --global user.name "FirstName LastName"
git config --global user.email your_email@example.com
git config --global core.editor vim

These commands create a new file ~/.gitconfig:

[user]
	name = FirstName LastName
	email = your_email@example.com
[core]
  editor = vim

git init

To initialize a repository, navigate to your project folder and run:

cd my_project
git init

This creates a hidden .git directory:

Initialized empty Git repository in ~/my_project/.git/

git status

Shows the current state of your files. Create two new files a.rb and b.rb:

# a.rb
class A
  def call
    puts "This is A class"
  end
end

# b.rb
class B
  def call
    puts "This is B class"
  end
end

Running git status shows that Git is not yet tracking these files:

On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        a.rb
        b.rb

nothing added to commit but untracked files present (use "git add" to track)

git add

Tells Git which files to track. Run git add . — the . means "add all changes and new files to the index".

Running git status again shows different output:

On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   a.rb
        new file:   b.rb

If you modify a staged file:

# a.rb
class A
  def call
    puts "This is #{self.class} class"
  end
end

git status will show a.rb both in the staged list and as modified. Staging a file captures its state at that moment — you can keep editing it, but only the staged snapshot will be committed until you stage it again.

git diff and git diff --staged

Show unstaged changes:

git diff
diff --git a/a.rb b/a.rb
index df2ba36..b2605f3 100644
--- a/a.rb
+++ b/a.rb
@@ -1,5 +1,5 @@
 class A
   def call
-    puts "This is A class"
+    puts "This is #{self.class} class"
   end
 end

Show staged changes:

git diff --staged
diff --git a/a.rb b/a.rb
new file mode 100644
index 0000000..df2ba36
--- /dev/null
+++ b/a.rb
@@ -0,0 +1,5 @@
+class A
+  def call
+    puts "This is A class"
+  end
+end

After updating the index with git add ., the staged diff will reflect the latest version of the file.

git commit

To save your changes permanently in Git, create a commit with a description:

git commit -m "Add new a.rb and b.rb files"
[master (root-commit) d7dfd69] Add new a.rb and b.rb files
 2 files changed, 10 insertions(+)
 create mode 100644 a.rb
 create mode 100644 b.rb

git log

Shows the list of commits with author, date, and hash:

git log
commit d7dfd69042385678bc0687766bc6651eccde4d2c (HEAD -> master)
Author: FirstName LastName <user@example.com>
Date:   Wed Sep 22 23:25:31 2021 +0400

    Add new a.rb and b.rb files

git stash

Suppose you staged a new file c.rb but suddenly need to work on something else. Use git stash to temporarily hide your changes:

git stash
Saved working directory and index state WIP on master: d7dfd69 Add new a.rb and b.rb files

Your working tree is now clean. You can view the stash list:

git stash list
# stash@{0}: WIP on master: d7dfd69 Add new a.rb and b.rb files

git stash show stash@{0}    # summary
git stash show stash@{0} -a # full diff

To restore the stash:

git stash apply  # restore but keep in stash list
git stash pop    # restore and remove from stash list

git checkout

Lets you switch to or create a new branch.

git checkout <branch>    # switch to a branch
git checkout -b <branch> # create a new branch and switch to it

A branch is a separate workspace within the project. The default branch name is master. After creating a branch with git checkout -b my_feature, it is an exact copy of master. Changes you commit there won't appear in master:

git checkout master
git log
# d7dfd69 Add new a.rb and b.rb files  (d.rb is absent here)

git merge

Once you finish work on my_feature and want to bring those changes into master:

git checkout master
git merge my_feature
Updating d7dfd69..0350f78
Fast-forward
 d.rb | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 d.rb

The commit log now shows the merged history. You can then reorganize files and commit again:

mkdir git_basics
mv *.rb git_basics
git add .
git commit -m "Move .rb files to git_basics folder"

git push / git pull

Link your local repository to the remote one you created on GitHub:

git remote add origin git@github.com:<YOUR_USERNAME>/my_project.git
git branch -M main
git push -u origin main

If you get a Permission denied (publickey) error, you need to add an SSH key.

ssh-keygen

Generate a key pair and enter a passphrase when prompted:

ssh-keygen

Print the public key and copy it:

cat .ssh/id_rsa.pub

Go to GitHub Profile → SSH and GPG keys → New SSH key and paste the key. Then push again:

git push -u origin main
Enumerating objects: 7, done.
...
To github.com:username/my_project.git
 * [new branch]      main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

git alias

You can shorten frequently used commands by adding an [alias] block to ~/.gitconfig:

[alias]
        ci      = commit
        br      = branch
        co      = checkout
        df      = diff
        dfs     = diff --staged
        st      = status

That said, avoid aliases in the early stages — typing the full commands helps you learn them properly.