Git Core Lecture

1、Git 简介

官方介绍:Git is a fast distributed revision control system (Git 是一个快速的分布式版本控制系统)

2、Git Core Command

2.1 git init

git 工程初始化,会在工作区 (working directory) 根目录中创建.git 目录

bash 复制代码
# 创建目录
$ mkdir git-init
$ cd git-init

# git 目录初始化
$ git init

hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: 	git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: 	git branch -m <name>
Initialized empty Git repository in /core-command/git-init/.git/

说明:

  • git init 初始化的集成分支名为:master,可以通过如下命令修改
bash 复制代码
# 修改默认分支名
$ git config --global init.defaultBranch main

# 再执行初始化时,不再有如上提示
$ git init
Initialized empty Git repository in /temp/.git/
  • 命令行直接修改分支名称,(master -> main)
bash 复制代码
$ git branch -m main
  • 查看配置修改结果,通过 git config -l 命令
bash 复制代码
$ git config -l

------
init.defaultbranch=main
------

2.2 git status

显示工作区的状态,可多次使用

刚初始化的工作区是没有可提交的内容

bash 复制代码
$ git status

No commits yet

nothing to commit (create/copy files and use "git add" to track)

2.3 git add

将文件内容添加到索引中(暂存区)

该命令是在工作区中找到的当前内容更新到索引(暂存区),为下一次提交准备内容。

示例:

bash 复制代码
# 创建一个文件
$ echo '# Hello Git' > hello-git.md

# 查看工作区状态
$ git status
On branch main

No commits yet

# 未追踪的文件
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	hello-git.md

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

# 将hello-git.md文件添加到索引(暂存区)
$ git add hello-git.md

# 查看工作区状态
$ git status
On branch main

No commits yet
# 将去提交的修改
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   hello-git.md

2.4 git commit

记录仓库的修改,即将索引(暂存区)的内容提交到对象仓库

提交信息包含索引当前的内容和描述变化的给定日志信息。

示例:

bash 复制代码
# 修改内容提交到对象库
$ git commit -m 'add hello-git.md file'
[main (root-commit) f3de15d] add hello-git.md file
 1 file changed, 1 insertion(+)
 create mode 100644 hello-git.md

$ git status
On branch main
nothing to commit, working tree clean

2.5 git diff

用于对比内容差异,包括工作区和索引,索引和对象库,以及分支之间等其他可对比的内容

示例:

bash 复制代码
# 修改 hello-git.md 文件
$ cat >> hello-git.md
## Git Core Command
### git init

$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   hello-git.md

no changes added to commit (use "git add" and/or "git commit -a")

$ git diff
# 比较文件,a 是比较源文件,b 是比较目标文件
diff --git a/hello-git.md b/hello-git.md
index ab690e8..db1f38b 100644
--- a/hello-git.md
+++ b/hello-git.md
@@ -1 +1,3 @@
 # Hello Git
+## Git Core Command
+### git init

# 再次提交
# 将 git add 和 git commit 命令合并使用
$ git commit -a -m 'modify hello-git.md file'

说明

  • git 的工作空间分为三种,工作区(工作目录)、索引(暂存区)、对象库
  • git 的工作流:工作区修改的有效内容 添加到 索引 提交 到对象库

2.6 git restore

恢复工作区、索引中已修改的文件,默认恢复工作区

示例:

  • 恢复工作区
bash 复制代码
# 修改hello-git.md 文件
$ cat >> hello-git.md
git init is used to initial git working tree(directory).

$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   hello-git.md

no changes added to commit (use "git add" and/or "git commit -a")

# 撤回修改(方式一): 将修改的内容手动撤回,如果改动太多,手动改成本太高,非常不推荐
$ vim hello-git.md
......

# 撤回修改(方式二): 使用 git restore 命令恢复修改的内容
$ git restore hello-git.md
# 查看 hello-git.md 内容
$ cat hello-git.md
# Hello Git
## Git Core Command
### git init
  • 恢复索引
bash 复制代码
# 修改 hello-git.md 文件
$ cat >> hello-git.md
git init is used to initial git working tree(directory).

# 添加到索引
$ git add hello-git.md

# 查看状态
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   hello-git.md

# 从索引中恢复文件(将内容恢复到未追踪状态)
$ git restore --staged hello-git.md

$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   hello-git.md

