Table of Contents

How to learn Git

Version Control System is important part of programming activity. It helps you to maintain all of your and your team code changes, so you can travel through time and see what is being done in specific date and time. It also helps to reflect your codebase in general and find a source of a bug since you know what is exactly being changed in your code.

In this article I want to overview different ways to learn the most popular VCS called Git by sharing links to different resources.

First taste

There are lots of Git introductionary videos. If you don't know what is git itself, it might be a good place to start learning. Other resources might look more hard to handle if you don't know the basics.

Examples of good Git introductionary videos:

Getting glimpse of git

Before touching git itself I would recommend to complete https://learngitbranching.js.org/. This way you will easily learn a set of needed glossary of git terminology to learn in more detail. It abstracts a bit from git console commands letting you to understand concepts itself.

Git CLI

After learning git concepts it is a good idea to install git itself. You can do it using your package manager of choice in GNU+Linux system. For example in Debian it would be:

sudo apt install git

By default you will only have cli interface. You can learn a bit about git looking at its help command:

git --help
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           [--super-prefix=<path>] [--config-env=<name>=<envvar>]
           <command> [<args>]

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone     Clone a repository into a new directory
   init      Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add       Add file contents to the index
   mv        Move or rename a file, a directory, or a symlink
   restore   Restore working tree files
   rm        Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect    Use binary search to find the commit that introduced a bug
   diff      Show changes between commits, commit and working tree, etc
   grep      Print lines matching a pattern
   log       Show commit logs
   show      Show various types of objects
   status    Show the working tree status

grow, mark and tweak your common history
   branch    List, create, or delete branches
   commit    Record changes to the repository
   merge     Join two or more development histories together
   rebase    Reapply commits on top of another base tip
   reset     Reset current HEAD to the specified state
   switch    Switch branches
   tag       Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch     Download objects and refs from another repository
   pull      Fetch from and integrate with another repository or a local branch
   push      Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.

Git has written documentation available in your gnu+linux system. You can read it using man command. I recommend starting reading with gitcore-tutorial.

man gitcore-tutorial

You are not forced to read all of that. Mans are written in encyclopedia way, so it is harder to learn then in other sources, but it is good to know that detailed information about git commands are available offline in your system.

w96k@debian:~$ man git
Display all 174 possibilities? (y or n)
git                           git-fsck-objects              git-remote
git-add                       git-gc                        git-remote-ext
git-am                        git-get-tar-commit-id         git-remote-fd
git-annotate                  gitglossary                   gitremote-helpers
git-apply                     git-grep                      git-repack
git-archive                   git-gui                       git-replace
gitattributes                 git-hash-object               gitrepository-layout
git-bisect                    git-help                      git-request-pull
git-blame                     githooks                      git-rerere
git-branch                    git-http-backend              git-reset
git-bugreport                 git-http-fetch                git-restore
git-bundle                    git-http-push                 git-revert
git-cat-file                  gitignore                     gitrevisions
git-check-attr                git-imap-send                 git-rev-list
git-check-ignore              git-index-pack                git-rev-parse
git-check-mailmap             git-init                      git-rm
git-checkout                  git-init-db                   git-send-pack
git-checkout-index            git-instaweb                  git-shell
git-check-ref-format          git-interpret-trailers        git-sh-i18n
git-cherry                    gitk                          git-sh-i18n--envsubst
git-cherry-pick               git-log                       git-shortlog
git-citool                    git-ls-files                  git-show
git-clean                     git-ls-remote                 git-show-branch
gitcli                        git-ls-tree                   git-show-index
git-clone                     git-mailinfo                  git-show-ref
git-column                    gitmailmap                    git-sh-setup
git-commit                    git-mailsplit                 git-sparse-checkout
git-commit-graph              git-maintenance               git-stage
git-commit-tree               git-merge                     git-stash
git-config                    git-merge-base                git-status
gitcore-tutorial              git-merge-file                git-stripspace
git-count-objects             git-merge-index               git-submodule

