Git笔记

一 git简介

工作区

暂存区 -> add

本地仓库(版本库) -> commit

远程仓库 -> push

二 git 安装

一是先安装包管理器Homebrew,然后通过Homebrew安装Git(推荐):

ruby 复制代码
$ brew install git

2.1 查看全局配置

css 复制代码
$ git config --global --list

2.2 配置git

arduino 复制代码
$ git config --global user.name "Your Name"

$ git config --global user.email "email@example.com"

三 创建版本库(本地git仓库)

3.1 新建文件夹

  • 创建本地 learngit 文件夹,指向 learngit 文件夹,查看当前文件路径
Shell 复制代码
$ mkdir learngit 
$ cd learngit
$ pwd
/Users/michael/learngit

3.2 git init命令把这个目录变成Git可以管理的仓库:

bash 复制代码
$ git init

Initialized empty Git repository in /Users/michael/learngit/.git/

第一步,用命令git add告诉Git,把文件添加到仓库:

shell 复制代码
(base) myth@MythdeMacBook-Pro-2 learngit % git add readme.txt                

(base) myth@MythdeMacBook-Pro-2 learngit %

第二步,用命令git commit告诉Git,把文件提交到仓库:

shell 复制代码
(base) myth@MythdeMacBook-Pro-2 learngit % git commit -m "wrote a readme file"

[main (root-commit) fc7c1c9] wrote a readme file

 1 file changed, 2 insertions(+)

 create mode 100644 readme.txt

(base) myth@MythdeMacBook-Pro-2 learngit %

git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

四 时光穿梭

git status 命令看看结果

shell 复制代码
$ 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:   readme.txt

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

(base) myth@MythdeMacBook-Pro-2 learngit %


