概念
- 版本控制系统(VCS): 是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术
- 分布式版本控制: 与集中式版本控制系统(如 SVN)不同,Git 是分布式的,这意味着每个开发者的本地仓库都包含了项目的完整历史。这样即使无法访问远程仓库,开发者也可以进行提交等操作。
- 仓库(Repository): 仓库是 Git 用来存储项目及其历史记录的地方。一个 Git 仓库通常包括工作区、暂存区和本地仓库。
- 分支(Branch): 分支是项目开发的不同路线。开发者可以在不同的分支上并行开发,最终通过分支合并将不同开发路线的成果合并在一起
- 工作区:在本地计算机上的项目的目录,工作区包含了当前项目的所有文件和子目录
- 暂存区/索引(stage/index):一般存放在 .git/index 中,是一个临时存储区域,它包含了即将被提交到版本库中的文件快照,在提交之前,你可以选择性地将工作区中的修改添加到暂存区
- 版本库/本地仓库: 工作区有个隐藏目录.git, 这个不算工作区, 而是 Git 的本地版本库, 版本库包含项目所有版本历史记录, 每次提交都会在版本库中创建一个新快照, 这些快照是不可变的,确保了项目的完整历史记录
- 远程仓库(Remote Repository): 远程仓库是托管在服务器上的 Git 仓库,通常用于团队协作。常见的远程仓库托管服务包括 GitHub、GitLab、Bitbucket 等。
配置
git config 配置项 配置的值
: 设置配置
git config 配置项
: 查看指定配置项的信息
git config --list
: 查看所有配置信息
git config -e
: 编辑 git 配置文件
省略
本地配置, 只对当前所在本地仓库有效(配置存在.git/config
)
--global
全局配置, 所有仓库有效(配置存在~/.gitconfig
)
--system
系统配置, 对所有用户生效(配置存在/etc/gitconfig
或git下载目录下的gitconfig文件
)- 配置项
user.name "用户名" | user.email 用户邮件地址
配置这两项是为了在每次提交代码时记录提交者的信息, 而非登录认证
core.editor "文本编辑器"
设置文本编辑器, 一般默认为 Vi 或 Vim
merge.tool 差异分析工具
为解决合并冲突时使用哪种差异分析工具
基础操作
git init
: 在当前目录下 初始化一个新Git仓库 (执行完成后, Git仓库会生成一个.git目录)
git init <本地目录>
: 将指定目录作为Git仓库git add <file>
: 将文件添加到暂存区(跟踪)
git add .
可将工作区中的所有文件添加到暂存区
.gitignore
在其内所写文件都将在 添加到暂存区时被忽略(该文件需手动创建)- 可以把它放在版本库的任何文件夹中(一般放在跟目录), 你甚至可以有多个
.gitignore
文件 - 语法: 忽略某特定位置文件
/路径
, 忽略工作区下所有同名文件文件名
,
忽略某特定位置目录及其中所有文件/目录路径/
, 忽略工作区下所有同名目录及其中所有文件目录名/
- 可以把它放在版本库的任何文件夹中(一般放在跟目录), 你甚至可以有多个
git status
: 查看文件状态
要提交的变更(Change to be committed): 已经用git add
的变更, 可用commit提交
未暂存的变更: 未被git add
暂存的变更
已修改(Modified): 已被 Git 跟踪的文件发生了更改,但这些更改还没有被提交到暂存区中
已删除(Deleted):文件在Git仓库中被删除
未跟踪(Untracked):新创建的文件,未被 Git 记录 (即未被跟踪)git commit -m "Commit message"
: 将暂存区中的文件的修改提交到版本库
-a 先自动将工作区文件的修改添加到暂存区, 再提交到版本库) (对未跟踪文件没用)git rm <file>
: 将某文件从工作目录中删除(删除后会自动将该 更改 加入暂存区)
--cached
: 将文件删除的更改 加入暂存区, 不删除工作目录中的该文件 (文件会因此处于未跟踪状态)
-f
: 强制删除 (若删除之前已在暂存区, 则需要使用强制删除
以同时删除该文件在 暂存区 的更改)
-r
: 递归删除git mv <file> <new-file>
移动或重命名一个文件、目录或软连接(同时将该 更改 加入暂存区)
-f 强制执行 (如果新文件名已经存在,但还是要重命名, 就需要)
分支
- 简介: 每一个分支都有一个指针, 而在git中有一个HEAD头指针, 它代表了我们当前所在的位置, 切换分支即为将HEAD指针指向 要切换的分支的指针上, 而每次提交,分支都会向前移动一步
git branch <branchname>
创建分支(不切换到新建分支)git branch
查看所有分支
无 查看本地分支
-r 查看远程分支
-a 查看所有本地和远程分支
-d <branchname>
删除本地分支
-D <branchname>
强制删除未合并的分支git checkout <branchname>
切换到指定分支
若切换分支时存在 未提交的更改, git会阻止切换操作 或 更改消失
-b 若指定分支不存在, 则自动创建(且创建后自动切换到该分支)git switch <branchname>
专门用于切换分支,相比git checkout
更加简洁和直观
-c 创建并切换到新分支git merge <branchname>
将其他分支合并到当前分支
fast-forward
合并策略: 如果一个分支的提交历史是另一个分支的子集,那么Git会简单地将当前分支指向另一个分支的最新提交,这样就完成了合并操作
recursive
合并策略: Git会创建一个新的提交来表示合并结果,这个提交会包含两个分支的所有变更内容
--no-ff
:禁用fast-forward合并策略,强制Git创建一个新的合并提交
--squash
:将合并结果压缩为一个提交,并且不会保留源分支的提交历史
冲突
- 产生的条件
同一文件的同一部分被不同分支修改
一个分支删除了文件,而另一个分支修改了该文件
一个分支重命名了文件,而另一个分支修改了原文件名的文件, 或进行了不同的重命名
两个分支都添加了同名但内容不同的文件
文件权限被不同的修改 - 解决冲突
发生冲突时, 通常会在冲突的文件中插入冲突标记
需要手动编辑冲突文件, 决定保留哪个版本的修改
解决完冲突后 使用git add <conflict_file>
与git commit
以提交结果
查看差异
git diff [file]
: 比较文件在工作区和暂存区的差异 (未指定文件则为所有文件)
--cached 或 --staged 显时暂存区和上一次提交的差异git diff [first-branch]...[second-branch]
: 显示两个分支之间的差异git diff <commit>
: 比较工作区和指定提交的差异git diff <commit1> <commit2>
: 比较两个提交之间的差异diff --git a/<文件名> b/<文件名> index <旧版本哈希>..<新版本哈希> <文件权限> --- a/<文件名> +++ b/<文件名> @@ <变化的行范围> @@
- <旧内容>
- <新内容>
恢复与回退
git checkout <commit> -- <filename>
:恢复工作目录中的文件到某个提交git checkout <commit>
: 切换到特定提交git reset <commit> [file]
:重置当前分支到指定提交
--soft:只重置 HEAD 到指定的提交,暂存区和工作目录保持不变
--mixed(默认):重置 HEAD 到指定的提交,暂存区重置,但工作目录保持不变
--hard:重置 HEAD 到指定的提交,暂存区和工作目录都重置git revert
:创建一个新的提交以撤销指定提交,不改变提交历史git reflog
:查看历史操作记录,找回丢失的提交
该命令记录了所有 HEAD 的移动。即使提交被删除或重置,也可以通过 reflog 找回
日志
git log [选项] [分支名/提交哈希]
查看仓库的历史提交记录
(包括提交的哈希值、作者、提交日期和提交消息)
-p
:显示提交的具体提交内容 (显示的内容以git diff格式呈现)
--oneline
:以简洁的一行格式显示提交信息(可以用来查看哈希值)
--graph
:以图形化方式显示分支和合并历史
--decorate
:显示分支和标签指向的提交
--author=<作者>
:只显示特定作者的提交
--since=<时间>
:只显示指定时间之后的提交
--until=<时间>
:只显示指定时间之前的提交
--grep=<模式>
:只显示包含指定模式的提交消息
--no-merges
:不显示合并提交
--stat
:显示简略统计信息,包括修改的文件和行数
--abbrev-commit
:使用短提交哈希值
--pretty=<格式>
:使用自定义的提交信息显示格式
-n <number>
: 限制显示的提交数git blame [选项] <文件路径>
逐行显示指定文件的每一行代码是由谁在什么时候引入或修改的
-L <起始行号>,<结束行号>
:只显示指定行号范围内的代码注释
-C
:对于重命名或拷贝的代码行,也进行代码行溯源
-M
:对于移动的代码行,也进行代码行溯源
-C -C
或-M -M
:对于较多改动的代码行,进行更进一步的溯源
--show-stats
:显示包含每个作者的行数统计信息
标签
- 概念: 用于给仓库中的特定提交点加上标记,通常用于发布版本(如 v1.0, v2.0), 标签不能重复
git tag
查看所有标签git tag <tagname>
给最新的一次提交打上标签
git tag <tagname> 提交哈希
给指定提交打上标签
-a
使你可以给创建的标签写注解 (同时也会记录标签创建的时间 与 创建者)
-m "<message>"
与-a
一起使用, message即为注解内容
-d
本地删除轻量标签 (只删除标签)git show <tagname>
显示标签信息- 标签特点: 默认情况下, git push不会推送标签, 需要显式地推送标签
git push origin <tagname>
推送标签到远程仓库git push origin --tags
推送所有标签git push origin --delete <tagname>
远程删除轻量标签
特殊
<commit>
可以是 提交哈希, 也可以是特殊表示方法,
HEAD表示最新一次提交, HEAD^代表倒数第二次提交, HEAD^^代表倒数第三次提交, 以此类推
远程仓库: [[Github]]
- 简介: github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开
- 连接github:
ssh-keygen -t rsa -C "git账户的邮箱@example.com"
所有选项一路回车(记住key文件保存的位置, 一般在~/
下生成 .ssh 文件夹中)- 将id_rsa.pub文件内容复制
- 打开github, 进入 Account => Settings => SSH and GPG keys
- 点击 New SSH key 按钮, 将之前复制的内容复制到Key文本框中, 点击提交
- 使用
ssh -T git@github.com
命令来确定是否连接成功
Hi xxxxxx! You've successfully authenticated, but GitHub does not provide shell access
- 克隆远程仓库到本地:
git clone <repository> [本地目录] [指定仓库目录的名称]
- 添加远程仓库:
git remote add [远程主机名] [url]
- 查看远程仓库:
git remote [-v]
查看当前本地仓库有哪些远程仓库
加上 -v 参数可以看到每个别名的实际链接地址 - 删除远程仓库:
git remote rm <远程主机名>
- 获取远程仓库内容:
git fetch [shortname]
, fetch后将其合并git merge [shortname]/[branch]
- 获取远程仓库内容(简化):
git pull [<远程主机名>] [<远程分支名>[:<本地分支名>]]
会自动合并
若远程主机名
远程分支名
没写, 则获取全部
本地分支名
可以将获取的分支与本地分支合并, 若没有 同名本地分支, 则会将远程分支改名 - 推送内容到远程仓库:
git push [-u] <远程主机名> <本地分支名>[:<远程分支名>]
[远程仓库名]
通常是origin
,是默认的远程仓库名
[分支名]
是你要合并的远程分支,比如main
或master
- 删除远程分支:
git push origin --delete <branchname>