Git
Git
初始化仓库
- Git仓库实际上就是一个目录,需要对该目录进行Git的初始化将该目录交由Git管理
- 初始化完成后,该仓库所有的文件都可以被Git进行管理,其所有修改删除等操作都会被跟踪到,也可以随时恢复到以前的版本
初始化本地仓库
-
如果没有项目目录,可以创建一个新目录
-
在项目目录中运行以下命令来初始化 Git 仓库:
-
git init -
这会在当前目录下创建一个隐藏的
.git文件夹,用于存储 Git 的所有元数据和对象数据库。- 该隐藏的
.git文件夹删除后该目录就变为一个普通的目录
- 该隐藏的
-
初始化后,当前目录就成为了一个 Git 仓库。
-
-
如果已经有一个项目目录,可以直接在该目录中初始化 Git 仓库
配置邮箱和用户名
-
在 Git 仓库初始化后,配置邮箱和用户名是必须的,但密码不是必须的。
-
邮箱和用户名用于标识提交的作者信息,而密码通常用于远程仓库的身份验证(如 GitHub、GitLab 等)。
-
Git 要求每次提交(commit)都记录作者信息,包括:
- 用户名:标识提交的作者。
- 邮箱:标识作者的邮箱地址。
- 这些信息会包含在每次提交的元数据中,用于追踪代码的修改历史。
-
全局配置(对所有仓库生效)
-
git config --global user.name "Your Name" git config --global user.email "your.email@example.com" -
不加
--global的话就为局部配置(仅对当前仓库生效)
-
克隆远程仓库
-
如果已经有一个远程仓库,可以直接克隆到本地:
-
git clone <远程仓库地址> -
这会在当前目录下创建一个与远程仓库同名的文件夹,并自动初始化 Git 仓库。
-
Git的工作区域
- Git 的工作区域是 Git 版本控制系统的核心概念之一,理解这些区域对于高效使用 Git 至关重要。Git 的工作区域主要包括以下四个部分:
- 工作区(Working Directory)
- 暂存区(Staging Area)
- 本地仓库(Local Repository)
- 远程仓库(Remote Repository)
工作区(Working Directory)
-
工作区是开发者直接编辑文件的目录。它是项目的根目录,包含所有正在开发的文件和文件夹。
-
特点
- 工作区中的文件可能是已跟踪的(tracked)或未跟踪的(untracked)。
- 已跟踪的文件:已经被 Git 管理的文件(即已经添加到仓库或暂存区)。
- 未跟踪的文件:新创建的文件或未被 Git 管理的文件。
- 工作区中的文件可能处于以下状态之一:
- 未修改(Unmodified):文件内容与本地仓库一致。
- 已修改(Modified):文件内容被修改,但尚未添加到暂存区。
- 已暂存(Staged):文件已被添加到暂存区,准备提交。
- 工作区中的文件可能是已跟踪的(tracked)或未跟踪的(untracked)。
-
命令
-
查看工作区状态:
-
git status
-
-
丢弃工作区的更改(恢复到上次提交的状态):
-
git checkout -- <文件名>
-
-
暂存区(Staging Area)
-
暂存区是一个临时区域,用于保存即将提交到本地仓库的更改。开发者可以选择性地将工作区中的文件添加到暂存区。
-
特点
- 暂存区是 Git 的一个独特设计,允许开发者分阶段提交更改。
- 只有添加到暂存区的文件才会被包含在下一次提交中。
-
命令
-
使用
git ls-files命令可以列出暂存区的所有文件。-
git ls-files
-
-
将文件添加到暂存区:
-
git add <文件名>- 支持通配符比如
git add *.txt表示将所有txt文件添加到暂存区
- 支持通配符比如
-
-
添加所有更改的文件:
-
git add ..代表当前目录
-
-
从暂存区移除文件:
-
git reset HEAD <文件名>
-
-
本地仓库(Local Repository)
-
本地仓库是存储项目完整历史记录的地方,包括所有提交、分支和标签。它位于项目目录下的
.git文件夹中。 -
特点
- 本地仓库是分布式的,每个开发者都拥有完整的仓库副本。
- 提交到本地仓库的更改不会自动同步到远程仓库。
-
命令
-
提交暂存区的更改到本地仓库:
-
git commit -m "提交信息"
-
-
**
git commit -a**:自动暂存所有已跟踪文件的修改并提交- 自动暂存所有已跟踪文件的修改:包括修改、删除的文件,但不包括未跟踪的新文件。
- 直接提交:将暂存的修改提交到仓库。
-
查看提交历史:
-
git log
-
-
撤销上一次提交(保留更改):
-
git reset --soft HEAD^-
撤销上一次提交,但保留更改(包括工作区和暂存区的更改)。
-
将
HEAD指针移动到上一次提交(HEAD^),同时将撤销的提交的更改放回暂存区。 -
其中HEAD^可以换成目标提交的 ID(使用
git log查看)。-
git reset --soft <commit-id>
-
-
-
-
默认模式(保存工作区,丢弃暂存区)
-
git reset --mixed HEAD^ 等同于 git reset HEAD^- 重置暂存区,但保留工作区的更改(即撤销的提交的更改会放回工作区)。
-
-
撤销上一次提交(丢弃更改):
-
git reset --hard HEAD^-
撤销上一次提交,并丢弃所有更改(包括工作区和暂存区的更改)。
-
将
HEAD指针移动到上一次提交(HEAD^),同时重置工作区和暂存区到上一次提交的状态。 -
如果执行了该命令还是可以回退版本的,因为git中的一切操作都是可以回退的
-
git reflog记录了所有HEAD指针的移动历史,即使你已经重置了HEAD,也可以通过它找回之前的提交。-
查看
reflog:其中包含<commit-id> -
git reflog -
使用
git reset --hard恢复到该提交: -
git reset --hard <commit-id>
-
-
-
-
远程仓库(Remote Repository)
-
远程仓库是存储在远程服务器(如 GitHub、GitLab、Bitbucket)上的仓库,用于团队协作和代码备份。
-
特点
- 远程仓库是集中式的,团队成员可以通过它共享代码。
- 开发者需要将本地仓库的更改推送到远程仓库,或从远程仓库拉取最新更改。
-
命令
-
克隆远程仓库到本地:
-
git clone <远程仓库地址>
-
-
查看远程仓库:
-
git remote -v
-
-
推送本地仓库的更改到远程仓库:
-
git push origin <分支名>
-
-
拉取远程仓库的更改到本地:
-
git pull origin <分支名>
-
-
HEAD
- 定义
HEAD是一个非常重要的概念,它是指向当前工作目录所对应的提交(commit)的引用。HEAD是一个指针,指向当前所在的提交(commit)。- 它通常指向当前分支的最新提交,但也可以指向某个具体的提交(在分离头指针状态下)。
HEAD是 Git 中用于跟踪当前工作状态的引用。
- 作用
- 指向当前分支,在大多数情况下,
HEAD指向当前分支的最新提交。例如:- 如果你在
main分支上工作,HEAD会指向main分支的最新提交。 - 如果你切换到
feature分支,HEAD会指向feature分支的最新提交。
- 如果你在
- 分离头指针(Detached HEAD)
- 当
HEAD直接指向某个具体的提交(而不是分支)时,称为分离头指针状态。 - 这种状态通常出现在以下情况:
- 直接检出某个提交(如
git checkout <commit-id>)。 - 检出标签(如
git checkout v1.0)。
- 直接检出某个提交(如
- 在分离头指针状态下,新的提交不会属于任何分支,可能会导致提交丢失(如果没有创建分支)。
- 当
- 指向当前分支,在大多数情况下,
HEAD的特殊符号- Git 提供了一些特殊符号来表示
HEAD的相对位置:HEAD^或HEAD~1,表示HEAD的上一次提交(父提交)。HEAD^^或HEAD~2,表示HEAD的上两次提交。以此类推。
- Git 提供了一些特殊符号来表示
.gitignore文件
-
.gitignore文件用于告诉 Git 哪些文件或目录应该被忽略,即不被 Git 跟踪或提交到仓库。 -
.gitignore文件的作用- 忽略未跟踪的文件:防止 Git 跟踪某些文件或目录。
- 避免提交不必要的文件:防止将临时文件、编译产物、敏感信息等提交到仓库。
-
以下是一些常见的应该被忽略的文件类型:
- 系统或编辑器生成的文件
- 编译产物或构建输出
- 编译生成的文件:如
*.class(Java)、*.o(C/C++)、*.pyc(Python)。 - 构建输出目录:如
build/、dist/、out/。
- 编译生成的文件:如
- 依赖目录
- 包管理器的依赖目录:如
node_modules/(Node.js)、vendor/(PHP Composer)、target/(Maven)。
- 包管理器的依赖目录:如
- 日志文件、测试输出和其他临时文件
-
.gitignore文件的放置位置- 项目根目录:通常将
.gitignore文件放在项目根目录下。 - 子目录:可以在子目录中放置额外的
.gitignore文件,规则仅对该目录生效。
- 项目根目录:通常将
-
.gitignore文件的格式- 每行一个规则:每个规则指定一个文件或目录。
- 支持通配符:
*:匹配任意字符(除了/)。**:匹配任意目录。?:匹配单个字符。[]:匹配括号内的任意字符。
- 以
/开头:匹配项目根目录下的文件或目录。- 根目录为
.git文件所在目录
- 根目录为
- 以
/结尾:匹配目录。 - 以
!开头:排除某个文件或目录(即使被其他规则忽略)。
-
.gitignore文件示例-
# 忽略所有 .log 文件 *.log # 忽略 build/ 目录下的所有文件 build/ # 忽略根目录下的 .env 文件 /.env # 忽略所有 .tmp 文件,但不忽略 important.tmp *.tmp !important.tmp # 忽略 doc/ 目录下的 .txt 文件,但不忽略 doc/notes.txt doc/*.txt !doc/notes.txt # 忽略 node_modules/ 目录 node_modules/ # 忽略 .DS_Store 文件(macOS 系统文件) .DS_Store
-
-
注意事项
.gitignore对已跟踪的文件无效:如果文件已经被 Git 跟踪,.gitignore不会生效。需要先使用git rm --cached移除跟踪。- 规则顺序:规则的顺序很重要,后面的规则可能会覆盖前面的规则。
Git常用命令
git diff
-
工作区中已修改但未暂存的文件与暂存区中的文件的差异(工作区与暂存区)
-
git diff
-
-
查看暂存区中的文件与最新提交(
HEAD)中的文件的差异(暂存区与最新提交)-
git diff --cached 或者 git diff --staged
-
-
查看工作区与暂存区中的文件与最新提交(
HEAD)中的文件的差异(工作区和暂存区与最新提交)-
git diff HEAD
-
-
查看两个提交之间的差异:
-
git diff <commit-id> <commit-id>
-
-
查看两个分支之间的差异:
-
git diff <分支1> <分支2>
-
-
查看某个文件在不同版本之间的差异:
-
git diff <commit-id> <commit-id> -- <文件名> git diff HEAD^ HEAD -- file.txt
-
-
查看差异的统计信息(如更改的文件数量和行数):
-
git diff --stat
-
git diff 的输出展示了文件之间的差异,格式为统一的 diff 格式。
-
git diff输出通常包括以下几个部分:- 文件头:描述被比较的文件。
- 块头:描述差异的具体位置。
- 差异内容:显示具体的行变化。
-
文件头格式如下:
-
diff --git a/file1.txt b/file1.txt index 1234567..89abcde 100644 -
diff --git a/file1.txt b/file1.txt:比较的是a/file1.txt(旧文件)和b/file1.txt(新文件)。 -
index 1234567..89abcde 100644:文件的索引信息,1234567是旧文件的哈希,89abcde是新文件的哈希,100644是文件模式。
-
-
块头格式如下
-
@@ -1,5 +1,6 @@ -
@@ -1,5 +1,6 @@:表示旧文件从第 1 行开始的 5 行,与新文件从第 1 行开始的 6 行有差异。
-
-
差异内容
- 差异内容用符号标记变化:
-:删除的行(旧文件中的行)。+:新增的行(新文件中的行)。- 没有符号:未更改的行。
- 差异内容用符号标记变化:
-
完整示例
-
diff --git a/file1.txt b/file1.txt index 1234567..89abcde 100644 --- a/file1.txt +++ b/file1.txt @@ -1,5 +1,6 @@ Hello, world! -This is the old line. +This is the new line. +This is an additional line. The rest of the file remains unchanged. Another line. -
文件头:
- 比较
a/file1.txt和b/file1.txt。 - 旧文件哈希为
1234567,新文件哈希为89abcde。
- 比较
-
块头:
- 旧文件从第 1 行开始的 5 行与新文件从第 1 行开始的 6 行有差异。
-
差异内容:
Hello, world!:未更改。-This is the old line.:删除的行。+This is the new line.:新增的行。+This is an additional line.:新增的行。The rest of the file和remains unchanged.:未更改。Another line.:未更改。
-
git rm
-
使用
rm命令只会从工作区删除文件,不会将该操作添加到暂存区 -
使用
git rm命令可以从工作区和暂存区同时删除文件-
git rm filename -
效果:
- 从工作区删除文件。
- 将删除操作添加到暂存区。
-
-
提交删除操作
-
删除文件后,需要提交更改以更新本地仓库:
-
git commit -m "Delete filename"
-
-
如果只想从仓库中取消跟踪文件但保留在工作区,可以使用
git rm --cached:-
git rm --cached filename -
效果:
- 从暂存区和仓库中移除文件:文件不再被 Git 跟踪。
- 不影响本地仓库的历史记录:文件仍然存在于之前的提交中,但未来的提交将不再包含该文件
- 保留文件在工作区:文件仍然保留在你的本地文件系统中,不会被删除。
- 执行
git rm --cached后,必须提交更改才能真正从未来的提交中移除文件。
-
-
如果需要删除目录及其内容,使用
-r选项:-
git rm -r directoryname -
提交删除操作即可
-
分支
概念
- Git 分支是 Git 的核心功能之一,它允许你在同一个仓库中并行开发多个功能或版本
- 分支:分支是代码的独立开发线,允许你在不影响主线(如
main或master)的情况下进行开发。 - 默认分支:通常为
main或master,是项目的主线。 - 特性分支:用于开发新功能或修复 bug 的分支。
命令
-
查看本地分支
-
git branch -
当前分支前会有一个
*标记。
-
-
查看所有分支(包括远程分支)
-
git branch -a
-
-
创建新分支
-
git branch <branch-name>
-
-
切换分支
-
git switch <branch-name>
-
-
删除本地分支
-
git branch -d <branch-name> -
这回删除已经进行合并的分支,如果分支未合并,使用
-D强制删除
-
-
合并分支
-
合并分支到当前分支
-
git merge <branch-name> -
如果发生冲突则手动打开文件进行修改后保存并提交
-
-
变基是将当前分支的提交“移植”到目标分支的最新提交之后。
-
找到共同的父节点,将该分支单独形成的节点接到目标分支之后
-
git rebase <target-branch>
-
-
-
查看分支的提交历史
-
git log <branch-name>
-
-
查看分支的图形化历史
-
git log --graph --oneline --all
-
-
推送本地分支到远程仓库
-
git push origin <branch-name>
-
-
拉取远程分支的更新
-
git pull origin <branch-name>
-
总结
| 命令 | 说明 |
|---|---|
git branch |
查看本地分支 |
git branch -a |
查看所有分支(包括远程分支) |
git branch <branch-name> |
创建新分支 |
git checkout -b <branch-name> |
创建并切换到新分支 |
git checkout <branch-name> |
切换到已有分支 |
git branch -d <branch-name> |
删除本地分支 |
git push origin --delete <branch-name> |
删除远程分支 |
git merge <branch-name> |
合并分支到当前分支 |
git rebase <target-branch> |
变基到目标分支 |
git push origin <branch-name> |
推送本地分支到远程仓库 |
git pull origin <branch-name> |
拉取远程分支的更新 |
远程仓库
连接远程仓库
-
创建远程仓库(GitHub、Gitee)等
-
配置配置 Git 的用户名和邮箱,这些信息会记录在每次提交中。
-
git config --global user.name "Your Name" git config --global user.email "your.email@example.com"
-
-
查看配置
-
git config --list
-
-
生成 SSH 密钥(推荐)
-
SSH 是一种安全的连接方式,可以避免每次操作时输入密码。
-
生成 SSH 密钥对
-
ssh-keygen -t rsa -b 4096 -C "your.email@example.com" -
会生成公钥和私钥
-
-
将公钥添加到远程仓库(如 GitHub、GitLab)的 SSH 密钥设置中。
-
-
测试 SSH 连接
-
ssh -T git@github.com -
不用修改上面测试命令,如果配置正确,会显示认证成功的消息。
-
-
SSH 密钥的工作原理
- 生成密钥对:
- 使用
ssh-keygen生成一对公钥和私钥。 - 私钥保存在本地,公钥上传到远程服务器或 Git 托管平台。
- 使用
- 身份验证过程:
- 当你尝试连接远程服务器或 Git 托管平台时,远程服务器会生成一个随机字符串,并用你的公钥加密。
- 加密后的字符串发送到你的本地计算机。
- 你的本地计算机使用私钥解密字符串,并将解密结果发送回远程服务器。
- 如果解密结果正确,远程服务器确认你的身份,允许访问。
- 生成密钥对:
常用命令
查看远程仓库信息
-
查看所有远程仓库的别名和 URL
-
git remote -v -
origin git@github.com:username/repository.git (fetch) origin git@github.com:username/repository.git (push) upstream git@github.com:otheruser/repository.git (fetch) upstream git@github.com:otheruser/repository.git (push) -
origin和upstream是远程仓库的别名。 -
fetch和push分别表示拉取和推送的 URL。
-
-
查看某个远程仓库的详细信息
-
git remote show origin
-
-
查看所有远程分支
-
git branch -r
-
-
查看所有分支(包括本地和远程)
-
git branch -a
-
-
查看远程分支的提交历史
-
git log origin/mainorigin/main为想查看的远程分支。
-
拷贝代码
-
git clone用于将远程仓库的代码完整地下载到本地。-
git clone <repository-url> -
<repository-url>:远程仓库的 URL(可以是 SSH 或 HTTPS)。 -
默认会将远程仓库克隆到当前目录下的同名文件夹中。
-
-
克隆特定分支
-
git clone -b <branch-name> <repository-url><branch-name>:远程仓库的分支名称。
-
-
拉取远程仓库的更新
-
git pull-
git pull是git fetch和git merge的组合,用于拉取远程分支的更新并合并到当前分支。 -
git pull origin <branch-name> -
origin:远程仓库的别名。 -
<branch-name>:远程分支名称。 -
git pull默认会拉取远程分支的更新并自动合并到当前分支。如果存在冲突,需要手动解决。
-
-
git fetch用于从远程仓库下载最新的代码,但不会自动合并到当前分支。-
拉取所有远程分支的更新 git fetch --all 拉取特定远程分支的更新 git fetch origin <branch-name>
-
-
如果使用
git fetch拉取了更新,可以手动合并到当前分支:-
git merge origin/<branch-name>
-
-
-
拉取更新后,可以使用以下命令查看远程分支的状态:
-
查看远程分支的更新
-
git log origin/<branch-name>
-
-
-
解决冲突
-
在拉取或合并远程分支时,可能会遇到冲突。解决冲突的步骤如下:
-
拉取远程分支
-
打开冲突文件,手动解决冲突。
-
添加解决冲突后的文件
-
提交合并
-
git pull origin main git add <file> git commit
-
-

浙公网安备 33010602011771号