Bo2SS

Bo2SS

1 Git Basics

Local test environment: macOS 11

01 | Course Overview#

VSC: Version Control System

  • Centralized - The client must always be connected to the server
    • SVM
  • Distributed - Both server and client have complete version repositories
    • Git, developed by Linus
    • Git-based open-source community - Background: DevOps era, development and operations
      • GitHub - the largest globally
      • GitLab - commonly used by companies; free, provides Continuous Integration (CI); such as Alibaba Cloud, Dianping

02 | Installing Git#

03 | Minimum Configuration Needed Before Using Git#

## Add name and email configuration
git config [--local | --global | --system] user.name 'Your name'
git config [--local | --global | --system] user.email 'Your email'
## View existing configuration
git config --list [--local | --global | --system]
## Differences
##  --local: This repository
##  --global: All repositories of the current user
##  --system: All users of this system
  • Purpose: Record personnel information, can also correspond to email reminders during CR (Code Review)

04 | Create Your First Repository and Configure Local User Information#

  • Two ways to create a repository, both will generate a .git folder
## Create a git repository in an existing project folder
git init
## Create a new git repository named [Project Name]
git init [Project Name]
  • If you need to configure local user information separately, use --local configuration, which has the highest priority, see the previous section
  • Perform a simple commit❗️
## Add files to this git project, omitted
## Add files to commit
git add [File Name]
### PS: Add all files in the current path - git add .
## Commit operation with accompanying information
git commit -m'Some Message'
### View git status, e.g., which files are pending commit, which are untracked
git status
### View git records, e.g., commit records
git log

05 | Understanding the Working Directory and Staging Area Through Several Commits#

image

  • Staging Area❗️ - One of the essences of Git
    • Use case: Develop two solutions, after completing the first solution, stage it first, then work on the second solution. If the second solution is not as good as the first, you can revert to the first.
    • PS:
      • If you want to replace a file in the working directory with the staging area, use git checkout -- file
      • If you want to restore all changed files in the working directory to be the same as in the staging area, use git checkout *
  • git add -u vs git add .
    • The former: only operates on tracked files, adding modifications and deletions of files to the staging area
    • The latter: also operates on newly created files, adding creation, modification, and deletion of files to the staging area
    • PS: git add all/-A applies to the entire repository, not just the current path
  • Specific operations are similar to the previous section - a simple commit

06 | A Convenient Way to Rename Files#

  • Detailed steps
## Rename
mv readme readme.md
## Add new file readme.md
git add readme.md
## Remove the tracked old file readme
git rm readme
## Commit
git commit -m"rename"
  • Use git reset --hard to revert to the latest commit, which clears the staging area
  • Show simplified steps
## One command replaces the three above
git mv readme readme.md
## Commit
git commit -m"rename"
  • Practical demonstration

image

Observe the status of the staging area in real-time through git status.

PS: The first method can also detect that it is renamed using git status

07 | View Version Evolution History Through git log#

## View concise single-line history
git log --oneline
## View the last 4 entries in history
git log -n4
git log -4 
## View history of all branches
git log --all
## View history of a specified branch (named BRANCH_NAME)
git log BRANCH_NAME
## View graphical version history
git log --graph
## Combined use: View the last 4 graphical single-line histories of all branches
git log --all -n4 --graph --oneline
## Jump to the web version of the git log help document
git help --web log
  • git log --all -n4 --graph --oneline effect diagram

image

Additional commands

  • git branch View what local branches exist, -a will view both local and remote branches
  • git checkout -b <new_branch> []
    • Create a new branch named new_branch (based on the commit hash value as the start point)
    • For convenience, the start point can be a fragment of the hash value, as long as it uniquely identifies the commit
  • git commit -am'msg'
    • Directly adds files in the working directory and staging area to the version library, equivalent to using add
    • ⚠️: Can only commit files that have already been tracked; newly created files still need to be added to the staging area first using git add .

PS

  • You can set a more user-friendly log display method through aliases in ~/.zshrc, and use lg ... after setting
alias lg="git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
  • Generally, single-letter options correspond to -, while non-single-letter options are --

08 | gitk: View Version History Through Graphical Interface Tool#

  • Install on Mac: brew install git-gui
  • Use: gitk
  • Simple interface display

image

  1. Select View-New View, then select All refs to display all branch and Tag information
  2. Right-click on a commit for many operations, such as Create tag

PS

  • Why does a commit have both an Author and a Committer?
    • Respect copyright
    • For example, the git cherry-pick command: applies a specified commit to another branch
    • For specific usage, refer to git cherry-pick tutorial - Ruanyifeng
  • Also recommend a Git graphical interface tool: Sourcetree, actually, tools are quite similar, depending on personal habits

09 | Exploring the .git Directory#

Git has excellent storage capabilities, allowing version management locally without a network

image

  • 🌟 Four key files: HEAD, config, refs, objects, analyzed one by one below
  • ❗️ Three important objects: commit, tree, blob, PS: tag

image

  1. The relationship diagram above, refer to GIT Object Model - Git Community Book Chinese Version
  2. blob: Full name Binary Large Object, can be understood as a file object
  3. The next section will delve deeper, but first, let's look at the four key files~
  • HEAD: Points to the currently active branch

image

Manually modifying the branch in HEAD has the same effect as git checkout

  • config: Local repository (local) configuration information

image

Mainly focus on user information

Manually modifying the config file has the same effect as git config --local

  • refs: Contains heads and tags folders