no changes added to commit (use "git add" and/or "git commit -a")

# 恢复文件
$ git restore hello-git.md

$ git status
On branch main
nothing to commit, working tree clean

# 查看 hello-git.md 内容
$ cat hello-git.md
# Hello Git
## Git Core Command
### git init

2.7 git rm

从工作区和索引中删除文件

示例:

bash 复制代码
# 1️⃣ 新增文件 git-rm.md
$ echo '# git rm' > git-rm.md
# 第1次删除 git-rm.md 
$ git rm git-rm.md
fatal: pathspec 'git-rm.md' did not match any files (执行报错,git rm 不能删除工作区中未追踪的文件)

# 2️⃣ 添加到索引
$ git add git-rm.md
# 第2次删除 git-rm.md 
$ git rm git-rm.md
error: the following file has changes staged in the index:
    git-rm.md
(use --cached to keep the file, or -f to force removal)

# 3️⃣ 提交到对象库
$ git commit -m 'add git-rm.md file'
# 第3次删除 git-rm.md 
$ git rm git-rm.md
rm 'git-rm.md'
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	deleted:    git-rm.md

# 4️⃣ 提交到对象库
$ git commit -m 'rm git-rm.md file'

2.8 git mv

移动或重命名一个文件,目录或符号链接

示例:

bash 复制代码
# 1️⃣ 新增文件 git-mv.md
$ echo '# git mv' > git-mv.md
# 第一次 mv
$ git mv git-mv.md git-mv-target.md
fatal: not under version control, source=git-mv.md, destination=git-mv-target.md

# 2️⃣ 添加到索引
$ git add git-mv.md
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   git-mv.md
# 第二次 mv
$ git mv git-mv.md git-mv-target.md
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   git-mv-target.md

# 3️⃣ 提交到对象库
$ git commit -m 'add git-mv.md file'
# 第三次 mv
$ git mv git-mv-target.md git-mv-new.md
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    git-mv-target.md -> git-mv-new.md
# 4️⃣ 再次提交
$ git commit -m 'mv git-mv-target.md to git-mv-new.md file'

2.9 git reset

重置当前 HEAD 到指定的状态

语法

bash 复制代码
git reset [<mode>] [<commit>]

mode 模式包含如下几种

  • --mixed(默认值):移动 HEAD 指针并重置索引,不会修改工作区,撤销了提交和暂存的更改,但保留了工作区的修改
  • --soft:只移动 HEAD 指针,暂存区和工作区中的更改都会保留在工作区中,以便再次提交
  • --hard:移动 HEAD 指针并重置索引和工作区,彻底删除了提交以及暂存区和工作区的修改,慎用,因为会导致工作区的内容丢失
  • --merge 和 --keep:较少使用,适用于特殊场景。前者尝试将 HEAD 指向的提交和指定提交之间的差异应用到当前工作区,后者类似 mixed,但保留未修改的文件。

示例:

2.9.1 mode参数
--mixed (默认值)
  • 新增文件的状态流转
bash 复制代码
# 1️⃣ 新增文件 git-reset.md
$ echo '# git reset' > git-reset.md
# 第1次 git reset
$ git reset
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	git-reset.md

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

# 2️⃣ 添加到索引
$ git add git-reset.md
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   git-reset.md
# 第2次 git reset (将文件从索引退回到未追踪状态)
$ git reset
$ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	git-reset.md

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

# 3️⃣ 提交到对象库
$ git commit -m 'add git-reset.md file'
# 第3次 git reset
$ git reset
On branch main
nothing to commit, working tree clean
  • 修改文件的状态流转
bash 复制代码
# 1️⃣ 修改文件
$ cat >> git-reset.md
## git reset <mode> <commit>
mode : --soft, --mixed, --hard, --keep etc.
# 第1次 git reset
$ git reset
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   git-reset.md

# 2️⃣ 添加到索引
$ git add git-reset.md
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   git-reset.md
# 第2次 git reset(回退到未追踪状态)
$ git reset
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   git-reset.md

# 3️⃣ 提交到对象库
$ git commit -a -m 'modify git-reset.md file'
# 第3次 git reset
$ git reset
On branch main
nothing to commit, working tree clean
--soft
  • 新增文件状态流转
bash 复制代码
# 1️⃣ 新增文件 git-reset-soft.md
$ echo '# git reset --soft' > git-reset-soft.md
# 第1次 git reset --soft
$ git reset --soft
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	git-reset-soft.md