----
在主分支
修改未暂存
   (使用 git add<file>... 去更新要被提交的内容)
   (使用git restore <file>..."来放弃工作目录中的更改)
   
修改过的 : readme.txt

git diff 查看修改内容

git diff 工作区 vs 暂存区(只看没 add 的改动)

git diff --cached / --staged 暂存区 vs 版本库 HEAD(看 add 完没 commit 的)

git diff HEAD 工作区 vs 版本库(全部差异)

shell 复制代码
// 修改readme.text

Git is a version control system.
Git is free software.

vs

Git is a version control system.
Git is free software.
New 啦啦啦啦
diff 复制代码
// 比较 工作区 vs 暂存区

$ git diff readme.txt 

diff --git a/readme.txt b/readme.txt****

index 46d49bf..aee6eb0 100644****

--- a/readme.txt****

+++ b/readme.txt****

@@ -1,2 +1,3 @@

 Git is a version control system.

 Git is free software.

+New 啦啦啦啦
diff 复制代码
// 添加暂存区 提交到版本库

$ git add readme.txt                 

$ git commit -m "add distributed"

[main 0f03200] add distributed

 1 file changed, 1 insertion(+)

4.1 版本回退

4.1.1 git reset

上一个版本就是HEAD^

上上一个版本就是HEAD^^

当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

shell 复制代码
// 回退到上一次版本

$ git reset --hard HEAD~1

HEAD is now at 02b41a1 添加代码

--hard会回退到上个版本的已提交状态

--soft会回退到上个版本的未提交状态,

--mixed会回退到上个版本已添加但未提交的状态。

按照 id 号回退, git reset --hard b4240(id号咋找? 从git log或 git reflog)

diff 复制代码
$ git reset --hard b4240

HEAD is now at b4240c3 再次添加代码

4.1.2 git log

查看提交日志, 自下而上 -> 从旧到新

diff 复制代码
$ git log                

commit 02b41a1d79b6cc75cceb48aae149247dd3d4fae1 (HEAD -> main)

Author: Music <122145736@qq.com>

Date:   Mon Jun 8 11:30:23 2026 +0800  

    添加代码

commit d68a0db0eb10f5f00398ce684e0a3e7d4432d2dd

Author: Music <122145736@qq.com>

Date:   Mon Jun 8 11:29:10 2026 +0800
 
    初始化readme.txt

(base) myth@MythdeMacBook-Pro-2 learngit %

4.1.3 git reflog

git reflog用来记录你的每一次命令, 比git log更全

diff 复制代码
$ git reflog

b4240c3 (HEAD -> main) HEAD@{0}: reset: moving to b4240

02b41a1 HEAD@{1}: reset: moving to HEAD~1

b4240c3 (HEAD -> main) HEAD@{2}: commit: 再次添加代码

02b41a1 HEAD@{3}: commit: 添加代码

d68a0db HEAD@{4}: commit (initial): 初始化readme.txt

4.2 工作区 & 暂存区

stage(或者叫index)的暂存区

还有Git为我们自动创建的第一个分支master

指向master的一个指针叫HEAD

4.3 管理修改

shell 复制代码
++ 修改a
++ git add
++ 修改b
++ commit

结果仅仅提交了 修改a
修改b还在工作区
shell 复制代码
$ git diff HEAD -- readme.txt 
diff --git a/readme.txt b/readme.txt
index 76d770f..a9c5755 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
 Git is a distributed version control system.
 Git is free software distributed under the GPL.
 Git has a mutable index called stage.
-Git tracks changes.
+Git tracks changes of files.

-- 代表版本库 ++ 代表工作区

4.4 撤销修改 checkout

shell 复制代码
$ git checkout -- readme.txt

// 修改后未加入暂存区  
效果: 撤销工作区修改

// 修改后加入暂存区  
效果: 无操作

// 修改后加入暂存区, 继续修改(默认保存工作区)  
效果: 撤销工作区修改(回到暂存后状态)
shell 复制代码
$  git reset HEAD <file>

// 修改文件状态
效果: 暂存区 退回 工作区 

4.5 删除文件

shell 复制代码
// 删除文件 并提交 

$ git rm test.txt

$ git commit -m "add test.txt"

为啥没有add 就可以提交呢?

  • rm 等同于 rm + add

五 远程仓库

5.1 添加远程仓库

本地版本库 -> 关联远程仓库 -> 推送版本库

5.1.1 创建本地版本库

shell 复制代码
# 1. cd 你的文件夹

# 2. 初始化成 Git 仓库 git init

# 3. 添加文件并提交 git add git commit -m "提交信息"

5.1.2 本地版本库 关联 远程仓库

shell 复制代码
// 关联

$ git remote add origin https://gitee.com/liyang1937/classbegin
shell 复制代码
# git remote add ~ 添加新的远程仓库地址

# orgin ~远程仓库别名, 不在gitee上显示, 保存在版本库 .git/config内, 代表远程地址

# https://gitee.com/liyang1937/classbegin ~ 远程仓库的地址
shell 复制代码
# 删除关联的远程仓库
$ git remote remove <远程仓库别名>

# 删除关联的远程仓库
$ git remote remove origin

# 查看关联的远程仓库
$ git remote -v

5.1.3 推送本地版本库

shell 复制代码
# 推送本地版本库

git push -u origin <分支名>

# git push -u origin main
shell 复制代码
# 查看本地所有分支
$ git branch -a
* main

// 推送分支
$ git push -u origin main


# -u: --set-upstream` 的缩写,意思是"建立上游关联"

# origin: 远程仓库的别名(你之前添加的)

# main: 要推送的本地分支名

推送需要填写 远程仓库的账户密码

Username for 'gitee.com': classbegin

Password for 'classbegin@gitee.com': ****

5.2 从远程仓库克隆

5.2.1 HTTPS 方式克隆

shell 复制代码
$ git clone git@github.com:michaelliao/gitskills.git <文件路径>
shell 复制代码
$ git clone https://gitee.com/liyang1937/classbegin.git /Users/myth/Desktop/classbegin

# 注意: 文件路径要是空的, 不能提前创建好, 否则报错(桌面不能提前创建好classbegin这个文件夹)

使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https

5.2.2 SSH 方式克隆

本地电脑生成一对钥匙 -> 公钥给gitee

第一步:生成 SSH 密钥(在本地电脑操作)
shell 复制代码
ssh-keygen -t ed25519 -C "你的Gitee邮箱地址"
shell 复制代码
ssh-keygen -t ed25519 -C "liyang1937@126.com"

# ssh-keygen: 秘钥生成器
# -t ed25519 -C 指定密钥类型
# -C "注释" 添加注释, 不写也行
第二步:添加公钥到 Gitee 并复制
shell 复制代码
// 查看公钥

cat ~/.ssh/id_ed25519.pub
第三步:粘贴到 Gitee

设置 -> 安全设置 -> ssh公钥 -> 粘贴 + 提交

第四步:验证并克隆
shell 复制代码
$ ssh -T git@gitee.com

# 如果看到 `Hi 用户名! You've successfully authenticated...` 的提示,就说明成功了
shell 复制代码
git clone git@gitee.com:liyang1937/classbegin.git /Users/myth/Desktop/abc

# 项目克隆到 /Users/myth/Desktop/abc 中

六 分支管理

6.1 创建与合并分支

head 指针 指向当前分支

6.1.2 切换分支 checkout / switch

shell 复制代码
// 创建并切换分支

$ git checkout -b dev
Switched to a new branch 'dev'

# -b创建分支
shell 复制代码
相当于
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
shell 复制代码
// 创建并切换分支

$ git switch -c dev

# -c创建分支
shell 复制代码
// 切换分支

$ git switch master

6.1.3 查看分支 branch

shell 复制代码
$ git branch
* dev
  master

git branch命令会列出所有分支,当前分支前面会标一个*号。

6.1.4 合并分支 merge

shell 复制代码
$ git checkout master
$ git merge dev

6.2 解决冲突

git log --graph 查看分支合并图

6.3 分支管理策略

shell 复制代码
$ git merge --no-ff -m "采用普通合并" dev
Merge made by the 'recursive' strategy.
 readme.txt | 1 +
 1 file changed, 1 insertion(+)

6.4 bug分支

6.4.1 暂存代码

shell 复制代码
// 1 暂存代码

$ git stash save "首页需求"
Saved working directory and index state On main: 首页需求
shell 复制代码
// 2 查看所有暂存

$ git stash list           

stash@{0}: On main: 首页需求
stash@{1}: On main: 一个牛逼的需求
shell 复制代码
// 3 回到暂存 并 保存当前暂存 (回到最近的暂存)

$ git stash apply

$ git stash list 
#暂存未删除

stash@{0}: On main: 首页需求
stash@{1}: On main: 一个牛逼的需求
shell 复制代码
// 4 退出暂存 且 保留暂存 (回到暂存前)

$ git reset --hard head         
HEAD is now at 80b784d 提交lalal

$ git stash list  
stash@{0}: On main: 首页需求
stash@{1}: On main: 一个牛逼的需求
shell 复制代码
// 5 退出暂存 并 删除当前暂存 (回到最近的暂存)

$ git stash pop

$ git stash list
# 删除了当前暂存 "首页需求"

stash@{0}: On main: 一个牛逼的需求
shell 复制代码
// 6 读取某个暂存

$ git stash list   

stash@{0}: On main: 个人中心
stash@{1}: On main: 一个牛逼的需求

$ git stash apply stash@{1}
# 获取暂存(保留记录)

git stash pop stash@{0}
# 获取暂存(删除记录)

6.5 feature分支

每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。

6.6 多人协作

shell 复制代码
// 1 查看远程库信息

$ git remote -v
origin  git@github.com:michaelliao/learngit.git (fetch)
origin  git@github.com:michaelliao/learngit.git (push)
shell 复制代码
// 2 推送 分支到远程

$ git push origin dev

# origin: 别名 等价于上面的地址

6.7 rebase 变基

rebase: 把你要提交的东西,假装是在最新代码基础上写出来的

啥是变基 ?

shell 复制代码
A --- D (远程最新)
 \
  B --- C (你的)

# 你早上开始写代码时,远程代码是 A,并开发需求B,C

# 同事这时候推送了 D(也在 A 基础上)。
shell 复制代码
A --- D --- B' --- C' (你的,现在基于 D)

# 变基后
shell 复制代码
$ git log --graph --pretty=oneline --abbrev-commit
* 582d922 (HEAD -> master) add author
* 8875536 add comment
* d1be385 (origin/master) init hello
*   e5e69f1 Merge branch 'dev'
|\  
| *   57c53ab (origin/dev, dev) fix env conflict
| |\  
| | * 7a5e5dd add env
| * | 7bd91f1 add new env
...
shell 复制代码
*****: 代表当前主分支(最外层)的提交
| *:   代表第一层子分支上的提交
||*:   代表第二层子分支上的提交
| * |: 代表也是第一层子分支,但右边还有另一个分支在并行

origin/master: 远程master
HEAD -> master: 本地maseter (默认最上面的才标记HEAD)

git pull : 拉取 + 合并(产生一个合并提交)

git pull --rebase (推荐) : 拉取 + rebase(历史变直线)

七 标签管理

7.1 创建标签

arduino 复制代码
// 添加标签

$ git tag <版本号>

# git tag v1.0
shell 复制代码
// 添加标签 + id

$ git tag v0.9 f52c633

# 如果你当时忘记打标签, 可以采用id打标签后补
shell 复制代码
// 添加标签 + 备注

git tag -a v0.1 -m "version 0.1 released" 1094adb
shell 复制代码
// 查看所有标签

$ git tag

7.2 操作标签

shell 复制代码
// 删除标签


git tag -d v1.0.0
# 删除本地标签


git push origin --delete v1.0.0
# 删除远程标签


git push origin :v1.0.0
# 或者(推送空值覆盖)

八 忽略文件相关

8.1 忽略文件 .gitignore

项目根目录的 .gitignore, 作用范围为 仅限当前项目

全局的 .gitignore_global, 作用范围为 电脑上所有Git 项目生效 (sourcetree偏好设置中)

8.2 配置 gitignore文件中忽略某类型, 但是还是被监听变化呢

  • 配置 .gitignore 后文件仍然出现,通常是因为该文件之前已经被 Git 追踪(track)了.gitignore 只对尚未被追踪的文件生效。

例如 *.xcuserstate文件 文件设置忽略, 却还是更新

shell 复制代码
# 1 指向 xcuserstate 所在文件夹
$ cd /Users/myth/Desktop/learn-swift1/learn-swift1.xcworkspace/xcuserdata


# 2 查看 xcuserdata 目录下所有被git追踪的文件
$ git ls-files /Users/myth/Desktop/learn-swift1/learn-swift1.xcworkspace/xcuserdata


# 3 检测出文件夹下 xcuserstate 及 xcbkptlist 被git追踪
myth.xcuserdatad/UserInterfaceState.xcuserstate
myth.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist


# 4 解除整个 xcuserdata 目录的追踪
$ git rm -r --cached /Users/myth/Desktop/learn-swift1/learn-swift1.xcworkspace/xcuserdata
rm 'learn-swift1.xcworkspace/xcuserdata/myth.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist'


# 5 提交 + 推送 删除变化 
git commit -m "停止追踪 xcuserdata 目录"  
git push 

或者 
source中操作 提交 + 推送

liaoxuefeng.com/books/git/t...

相关推荐
bonechips1 小时前
JS:同步与异步,从单线程到 Promise 的编程之路
前端·javascript
如果超人不会飞1 小时前
TinyVue Pager分页组件使用指南
前端·vue.js
Aolith1 小时前
从 Pinia 到 Zustand:我在 React 里复刻了一套用户状态管理
前端·react.js·typescript
先吃饱再说1 小时前
为什么 `setTimeout` 会“插队”?JS 事件循环与 Promise 通关笔记
前端·javascript·promise
龙井>_<1 小时前
vsCode解决css代码补全不生效问题,UnoCSS插件失效修复
前端·css·ide·vscode
Web打印2 小时前
HttpPrinter Web打印中间件 wiki.httpprinter.com 知识库内容总结
前端·中间件
2501_918126912 小时前
一个上帝类程序作画
前端·css·css3
如意IT2 小时前
浏览器CDP自动化检测技术-Error和Worker
前端·javascript·自动化·chromium·指纹浏览器
IT_陈寒2 小时前
Python列表的+=操作符坑了我一整天
前端·人工智能·后端