image

  • Each branch in heads stores a commit hash value
  • Each milestone in tags also stores a commit hash value
    • It may also be a tag hash value, which points to a commit
  • git cat-file: Displays information about repository objects
    • -t: Type
    • -p: Content (using the cat command directly may display garbled text, as these objects need to be parsed)
    • The latter takes a unique hash value or filename

PS: Careful observers will find that a commit stores a tree hash value, which connects back to the initial relationship diagram; try checking the contents of the tree

  • objects: Stores all objects, including tree / blob / commit

image

    1. Most folders 📁 are named with the first 2 characters of the hash value, containing files named with 38 characters
    • This 40-character hash value uniquely points to an object
    1. The tree object stores blob object information, and the content of the blob object is the content of a file, such as css.x
    • The tree object can also store information about another tree object
    • As long as the file content is the same, in Git's eyes, it is a unique blob
    1. The content of the blob object is consistent with the content of the file it points to
    • Will it always be consistent? Not necessarily, it depends on the version
  • PS: There are also pack and info folders
    • The former is used to store packaged loose folders, while the latter works in conjunction with the former

10 | The Relationship Between commit, tree, and blob Objects#

The previous section mentioned these three; this section will look at a commit in detail to deepen understanding

image

  • This is the relationship diagram of the three; pay attention to the direction of the arrows, refer to GIT Object Model - Git Community Book Chinese Version
  • Analysis
    • The content of a commit is managed by a tree, and there is exactly one tree
      • It stores a snapshot of all folders and files in the current commit
    • A tree can have multiple subtrees and multiple blobs
    • A blob stores the specific information of a file object
      • The same file content is unique, regardless of the filename
  • Example

image

commit👉tree👉blob + tree

PS: lg is the friendly display command for git log configured in section 7

11 | Small Exercise: Count the Number of Trees#

A newly created Git repository contains exactly 1 commit, which only includes /doc/readme
How many trees and blobs does it contain?

Let's start the experiment🧪

## First, create a Git repository
git init watch_git_object
## Enter the repository, create a doc folder, and add readme
cd watch_git_object
mkdir doc
echo "hello, world" > doc/readme
## At this point, check if there are any file-type files in .git/objects: empty
find .git/objects -type f
## Add doc to the staging area
git add doc/
## Check again: Git generates a blob object, recording the content of readme
find .git/objects -type f

image

  • Adding to the staging area will generate a blob object
  • ❗️At this point, there are still no commit or tree objects; proceed to commit
## Perform commit
git commit -m'Add readme'
## Check the files in .git/objects: there are already 4
find .git/objects -type f
## Check their types and contents one by one, as shown in the figure below
git cat-file -t ***
git cat-file -p ***

image

  • It can be seen that a new: 1 commit, 2 trees have been generated
  • Their relationship is:
    • commit👉tree (commit corresponds to one tree)👉tree (doc folder)👉blob (readme file)

12 | Precautions in Detached HEAD State#

detached HEAD

  • Occurs when switching HEAD to a specific commit (even the latest commit of a branch)

image

git checkout <HASH_OF_COMMIT>, rather than a specific branch

At this point, a detached HEAD situation will occur; you can perform some experimental operations and commit

  1. If you do not want to keep these commits: you can switch back to the branch directly without any additional operations

  2. If you want to keep these commits: you need to create a new branch from here to link it with the branch

  • Next, make some modifications to readme and commit, then switch back to a branch

image

Git provides a friendly reminder: If you want to keep the recent commits, you can create a new branch using the commit's hash value

Use gitk to check the current branch situation, and you will see that the previous commit is not visible

image

Execute the friendly reminder command git branch fix_readme 34976f8

image

The previous commits are now linked to the fix_readme branch

  • Summary
    • Use case: To perform some experimental attempts
    • ⚠️: When wanting to keep the commits made, it must be linked to a branch

13 | Further Understanding HEAD and Branch#

  • Learn with two questions:
  1. What happens to HEAD when creating a new branch? (What does HEAD point to)
  2. What are the usage tips related to HEAD? (Referring to commits, special markers ^, ~)

Let's explore one by one:

  • 1

HEAD can point to a specific branch or a specific commit

Using the command git checkout -b <NEW_BRANCH_NAME> <BASE_BRANCH_NAME/HASH_OF_COMMIT>, create a new branch based on a certain branch or commit, and switch to the new branch

image

You can see: HEAD changes from pointing to the detached HEAD to pointing to the fix_new branch

Next, observe the information in the HEAD file

image

In fact, HEAD points to a branch, and that branch points to a specific commit

  • 2

Since HEAD ultimately points to a commit, it can also be used to refer to the commit's hash value~

For example, when using git diff <A> <B> to compare two commits

image

The above three commands are equivalent, namely:

git diff 34976f8 a60a3d5, git diff HEAD HEAD~, git diff HEAD 'HEAD^'

⚠️:

The ^ and ~ markers of HEAD can retrieve the ancestor commits of HEAD; their differences can be referenced in the diagram below:

image

The direction of this branch diagram is opposite to that generated by git log --graph, where A is the smallest; and it combines the situation of merge branches

Refer to What's the difference between HEAD^ and HEAD~ in Git? - StackOverflow

PS: In zsh, ^ has a special meaning, so it needs to be enclosed in quotes

Having learned this, have you updated your understanding of Git? Are you looking forward to the Next Part?!

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.