# 2️⃣ 添加到索引
$ git add git-reset-soft.md
# 第2次 git reset --soft
$ git reset --soft
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   git-reset-soft.md

# 3️⃣ 提交到对象库
$ git commit -m 'add git-reset-soft.md file'
# 第3次 git reset --soft
$ git reset --soft
$ git status
On branch main
nothing to commit, working tree clean
  • 修改文件状态流转
bash 复制代码
# 1️⃣ 修改文件 git-reset-soft.md
$ cat >> git-reset-soft.md
# git reset --soft mode is in active.
# 第1次 git reset --soft
$ git reset --soft
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   git-reset-soft.md

# 2️⃣ 添加到索引
$ git add git-reset-soft.md
# 第2次 git reset --soft
$ git reset --soft
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   git-reset-soft.md

# 3️⃣ 提交到对象库
$ git commit -m 'modify git-reset-soft.md file'
# 第3次 git reset --soft
$ git reset --soft
$ git status
On branch main
nothing to commit, working tree clean
--hard
  • 新增文件状态流转
bash 复制代码
# 1️⃣ 新增文件 git-reset-hard.md
$ echo '# git reset --hard' > git-reset-hard.md
# 第1次 git reset --hard
$ git reset --hard
HEAD is now at 64c3235 modify git-reset-soft.md file

# 2️⃣ 添加到索引
$ git add git-reset-hard.md
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   git-reset-hard.md
# 第2次 git reset --hard
$ git reset --hard
HEAD is now at 64c3235 modify git-reset-soft.md file (add 到索引的文件被删除了)
$ git status
On branch main
nothing to commit, working tree clean

# 3️⃣ 提交到对象库
$ echo '# git reset --hard' > git-reset-hard.md
$ git add git-reset-hard.md
$ git commit -a -m 'add git-reset-hard.md file'
# 第3次 git reset --hard
$ git reset --hard
$ git status
On branch main
nothing to commit, working tree clean
  • 修改文件状态流转
bash 复制代码
# 1️⃣ 修改文件 git-reset-hard.md (工作区修改的内容被撤销)
$ cat >> git-reset-hard.md
## git reset --hard
the mode of hard will remove working tree and index.
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   git-reset-hard.md
# 第1次 git reset --hard
$ git reset --hard
HEAD is now at 2f1ffeb add git-reset-hard.md file(工作区中修改的内容被删除了)
$ git status
On branch main
nothing to commit, working tree clean

# 2️⃣ 添加到索引 (添加到索引中的修改的内容被撤销)
$ cat >> git-reset-hard.md
## git reset --hard
the mode of hard will remove working tree and index.
$ git add git-reset-hard.md
# 第2次 git reset --hard
$ git reset --hard
HEAD is now at 2f1ffeb add git-reset-hard.md file (add到索引的文件被删除了)
$ git status
On branch main
nothing to commit, working tree clean

# 3️⃣ 提交到对象库(提交到对象库的不会被撤销)
$ cat >> git-reset-hard.md
## git reset --hard
the mode of hard will remove working tree and index.
$ git add git-reset-hard.md
$ git commit -a -m 'modify git-reset-hard.md file'
# 第3次 git reset --hard
$ git reset --hard
HEAD is now at b128c80 modify git-reset-hard.md file(提交到对象库的不会被删除)
$ git status
On branch main
nothing to commit, working tree clean
2.9.2 commit 参数
mode(--mixed)默认值
bash 复制代码
# 新增文件并提交到对象库
$ echo 'add git-reset-HEAD-1.md' > git-reset-HEAD-1.md
$ git add git-reset-HEAD-1.md
$ git commit -m 'add git-reset-HEAD-1.md file'

# 回退到上个提交 commit(上次提交的内容又回到工作区,可继续通过 add/commit 到对象库)
$ git reset HEAD~1
$ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	git-reset-HEAD-1.md
mode(--soft)
bash 复制代码
# 新增文件并提交到对象库
$ echo 'add git-reset-HEAD-1.md' > git-reset-HEAD-1.md
$ git add git-reset-HEAD-1.md
$ git commit -m 'add git-reset-HEAD-1.md file'

