git
git 操作
版本控制
集中式(svn)
svn 因为每次存的都是差异 需要的硬盘空间会相对的小一点 可是回滚的速度会很慢
优点:
代码存放在单一的服务器上 便于项目的管理
缺点:
服务器宕机: 员工写的代码得不到保障
服务器炸了: 整个项目的历史记录都会丢失
分布式(git)
git 每次存的都是项目的完整快照 需要的硬盘空间会相对大一点(Git 团队对代码做了极致的压缩 最终需要的实际空间比svn 多不了太多 可是 Git 的回滚速度极快)
优点:
完全的分布式
缺点:
学习起来比 SVN 陡峭
git配置
git config --global user.name "..."
git config --global user.email "..."
git config --list
底层命令
基础的 linux 命令
clear
清除屏幕
echo 'test content'
往控制台输出信息
echo 'test content' > test.txt
创建文件
ll
将当前目录下的子文件&子目录平铺在控制台
find 目录名
将对应目录下的子孙文件&子孙目录平铺在控制台
find 目录名 -type f
将对应目录下的文件平铺在控制台
rm 文件名
删除文件
mv 源文件 重命名文件
重命名
cat 文件的url
查看对应文件的内容
vim 文件的url(在英文模式下)
- 按i进插入模式进行文件的编辑
- 按esc键&按:键进行命令的执行
- q! 强制退出(不保存)
- wq 保存退出
- set nu 设置行号
初始化新仓库
初始化后,在当前目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中。
命令:git init
.git目录
hooks 目录包含客户端或服务端的钩子脚本
info 包含一个全局性排除文件
logs 保存日志信息
objects 目录存储所有数据内容
refs 目录存储指向数据的提交对象的指针(分支)
config 文件包含项目特有的配置选项
description 用来显示对仓库的描述信息
HEAD 文件指示目前被检出的分支
index 文件保存暂存区信息
git 对象
git 的核心部分是一个简单的键值对数据库。你可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索该内容
- 向数据库写入内容并返回对应键值
echo 'test content' | git hash-object -w --stdin
-w 选项指示 hash-object 命令存储数据对象;若不指定此选项,则该命令仅返回对应的键值
--stdin(standard input)选项则指示该命令从标准输入读取内容;若不指定此选项,则须在命令尾部给出待存储文件的路径 - 查看 Git 是如何存储数据的
find .git/objects -type f
返回: .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
这就是开始时 git 存储内容的方式:一个文件对应一条内容。校验和的前两个字符用于命名子目录,余下的38个字符则用作文件名。 - 根据键值拉取数据
git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
-p 选项可指示该命令自动判断内容的类型,并为我们显示格式友好的内容
返回对应文件的内容
注意:
当前的操作都是在对本地数据库进行操作 不涉及暂存区
构建树对象
树对象(tree object),它能解决文件名保存的问题,也允许我们将多个文件组织到一起。Git 以一种类似于 UNIX 文件系统的方式存储内容。所有内容均以树对象和数据对象(git 对象)的形式存储,其中树对象对应了 UNIX 中的目录项,数据对象(git 对象)则大致上对应文件内容。一个树对象包含了一条或多条记录(每条记录含有一个指向 git 对象或者子树对象的 SHA-1 指针,以及相应的模式、类型、文件名信息)。一个树对象也可以包含另一个树对象。
- 利用
update-index
命令为test.txt文件的首个版本——创建一个暂存区。并通过write-tree
命令生成树对像。
命令:
git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt
git write-tree
文件模式为 100644,表明这是一个普通文件
100755,表示一个可执行文件
120000,表示一个符号链接。
--add 选项:因为此前该文件并不在暂存区中 首次需要 --add
--cacheinfo 选项:因为将要添加的文件位于 git 数据库中,而不是位于当前目录下 - 查看暂存区
git ls-files -s
树对象
- 查看树对象
git cat-file -p master^{tree}(或者是树对象的 hash)
master^{tree} 语法表示 master 分支上最新的提交所指向的树对象。 - 解析树对象
git 根据某一时刻暂存区(即 index 区域)所表示的状态创建并记录一个对应的树对象,如此重复便可依次记录(某个时间段内)一系列的树对象。其实树对象是对暂存区内操作的抽象,这颗树对象相对于就是快照。当我们的工作区有任何更改同步到暂存区时。便会调用write-tree
命令向暂存区内容写入一个树对象。它会根据当前暂存区状态自动创建一个新的树对象。即每一次同步都产生一颗树对象。且该命令会返回一个 hash 指向树对象。
在 Git 中每一个文件(数据)都对应一个 hash(类型 blob)
每一个树对象都对应一个 hash(类型 tree)
总结
我们可以认为树对象就是我们项目的快照
提交对象
我们可以通过调用 commit-tree
命令创建一个提交对象,为此需要指定一个树对象的 SHA-1 值,以及该提交的父提交对象(如果有的话 第一次将暂存区做快照就没有父对象)
- 创建提交对象
echo 'first commit' | git commit-tree d8329f
返回:fdf4fc3344e67ab068f836878b6c4951e3b15f3d - 查看提交对象
git cat-file -p fdf4fc3
- 提交对象的格式
它先指定一个顶层树对象,代表当前项目快照;然后是作者/提交者信息(依据你的 user.name 和 user.email 配置来设定,外加一个时间戳);留空一行,最后是提交注释
注意git commit-tree
不但生成提交对象 而且会将对应的快照(树对象)提交到本地库中
高层命令
初始化新仓库
命令:git init
检查当前文件状态
命令:git status
作用:确定文件当前处于什么状态
基本操作
- 跟踪新文件(暂存)
命令:git add 文件名
作用:跟踪一个新文件
在git add
后面可以指明要跟踪的文件或目录路径。如果是目录的话,就说明要递归跟踪该目录下的所有文件。
git hash-object -w 文件名(修改了多少个工作目录中的文件 此命令就要被执行多少次)
git update-index ...
- 暂存已修改文件
现在 README 文件都已暂存,下次提交时就会一并记录到仓库。假设此时,你想要在 README 里再加条注释,重新编辑存盘后,准备好提交。不过且慢,再运行git status
看看:
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README
README 文件出现了两次!一次算已修改,一次算已暂存, Git 暂存了运行 git add 命令时的版本,如果现在提交,那么提交的是添加注释前的版本,而非当前工作目录中的版本。所以,运行了 git add 之后又作了修订的文件,需要重新运行 git add 把最新版本重新暂存起来
-
查看已暂存和未暂存的更新
- 当前做的哪些更新还没有暂存?
命令:git diff
(不加参数直接输入 git diff) - 有哪些更新已经暂存起来准备好了下次提交?
命令:git diff –-cached
或者git diff –-staged
(1.6.1 以上)
- 当前做的哪些更新还没有暂存?
-
提交更新
命令:git commit
注意:这种方式会启动文本编辑器以便输入本次提交的说明默认的提交消息包含最后一次运行 git status 的输出,放在注释行里,另外开头还有一空行,供你输入提交说明。你完全可以去掉这些注释行,不过留着也没关系,多少能帮你回想起这次更新的内容有哪些。另外也可以用 -m 参数后跟提交说明的方式,在一行命令中提交更新,命令:git commit –m "message xx"
提交时记录的是放在暂存区域的快照,任何还未暂存的仍然保持已修改状态,可以在下次提交时纳入版本管理。每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较
git write-tree
git commit-tree
-
跳过使用暂存区域
git会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤
命令:git commit -a
-
移除文件(已跟踪到未跟踪)
要从 git 中移除某个文件,就必须要从已跟踪文件清单中注册删除(确切地说,是在暂存区域注册删除),然后提交。可以用git rm
命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。 -
文件改名
git mv file.from file.to
-
查看历史记录
在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。完成这个任务最简单而又有效的工具是git log
命令
git log
git log --pretty=oneline
git log --oneline
分支
创建分支
命令:git branch
作用:
为你创建了一个可以移动的新的指针。比如,创建一个 testing 分支:git branch testing
。这会在当前所在的提交对象上创建一个指针
git branch name
创建一个新分支,并不会自动切换到新分支中去
注意:
git branch
不只是可以创建与删除分支。如果不加任何参数运行它,会得到当前所有分支的一个列表
git branch -a
查看本地和远程仓库的所有分支
git branch -r
查看远程仓库的分支
git branch -d name
删除分支
git branch -v
可以查看每一个分支的最后一次提交
git branch name commitHash
新建一个分支并且使分支指向对应的提交对象
git branch –merged
查看哪些分支已经合并到当前分支,在这个列表中分支名字前没有*号的分支通常可以使用 git branch -d
删除掉
git branch --no-merged
查看所有包含未合并工作的分支,尝试使用 git branch -d
命令删除在这个列表中的分支时会失败。如果真的想要删除分支并丢掉那些工作,可以使用 -D 选项强制删除它。
查看当前分支所指对象
命令:git log --oneline --decorate
(提供这一功能的参数是 --decorate)
切换分支
git checkout testing
分支切换会改变你工作目录中的文件,在切换分支时,一定要注意你工作目录里的文件会被改变。如果是切换到一个较旧的分支,你的工作目录会恢复到该分支最后一次提交时的样子。如果 Git 不能干净利落地完成这个任务,它将禁止切换分支,每次在切换分支前提交一下当前分支
创建分支并切换
git checkout -b test
查看项目分叉历史
git log --oneline --decorate --graph --all
分支合并
命令:git merge 分支名
分支模式
分支本质
git 的分支,其实本质上仅仅是指向提交对象的可变指针
分支原理
- .git/refs 目录
这个目录中保存了分支及其对应的提交对象 - HEAD 引用
HEAD文件是一个符号引用(symbolic reference),指向目前所在的分支。 所谓符号引用,意味着它并不像普通引用那样包含一个 SHA-1 值。它是一个指向其他引用的指针
配别名
git 并不会在你输入部分命令时自动推断出你想要的命令。如果不想每次都输入完整的 git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名。
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git存储
git stash 命令会将未完成的修改保存到一个栈上,而你可以在任何时候重新应用这些改动(git stash apply)
git stash list 查看存储
git stash apply stash@{2} 如果不指定一个储藏,git认为指定的是最近的储藏
git stash pop 来应用储藏然后立即从栈上扔掉它
git stash drop 加上将要移除的储藏的名字来移除它
撤销
- git commit –amend
命令:git commit --amend
作用:
这个命令会将暂存区中的文件提交。如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令),那么快照会保持不变,而你所修改的只是提交信息
如果你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作
git commit -m 'initial commit'
git add forgotten_file
git commit –amend
最终你只会有一个提交 第二次提交将代替第一次提交的结果
- git restore --stage
命令:git restore --stage 文件名
/git reset HEAD filename
作用:将文件从暂存区中撤回到工作目录 - git restore
命令:git restore 文件名
/git checkout --filename
作用:将在工作目录中对文件的修改撤销
reset三部曲
git reset --soft HEAD~
reset 移动 HEAD 指向的分支(本质上是撤销了上一次 git commit 命令)- git reset [–mixed] HEAD~
它依然会撤销上次提交,但还会取消暂存所有的东西 - git reset --hard HEAD~
撤销了最后的提交 git add 和 git commit 命令以及工作目录中的所有工作
数据恢复
- 显示足够多的信息
git reflog
- 恢复
git branch recover-branch ab1afef
打tag
可以给历史中的某一个提交打上标签以示重要。比较有代表性的是人们会使用这个功能来标记发布结点(v1.0等等)。
- 列出标签
git tag
git tag -l 'v1.8.5*'
- 创建标签
git tag v1.4
git tag v1.4 commitHash
git tag -a v1.4
git tag -a v1.4 commitHash
git tag -a v1.4 commitHash -m 'my version 1.4'
- 查看特定标签
git show 可以显示任意类型的对象(git 对象 树对象 提交对象 tag对象)
git show tagname
- 远程标签
默认情况下,git push命令并不会传送标签到远程仓库服务器上。在创建完标签后你必须显式地推送标签到共享服务器上。你可以运行
git push origin tagname
如果想要一次性推送很多标签,也可以使用带有--tags选项的git push命令。这将会把所有不在远程仓库服务器上的标签全部传送到那里。
git push origin --tags
- 删除标签
要删除掉你本地仓库上的标签,可以使用命令
git tag -d tagname
应该注意的是上述命令并不会从任何远程仓库中移除这个标签,你必须使用下面命令来更新你的远程仓库
git push <remote> :refs/tags/tagname
- 检出标签
如果你想查看某个标签所指向的文件版本,可以使用
git checkout tagname
虽然说这会使你的仓库处于“分离头指针(detacthed HEAD)”状态。在“分离头指针”状态下,如果你做了某些更改然后提交它们,标签不会发生变化,但你的新提交将不属于任何分支,并且将无法访问,除非访问确切的提交哈希。因此,如果你需要进行更改通常需要创建一个新分支
git checkout -b version2
Eslint
js 代码的检查工具
下载: npm i eslint -D
使用:
- 生成配置文件
npx eslint --init
- 检查 js 文件
npx eslint 目录名
- 命中的规则:
字符串必须使用单引号
语句结尾不能有分号
文件的最后必须要有换行
husky: 哈士奇, 为 Git 仓库设置钩子程序
在仓库初始化完毕之后 再去安装哈士奇
在 package.json 文件写配置
"husky": {
"hooks": {
"pre-commit": "npm run lint"
//在git commit之前一定要通过npm run lint的检查
// 只有npm run lint不报错时 commit才能真正的运行
}
}
.gitignore
所有空行或者以注释符号#开头的行都会被 git 忽略。
可以使用标准的 glob 模式匹配。
- *代表匹配任意个字符
- ?代表匹配任意一个字符
- **代表匹配多级目录
- 匹配模式前跟反斜杠(/) 这个斜杠代表项目根目录
- 匹配模式最后跟反斜杠(/)说明要忽略的是目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
远程协作基本流程
项目经理创建远程仓库
项目经理创建本地库
项目经理为远程仓库配置别名&用户信息
添加一个新的远程 git 仓库,同时指定一个你可以轻松引用的简写
git remote add <shortname> <url>
显示远程仓库使用的 git 别名与其对应的URL
git remote –vv
查看某一个远程仓库的更多信息
git remote show [short/remote-name]
重命名
git remote rename pb paul
如果因为一些原因想要移除一个远程仓库 -你已经从服务器上搬走了或不再想使用某一个特定的镜像了,又或者某一个贡献者不再贡献了
git remote rm [short/remote-name]
项目经理推送本地项目到远程仓库
初始化一个本地仓库然后:
git push [short/remote-name] [branch-name]
将本地项目的 master 分支推送到 origin(别名)服务器
成员克隆远程仓库到本地
git clone url
(克隆时不需要 git init)默认克隆时为远程仓库起的别名为 origin
项目经理邀请成员加入团队
成员推送提交到远程仓库
git push [remote-name] [branch-name]
项目经理更新成员提交的内容
git fetch [remote-name]
这个命令会访问远程仓库,从中拉取所有你还没有的数据。执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看,必须注意 git fetch 命令会将数据拉取到你的本地仓库,它并不会自动合并或修改你当前的工作。当准备好时你必须手动将其合并入你的工作。
远程跟踪分支
推送其他分支(共享分支)
- 一方:
git push origin serverfix
git push origin serverfix(本地):awesomebranch(远程)
- 其他协作者
git fetch origin
git merge origin/serverfix
将这些工作合并到当前所在的分支。
如果想要在自己的 serverfix 分支上工作,可以将其建立在远程跟踪分支之上:
git checkout -b serverfix origin/serverfix
跟踪分支
从一个远程跟踪分支(origin/master)检出一个本地分支会自动创建一个叫做“跟踪分支”(有时候也叫做“上游分支” master)。只有主分支并且克隆时才会自动建跟踪分支. 跟踪分支是与远程分支有直接关系的本地分支。如果在一个跟踪分支上输入 git pull,git 能自动地识别去哪个服务器上抓取、合并到哪个分支。
如果你愿意的话可以设置其他的跟踪分支,或者不跟踪 master 分支。
git checkout -b [branch] [remotename]/[branch]
git checkout -b serverfix origin/serverfix
这是一个十分常用的操作所以 git 提供了 --track 快捷方式
git checkout --track origin/serverfix
如果想要将本地分支与远程分支设置为不同名字
git checkout -b sf origin/serverfix
设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的跟踪分支,你可以在任意时间使用 -u 选项运行 git branch 来显式地设置
git branch -u origin/serverfix(--set-upstream-to)
查看设置的所有跟踪分支
git branch -vv
删除远程分支
git push origin --delete serverfix
//删除远程分支
git remote prune origin --dry-run
//列出仍在远程跟踪但是远程已被删除的无用分支
git remote prune origin
//清除上面命令列出来的远程跟踪
pull request
- 从 master 分支中创建一个新分支(自己 fork 的项目)
- 提交一些修改来改进项目(自己 fork 的项目)
- 将这个分支推送到 gitHub 上(自己 fork 的项目)
- 创建一个合并请求
- 讨论,根据实际情况继续修改
- 项目的拥有者合并或关闭你的合并请求
注意点:
每次在发起新的 Pull Request 时要去拉取最新的源仓库的代码,而不是自己 fork 的那个仓库。
git remote add <shortname 源仓库> <url 源仓库>
git fetch 远程仓库名字
git merge 对应的远程跟踪分支
SSH
ssh-keygen –t rsa –C 你的邮箱
:生成公私钥
.ssh 文件位置:C:\Users\Administrator.ssh
ssh -T git@github.com
:测试公私钥是否已经配对
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具