Try to init test repository and make new commits, branches and so on to checkout how git commands works in practice without touching your job's projects. Git can rewrite history, so you can mess up whole codebase. Gladly it is hard to do so, just remember not to use git push --force.

Git non-cli interface

Using CLI can be cumbersome, so many people use git-cli wrappers such as GUI or TUI git clients. I use Magit, which is Git interface for text editor GNU Emacs. It provides me nice overview of all available commands and while using them it helps me to choose flags that being displayed in my text editor.

Transient and dwim commands
 A Apply            i Ignore             r Rebase
 b Branch           I Init               t Tag
 B Bisect           j Jump to section    T Note
 c Commit           J Display buffer     V Revert
 C Clone            l Log                w Apply patches
 d Diff             L Log (change)       W Format patches
 D Diff (change)    m Merge              X Reset
 e Ediff (dwim)     M Remote             y Show Refs
 E Ediff            o Submodule          Y Cherries
 f Fetch            O Subtree            z Stash
 F Pull             P Push               Z Worktree
 h Help             Q Command            ! Run
 H Section info

Applying changes
 a Apply      s Stage      S Stage all
 v Reverse    u Unstage    U Unstage all
 k Discard

Essential commands
 g        refresh current buffer     C-x m show all key bindings
 q        bury current buffer        C-x i show Info manual
 <tab>    toggle section at point

This is how commit menu looks like:

Arguments
 -a Stage all modified and deleted files (--all)
 -e Allow empty commit (--allow-empty)
 -v Show diff of changes to be committed (--verbose)
 -n Disable hooks (--no-verify)
 -R Claim authorship and reset author date (--reset-author)
 -A Override the author (--author=)
 -s Add Signed-off-by line (--signoff)
 -C Reuse commit message (--reuse-message=)

Create      Edit HEAD   Edit
 c Commit    e Extend    f Fixup      F Instant fixup
	     w Reword    s Squash     S Instant squash
	     a Amend     A Augment

It might be a good idea to learn git by using your text editor of choice. Almost every of them has git interface. They also might provide a graphical way to show your git log with colorful branches.

Learning in detail

You can read all manpages that I listed above in the article, but this is unstructured and kind of boring. There is a better way to learn Git in a more detail: the book called "Pro GIT". I highly recommend to read it, but it makes more sense to read after getting the basics of git.

Common Git tasks you would need for a work

  • Making and checking (log) commits
  • Reverting and editing existing commits
  • Creating, Merging and Rebasing Branches
  • Git Cherry-pick
  • Interactive rebase
  • Show diffs
  • Conflict resolution
  • Creating pull requests or patches

Common Git glossary

The most basic terms to operate and understand git.

HEAD
current pointer to one of the branches
STAGE
list of files that being chosen for git operation (for example choosing three specific files to create one commit)
Commit
operation, that contains changes in your files
Relative commits
main^3, main~2
Branch
new HEAD pointer to the commit, that branches from for example main branch. It is main functionality for doing parallel development with other people, so you don't intersect with other people's work.
Detach
HEAD pointer, that points to specific commit and not a branch
Merge
Append work from one branch to another by creating new commit with all of the branch changes
Rebase
Append work from one branch to another by moving all commits from one branch to another
Rebase Interactive
Append work from one branch to another by moving and editing commits from one branch to another
Cherry-pick
Add existing commit to a specific commit. It works like rebase, but instead of branches it uses commits.
Remote
external repository, that being hosts somewhere on internet or anywhere else outside your computer
Fetch
loads remote branches without touching local commits and branches
Pull
fetches remote and merges it to your local branches. It can also rebase with --rebase flag.

More detailed glossary

Conclusions

I hope you got a little overview and now you are able to learn and use git yourself. I will summarize all written above in steps of learning git:

  1. Watching git overview videos
  2. https://learngitbranching.js.org/
  3. Book "Pro Git"
  4. Reading git mans starting with man gitcore-tutorial

w96k Ⓐ 2019-2022

2022-11-21 Mon 19:51