# 回退到上个提交 commit(上次提交的内容又回到暂存区,可继续通过 commit 到对象库)
$ git reset --soft HEAD~1
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   git-reset-HEAD-1.md
mode(--hard)
bash 复制代码
# 新增文件并提交到对象库
$ echo 'add git-reset-HEAD-1.md' > git-reset-HEAD-1.md
$ git add git-reset-HEAD-1.md
$ git commit -m 'add git-reset-HEAD-1.md file'

# 回退到上个提交 commit(上次提交的内容从工作区和暂存区全部删除)
$ git reset --hard HEAD~1
HEAD is now at b128c80 modify git-reset-hard.md file
$ git status
On branch main
nothing to commit, working tree clean

3、Git Branch

git branch 是用于创建、删除以及查看分支信息

3.1 查看分支

列出当前 git 工程的所有分支

bash 复制代码
# 列出所有分支
$ git branch
* main

# 列出所有分支详情
$ git branch -v (--verbose)
* main b128c80 modify git-reset-hard.md file

说明

  • main:表示分支名称
  • *:星号标识当前的分支

3.2 新建分支

bash 复制代码
# 新建 test 分支
$ git branch test

# 查看分支
$ git branch
* main
  test

3.3 切换分支

  • 方式一:checkout
bash 复制代码
# 切换到 test 分支
$ git checkout test
Switched to branch 'test'

# 查看分支
$ git branch
  main
* test
  • 方式二:switch
bash 复制代码
# 切换到 main 分支
$ git switch main
Switched to branch 'main'

# 查看分支
$ git branch
* main
  test
  • 方式三(推荐):switch
bash 复制代码
# 新建并切换到uat分支
$ git switch -c uat
Switched to a new branch 'uat'

$ git branch
  main
  test
* uat
  • 方式四(切换到上个分支):switch
bash 复制代码
# 切换到 main
$ git switch main
Switched to branch 'main'

# 切换到上个分支
$ git switch -
Switched to branch 'uat'

# 多次使用可在 main 和 uat 分支来回切换
$ git switch -
Switched to branch 'main'

3.4 删除分支

bash 复制代码
# 1️⃣ 删除 test 分支 (test 分支没有需要合并到 main 分支内容时可直接删除)
$ git branch -d test
Deleted branch test (was b128c80).

# 2️⃣ 新建 test 分支,且增加一个提交
$ git switch -c test
$ echo 'add test.md file in test branch' > test_branch.md
$ git add test_branch.md
$ git commit -m 'add test.md file'

# 先切换到 main 分支
$ git switch main 
# 再次删除 test 分支(不能删除当前分支)
$ git branch -d test
error: The branch 'test' is not fully merged.
If you are sure you want to delete it, run 'git branch -D test'.

说明:test 分支有未 merge 到 main 分支的 commit,所以删除报错,要删除有 2 种方式

  • 合并到 main 后删除
bash 复制代码
# test 分支合并到 main
$ git mrege test
Updating b128c80..495a531
Fast-forward
 test_branch.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 test_branch.md

 # 删除 test 分支(成功删除)
 $ git branch -d test
 Deleted branch test (was 495a531).
  • 强制删除分支:git branch -D test
bash 复制代码
# 新建 test 分支
$ git switch -c test

# 强制删除
$ git branch -D test
Deleted branch test (was c9d4915).

3.5 修改分支

bash 复制代码
# 移动或重命名分支(test -> test-new)
$ git branch -m test test-new
$ git branch
* main
  test-new
  uat

# 复制分支(test-new -> test-new-copy)
$ git branch -c test-new test-new-copy
$ git branch
* main
  test-new
  test-new-copy
  uat

3.6 合并分支

bash 复制代码
# 创建 feature 分支
$ git switch -c feature-add-readme

# 新建一个提交
$ echo '# Git add new Feature' > README.md
$ git add README.md
$ git commit -m 'add readme.md file'

# feature 分支合并到 main 分支
$ git switch main
$ git merge feature-add-readme
Updating b128c80..d3ecec6
Fast-forward
 README.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

说明:

  • 分支合并并不总是一帆风顺的,总会出现冲突,此时可以通过 git diff 查看差异并修正,修正后可通过 **git merge --continue **继续合并。如果不想再合并,可通过 **git merge --abort **放弃本次合并
  • 如果合并分支差异很多,建议使用 GUI 工具进行查看差异并合并

3.7 分支隐藏变化内容

工作中经常情况是,正在某个分支开发需求,但是突然线上有问题需要紧急修复 bug。此时可以用过stash指令,将已修改的内容保存后,再去切换到主分支进行修复 bug。

bash 复制代码
# test分支正开发需求(添加一个文件,修改一个文件)
$ echo 'add test-stash.md file' > test-stash.md
$ git add test-stash.md
$ cat >> README.md
working on feature readme.md file
$ git status
On branch test
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   test-stash.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   README.md

# 隐藏修改的内容
$ git stash
Saved working directory and index state WIP on test: d3ecec6 add readme.md file
# 查看隐藏的修改内容
$ git stash list
stash@{0}: WIP on test: d3ecec6 add readme.md file

# 切换到 main 分支修复 bug
$ git switch main
------on-fix-bug------

# 切换到 test 分支
$ git switch -

# 恢复隐藏的内容,继续开发新需求
$ git stash pop
On branch test
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   test-stash.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   README.md

# 删除隐藏的内容
Dropped refs/stash@{0} (2e5f54e16dbe17da875c2a542edacd64f0532a89)

# 查看隐藏列表
$ git stash list
// 空内容

stash 其他参数

数据准备:

bash 复制代码
# 将上面的内容继续隐藏
$ git stash
Saved working directory and index state WIP on test: d3ecec6 add readme.md file

# 添加隐藏
$ echo 'add test-stash-2.md file' > test-stash-2.md
$ git add test-stash-2.md
$ git stash
Saved working directory and index state WIP on test: d3ecec6 add readme.md file
# 添加隐藏
$ cat >> test-stash-2.md
modify test-stash-2.md file
$ git add test-stash-2.md
$ git stash
Saved working directory and index state WIP on test: d3ecec6 add readme.md file

# 查看
$ git stash list
stash@{0}: WIP on test: d3ecec6 add readme.md file
stash@{1}: WIP on test: d3ecec6 add readme.md file
  • drop:删除一条隐藏的内容
bash 复制代码
# 删除指定 stash
$ git stash drop stash@{0}
Dropped stash@{0} (db32a1ec419ad2b74bffe23755102e146f9d170a)

# 查看
$ git stash list
stash@{0}: WIP on test: d3ecec6 add readme.md file
  • clear : 移除所有已隐藏的内容
bash 复制代码
# 添加隐藏
$ echo 'add test-stash-3.md file' > test-stash-3.md
$ git add test-stash-2.md
$ git stash
Saved working directory and index state WIP on test: d3ecec6 add readme.md file

# 查看
$ git stash list
stash@{0}: WIP on test: d3ecec6 add readme.md file
stash@{1}: WIP on test: d3ecec6 add readme.md file

# 清空所有 stash
$ git stash clear

# 查看
$ git stash list
// 空内容
相关推荐
等一场春雨22 分钟前
Java设计模式 八 适配器模式 (Adapter Pattern)
java·设计模式·适配器模式
可涵不会debug23 分钟前
Git 分支管理与多人协作实战指南
git
一弓虽43 分钟前
java基础学习——jdbc基础知识详细介绍
java·学习·jdbc·连接池
王磊鑫44 分钟前
Java入门笔记(1)
java·开发语言·笔记
硬件人某某某1 小时前
Java基于SSM框架的社区团购系统小程序设计与实现(附源码,文档,部署)
java·开发语言·社区团购小程序·团购小程序·java社区团购小程序
程序员徐师兄1 小时前
Java 基于 SpringBoot 的校园外卖点餐平台微信小程序(附源码,部署,文档)
java·spring boot·微信小程序·校园外卖点餐·外卖点餐小程序·校园外卖点餐小程序
安冬的码畜日常1 小时前
【Vim Masterclass 笔记22】S09L40 + L41:同步练习11:Vim 的配置与 vimrc 文件的相关操作(含点评课内容)
笔记·vim·vim配置·vim同步练习·vim options·vim option-list
chengpei1471 小时前
chrome游览器JSON Formatter插件无效问题排查,FastJsonHttpMessageConverter导致Content-Type返回不正确
java·前端·chrome·spring boot·json
五味香2 小时前
Java学习,List 元素替换
android·java·开发语言·python·学习·golang·kotlin
Joeysoda2 小时前
Java数据结构 (从0构建链表(LinkedList))
java·linux·开发语言·数据结构·windows·链表·1024程序员节