Git - 常用命令
笔记
下面我们学习 Git 在本地常用的命令,也是开发经常用到的命令。
2024-01-04 @scholar
# 1. Git常用命令
# 本地命令
命令名称 | 作用 |
---|---|
git config --global user.name 用户名 | 设置用户签名 |
git config --global user.email 邮箱 | 设置用户签名 |
git init | 初始化本地库 |
git status | 查看本地库状态 |
git add 文件名(-A 代表目录及子目录下所有文件名) | 添加到暂存区 |
git commit -m "日志信息" [文件名](不加文件名,默认所有文件都添加该日志信息) | 添加到本地库 |
git reflog | 查看历史记录(简要) |
git log | 查看历史记录(详细) |
git log --pretty=oneline | 一行显示一个版本信息(版本号完整) |
git log --oneline | 一行显示一个版本信息(版本号简写) |
git reset --hard 版本号 | 版本穿梭、跳转 |
git diff [文件名] | 比较工作区中和暂存区的文件 |
git diff [本地库中历史版本] [文件名] | 比较工作区中的文件和本地库历史记录 |
git branch 分支名 | 创建分支 |
git branch -D 分支名 | 删除分支 |
git branch -m 新的分支名 | 将当前分支名改为新的分支名 |
git branch -v | 查看分支 |
git checkout 分支名 | 切换分支 |
git merge 分支名 | 合并分支 |
# 远程命令
命令名称 | 作用 |
---|---|
git remote -v | 查看当前所有远程地址别名 |
git remote add 别名 远程地址 | 起别名 |
git push 别名 分支 | 推送本地分支上的内容到远程仓库 |
git clone 远程地址 | 将远程仓库的内容克隆到本地 |
git pull 远程库地址别名 远程分支名 | 将远程仓库对于分支最新内容拉下来后与 当前本地分支直接合并 |
如果 git push
不加别名和分支,默认别名是 origin,分支是 master。
我们 clone 项目会自动做如下操作:
- 拉取代码
- 初始化本地仓库
- 创建别名,默认是
origin
具体看 Git - SSH免密登录。
# 2. 设置用户签名
在 Git 中,用户签名用于标识每个提交的作者。每次提交代码时,Git 都会记录提交者的用户名和邮箱,以确保代码更改与正确的作者相关联。签名信息可以在不同级别进行配置,具体可以分为项目级别和系统用户级别。
# 项目级别/仓库级别签名
项目级别签名只会在当前仓库中生效。这意味着每个 Git 仓库可以有不同的用户签名,适用于需要在同一台机器上管理多个仓库且每个仓库使用不同身份的场景。
设置方法如下:
git config user.name "用户名" # 设置当前仓库的用户名
git config user.email "邮箱" # 设置当前仓库的邮箱
2
- user.name:指定用户的名称,通常为用户名或真实姓名。
- user.email:指定用户的电子邮件地址,可以是常用的邮件地址或虚拟邮箱。
这些配置将保存在当前仓库的 .git/config
文件中,因此它们只会影响当前项目。
# 系统用户级别签名
系统级别签名是全局设置,适用于当前操作系统中的所有 Git 仓库。该签名会在所有没有单独设置项目级签名的仓库中使用。
设置方法如下:
git config --global user.name "用户名" # 设置全局用户名
git config --global user.email "邮箱" # 设置全局邮箱
2
- --global:表示该设置是全局的,适用于当前操作系统中的所有 Git 仓库。全局配置将保存在用户主目录下的
.gitconfig
文件中。
# 配置优先级
- 就近原则:Git 会优先使用最接近的配置。如果项目级别签名已设置,它会覆盖系统用户级别的签名。
- 如果项目级别签名没有设置,Git 会使用系统用户级别的签名。
- 如果两者都没有设置,Git 将无法进行提交操作,必须配置签名。
配置文件位置
- 项目级签名:保存在当前项目目录下的
.git/config
文件中,属于该仓库的本地配置。 - 系统级签名:保存在操作系统用户主目录下的
.gitconfig
文件中,属于全局配置。
说明
- 签名作用:Git 的签名信息主要用于记录每次提交的作者,并在版本控制历史中展示提交记录。每个提交记录都会附带用户的名称和邮箱。
- 邮箱格式:邮箱地址可以是常用的邮件地址或是 Git 提供的虚拟邮箱(如 GitHub 会为每个用户提供一个虚拟邮箱)。Git 本身并不会验证邮箱的有效性,只会用它来标识提交者。
- 与 GitHub 账号的关系:Git 提交时的用户签名和 GitHub(或其他代码托管平台)的登录账号没有直接关系。Git 用户签名只是提交记录的一部分。
图示:设置签名的步骤
# 3. 初始化本地库
在开始使用 Git 进行版本控制时,第一步是初始化一个本地 Git 仓库。使用 git init
命令可以将当前目录转换为 Git 仓库,Git 将开始管理该目录中的文件和更改。
git init # 初始化 Git 仓库
- 执行该命令后,Git 会在当前目录创建一个
.git
文件夹,这个文件夹用于存储所有的 Git 元数据,包括提交记录、配置文件、分支信息等。 - .git 目录是 Git 用来管理版本控制的核心,不能随意删除或修改。如果删除了
.git
目录,Git 就会失去对该项目的管理能力。
注意
- .git 目录:是 Git 管理版本控的核心目录。里面包含:
- config:仓库级的配置文件,存储与该仓库相关的设置。
- HEAD:当前工作分支的指针。
- objects:存储所有提交、文件和历史记录的数据。
- refs:存储分支和标签的引用。
- 初始化后的工作区:在 Git 初始化之后,所有目录和文件都会被 Git 跟踪,但它们尚未提交到版本库。如果需要将修改提交到版本库,还需要执行
git add
和git commit
。
# 4. 查看本地库状态
使用 git status
命令可以查看当前工作区和暂存区的状态,帮助我们了解哪些文件已经修改、哪些文件已经暂存、哪些文件已经提交。
基本命令:
git status # 查看 Git 仓库的状态
执行 git status
后,你会看到以下信息:
- 红色文件:表示这些文件已修改但尚未加入暂存区。它们在工作区被修改,但尚未准备好进行提交。
- 绿色文件:表示这些文件已被加入暂存区,准备进行提交。
- 如果文件被修改并且通过
git add
命令加入了暂存区,Git 会显示这些文件为绿色,表示它们已经准备好被提交到版本库。
- 如果文件被修改并且通过
- 已提交的文件:表示这些文件已经被提交到本地仓库,且不再出现在
git status
中。如果文件已经被提交到本地库,它们将不再显示在git status
的输出中。
图示:Git 状态命令的输出
# 5. 文件增删改操作
Git 提供了一些命令来管理文件的增删改操作,包括将文件从工作区添加到暂存区、从暂存区删除文件、以及提交更改到本地库等。
# 删除暂存区的文件
如果你已经把某个文件添加到暂存区,但不想提交该文件,可以使用 git rm --cached
命令将其从暂存区移除。此操作不会删除工作区的文件,文件会依然存在于本地文件系统中。
git rm --cached 文件名 # 从暂存区移除文件,但保留文件在工作区
- --cached:表示只从 Git 的暂存区移除文件,不会删除文件本身。如果不加该选项,Git 会删除文件以及工作区中的文件。
# 添加文件到暂存区
将文件添加到暂存区是将修改的文件准备好提交到 Git 仓库的一步。可以使用以下命令:
git add 文件名 # 将指定文件添加到暂存区
- 文件名:可以是文件的路径,例如
git add src/index.js
。 - 如果你希望将所有修改过的文件(包括新增、修改和删除的文件)都加入暂存区,可以使用
-A
参数:
git add -A # 将所有文件(新增、修改、删除)添加到暂存区
- -A:表示将工作区中的所有更改(包括新文件、已修改文件和已删除文件)都添加到暂存区。
# 提交文件到本地库
当文件被添加到暂存区后,你可以使用 git commit
命令将这些修改提交到本地仓库。提交时需要为本次提交写一个提交信息,描述所做的更改。
git commit -m "日志信息" # 提交到本地库,附带提交信息
- -m:指定提交信息,说明你这次提交的目的或内容。
- 文件名:你可以指定某个文件名来提交某个文件的更改。如果不指定文件名,Git 会提交所有已添加到暂存区的文件。
# 6. 历史版本操作
Git 提供了多种方法来查看和操作历史版本,帮助我们回溯项目的历史,找回某个版本或查看提交记录。
# 查看历史版本
Git 提供了多种命令来查看项目的历史版本:
git log
:查看详细版本信息,列出所有提交记录,包括提交的哈希值、作者、日期和提交信息。
git log # 查看详细版本信息
git reflog
:查看所有的引用历史,包括分支变动和 HEAD 的历史位置。
git reflog # 查看简要版本信息
git log --pretty=oneline
:以简洁的格式查看提交记录,显示每个版本的完整哈希值和提交信息。
git log --pretty=oneline # 一行显示一个版本信息(版本号完整)
git log --oneline
:显示每个提交的简短版本号(仅显示哈希值的简写)和提交信息。
git log --oneline # 一行显示一个版本信息(版本号简写)
# 多屏显示控制方式
- 空格:向下翻页
- b:向上翻页
- q:退出日志查看
# 切换历史版本
Git 提供了多种方法来回退到某个历史版本,或者撤销某些更改。回退历史版本通常使用 git reset
命令。
# 基于索引值操作(推荐)
你可以使用提交的哈希值来回退到某个历史版本,git reset --hard
命令会将仓库回退到指定的提交,并且会重置工作区和暂存区的状态。
git reset --hard [局部索引值] # 回退到指定版本
git reset --hard a6ace91 # 例如,回退到提交哈希值 a6ace91
2
- 该命令会丢弃之后的所有更改,将仓库恢复到指定版本。
# 使用 ^
符号:只能后退
使用 ^
符号,你可以基于当前版本进行后退。每一个 ^
表示后退一步。
git reset --hard HEAD^ # 后退一步
- HEAD^:表示回退到当前提交的前一个提交。
- 如果需要后退多步,可以使用多个
^
。
git reset --hard HEAD^^ # 后退两步
# 使用 ~
符号:后退指定步数
使用 ~
符号,你可以指定后退的步数。
git reset --hard HEAD~n # 后退 n 步
- 例如,
git reset --hard HEAD~3
表示回退到当前版本之前的第 3 个提交。
# 使用 HEAD
恢复当前提交本地库的版本
如果你想恢复到当前提交的版本,可以使用 git reset --hard HEAD
。这会将仓库恢复到当前版本的状态(丢弃未提交的修改)。
git reset --hard HEAD # 恢复当前提交本地库的版本
# reset
命令的三个参数对比
--soft
:仅仅移动 HEAD 指针,不会改变暂存区和工作区的内容。此时更改仍然存在于暂存区,等待提交。
git reset --soft HEAD~1 # 只移动 HEAD 指针,不影响暂存区和工作区
--mixed
(默认选项):移动 HEAD 指针,并且重置暂存区的内容,但不会影响工作区的内容。也就是说,暂存区会回到指定版本的状态,而工作区的修改保留。
git reset --mixed HEAD~1 # 重置暂存区,但保留工作区修改
--hard
:不仅移动 HEAD 指针,重置暂存区,还会重置工作区。所有未提交的更改都会丢失,恢复到指定版本的完全状态。
git reset --hard HEAD~1 # 完全重置,丢失所有未提交的修改
# 7. 比较文件操作
Git 提供了多种命令来比较工作区、暂存区和本地库之间的文件差异。这些比较功能可以帮助开发者检查代码变更,确保提交的准确性。
# 将工作区中的文件和暂存区进行比较
使用 git diff
命令,可以查看工作区和暂存区之间的差异。这个命令会显示当前工作区(尚未暂存的文件)与暂存区(已加入 Git 管理的文件)之间的差异。
git diff [文件名] # 比较工作区和暂存区的差异
- [文件名]:指定要比较的文件。如果不指定文件名,则比较所有文件。
# 将工作区中的文件和本地库历史记录进行比较
如果你希望查看工作区的文件与本地库中的历史版本之间的差异,可以使用 git diff
与本地库中的历史版本进行比较:
git diff [本地库中历史版本] [文件名] # 比较工作区和指定历史版本的差异
- [本地库中历史版本]:可以指定某个提交的哈希值,或者使用
HEAD
来表示当前版本。 - [文件名]:指定要比较的文件。如果不指定文件名,默认会比较多个文件。
例如,比较当前工作区和 HEAD
(当前版本)的差异:
git diff HEAD [文件名] # 比较工作区与当前版本(HEAD)的差异
# 8. 分支操作
分支是 Git 中非常强大的功能,可以让你在不同的任务上并行开发,而不会相互影响。通过分支,你可以在不影响主分支的情况下开发新功能,修复 bug,或者尝试不同的方案。分支的本质是指向 Git 提交历史中的某个特定版本,它是一个指针。
# 什么是分支?
在 Git 中,分支就是一个指针,它指向代码库中某个特定的提交(版本)。通过分支,开发者可以在不同的代码路径上进行并行开发,而这些分支的修改不会直接影响到其他分支。
例如,我们可以在主分支(master
或 main
)上进行稳定的开发,同时在其他分支(如 feature
、bugfix
)上开发新功能或者修复问题。各个分支之间的修改不会互相干扰。
图示:分支的概念
分支的好处
- 并行开发:允许多个开发者同时在不同的分支上进行工作,每个开发者可以独立地修改代码,互不干扰。
- 避免冲突:分支可以让开发者在自己的分支上开发,而不会影响主分支的运行。当功能开发完成时,再将分支合并到主分支。
- 恢复失败的任务:如果某个分支的开发失败,可以轻松删除该分支,而不会影响其他分支的进展。
图示:分支的并行开发
# 分支操作
命令名称 | 作用 |
---|---|
git branch 分支名 | 创建新分支 |
git branch -D 分支名 | 删除分支 |
git branch -m 新的分支名 | 修改当前分支名 |
git branch -v | 查看分支 |
git checkout 分支名 | 切换到指定分支 |
git merge 分支名 | 合并指定分支到当前分支 |
# 创建分支
使用 git branch
命令来创建一个新的分支:
git branch [分支名] # 创建一个新分支
- [分支名]:指定要创建的分支名称。
# 删除分支
当一个分支不再需要时,可以使用 git branch -D
删除它。注意,删除的分支需要确保没有未合并的修改,否则 Git 会提示警告。
git branch -D [分支名] # 强制删除分支
- -D:表示强制删除分支。如果分支没有被完全合并,Git 会阻止删除,使用
-D
强制删除。
# 修改分支名
如果你想修改当前分支的名称,可以使用 git branch -m
命令:
git branch -m [新的分支名] # 修改当前分支的名称
# 查看分支
使用 git branch -v
命令可以查看当前 Git 仓库的所有分支及其最新提交。
git branch -v # 查看所有分支及其最新提交
# 切换分支
使用 git checkout
命令可以切换到指定的分支。切换分支时,Git 会自动更新工作区的内容,以便与目标分支匹配。
git checkout [分支名] # 切换到指定的分支
# 合并分支
如果你想将某个分支的修改合并到当前分支,可以使用 git merge
命令。合并操作通常分为两个步骤:
- 切换到目标分支:首先切换到接受合并内容的分支。
git checkout [目标分支] # 切换到接收修改的目标分支
- 执行合并操作:然后执行
git merge
命令来合并分支。
git merge [源分支] # 将源分支的修改合并到当前分支
- [目标分支]:是你当前所在的分支,接受合并的内容。
- [源分支]:是你希望将其内容合并到当前分支的分支。
# 分支冲突
在执行合并操作时,如果两个分支在相同文件的相同位置进行了不同的修改,Git 就会无法自动解决这些差异,从而产生合并冲突。合并冲突的状态会显示为 MERGING
,并且在文件中会出现特殊标记。
图示:产生冲突
# 解决冲突
解决冲突的步骤如下:
- 编辑文件:打开冲突的文件,删除 Git 自动插入的标记(
<<<<<<<
、=======
、>>>>>>>
),然后选择保留合适的代码。
图示:冲突文件的内容
- 保存文件:修改文件内容,解决冲突后保存退出。
- 添加到暂存区:将已解决冲突的文件添加到暂存区。
git add [文件名] # 将解决冲突后的文件添加到暂存区
- 提交合并:提交合并后的结果。此时,提交信息中会自动标注为合并提交。
git commit -m "解决合并冲突" # 提交合并结果
注意:在此时提交时,git commit
命令不能带具体文件名,Git 会自动提交所有已暂存的修改。
# 创建分支和切换分支的图解
创建分支和切换分支的过程可以通过 Git 中的指针变化来理解。HEAD
是当前分支的指针,指向当前所在的提交。每当你切换分支时,HEAD
会指向新的分支。
图示:创建分支和切换分支
- HEAD 指针:在 Git 中,
HEAD
是一个指向当前分支或提交的指针。通过git checkout
或git branch
命令,可以切换HEAD
指向的分支。
# 9. 分支进阶操作
在 Git 中进行分支的高级操作可以帮助开发者更灵活地管理分支,清理历史记录,修改提交记录或重命名分支。以下是一些常见的分支进阶操作及其详细步骤。
# 删除所有记录
如果你希望清空所有提交记录,将仓库恢复为初始状态,但保留现有代码,可以按照以下步骤操作:
操作步骤:
切换到一个新的分支:避免直接操作主分支,先创建并切换到新分支。
git branch kele # 创建一个新分支 kele git checkout kele # 切换到新分支 kele
1
2添加所有文件到暂存区:将当前工作区中的所有文件添加到暂存区(忽略
.gitignore
文件中排除的内容)。git add -A # 添加所有文件到暂存区
1提交文件到本地库:将暂存区中的文件提交到本地库。
git commit -am "commit message" # 提交文件并附带提交信息
1删除
master
分支:清空主分支。git branch -D master # 强制删除 master 分支
1重命名当前分支为
master
:将当前分支改为主分支。git branch -m master # 将当前分支重命名为 master
1强制推送到远程
master
分支:覆盖远程的主分支。git push -f origin master # 强制推送到远程 master 分支
1
# 删除上次提交记录
如果你想修改上次提交的代码,并重新提交一次更完善的记录,可以使用以下方法。
操作步骤:
回到上一个版本:将代码回退到上一个版本,但不要使用
--hard
参数,以保留工作区的更改。git reset commitId # 回到指定的提交版本(不带 --hard)
1commitId
:需要回退的提交的哈希值,使用git log
查看。
暂存当前修改:将当前工作区中的修改暂存起来。
git stash # 暂存修改
1强制推送到远程:删除远程的最新一次提交记录。
git push --force # 强制推送到远程,删除远程的最新提交
1释放暂存的修改:将暂存的修改恢复到工作区,继续修改代码。
git stash pop # 恢复暂存的修改
1重新提交并推送:修改完成后重新提交,并将更改推送到远程仓库。
git add . # 添加修改的文件到暂存区 git commit -m "message" # 提交修改 git push # 推送到远程仓库
1
2
3
# 修改本地分支名和对应的远程分支名
如果需要修改分支名称,并同步更新本地和远程分支,可以按照以下步骤操作。修改前需确保代码是最新的,以免影响团队开发。
操作步骤:
修改本地分支名:将本地分支名改为新的名称。
git branch -m oldBranchName newBranchName # 修改本地分支名
1删除远程分支:将远程旧分支删除。
git push origin :oldBranchName # 删除远程分支 oldBranchName
1:
:在分支名前加冒号表示删除。
推送新的本地分支到远程:将改名后的本地分支推送到远程,并设置上游分支。
git push --set-upstream origin newBranchName # 推送新的分支到远程并关联
1
# 图示:分支操作示意图
分支创建和切换示意图
- 创建分支的本质:在 Git 中,分支是指向提交记录的指针。当你创建一个新分支时,Git 会生成一个新的指针,并指向当前的提交。
- HEAD 的作用:
HEAD
是一个指针,始终指向当前所在的分支。
分支冲突示意图
当合并分支时,如果两个分支对同一文件的同一位置进行了不同的修改,就会出现冲突。需要开发者手动解决。
# 10. Git 远程操作
Git 提供了强大的远程操作功能,用于管理本地与远程仓库之间的交互。远程仓库通常存储在代码托管平台(如 GitHub、GitLab、Bitbucket)上。以下是 Git 远程操作的常见场景及其详细步骤。
# 1. 查看远程仓库
要查看当前 Git 仓库已连接的远程仓库地址及其别名,可以使用以下命令:
git remote -v # 显示所有远程仓库地址和别名
- 输出内容:
origin
:默认远程仓库的别名。fetch
:用于拉取远程内容。push
:用于推送本地内容到远程。
# 2. 添加远程仓库
在初始化本地仓库后,需要添加一个远程仓库地址来同步代码。使用 git remote add
命令添加远程仓库:
git remote add origin [远程仓库地址] # 添加远程仓库并命名为 origin
origin
:远程仓库的别名(可以自定义)。[远程仓库地址]
:远程仓库的完整地址,通常以 HTTPS 或 SSH 开头,例如:- HTTPS:
https://github.com/username/repository.git
- SSH:
git@github.com:username/repository.git
- HTTPS:
什么是 origin?
- 别名(alias):在使用 Git 时,你的本地仓库可以连接到一个或多个远程仓库。为了方便操作,每个远程仓库都会被赋予一个简短的名称(别名)。默认情况下,当你通过
git clone
克隆一个远程仓库时,Git 会自动为这个仓库的远程地址分配一个别名,称为origin
。 - 便捷性:通过别名
origin
,你可以在命令中直接使用它,而无需每次都输入完整的远程仓库地址。
# 3. 删除远程仓库
如果需要解除本地与远程仓库的绑定,可以删除远程仓库:
git remote remove origin # 删除名为 origin 的远程仓库
# 4. 修改远程仓库地址
如果远程仓库的地址变更(例如迁移到新的服务器),可以使用以下命令修改:
git remote set-url origin [新的远程仓库地址] # 修改远程仓库的地址
# 5. 克隆远程仓库
克隆是 Git 中常见的操作,用于将远程仓库的完整内容复制到本地。执行克隆操作时,Git 会自动创建一个与远程仓库关联的本地仓库。
git clone [远程仓库地址] # 克隆远程仓库到本地
示例:
git clone https://github.com/username/repository.git
1- 该命令会在当前目录下创建一个名为
repository
的文件夹,并将远程仓库的内容拉取到本地。
- 该命令会在当前目录下创建一个名为
# 6. 推送代码到远程仓库
推送操作用于将本地代码同步到远程仓库。一般情况下,先将修改提交到本地仓库后,再进行推送。
首次推送
当本地仓库首次推送到远程仓库时,需要指定远程分支的名称:
git push -u origin master # 将本地 master 分支推送到远程 master 分支,并设置默认推送
-u
:设置本地分支与远程分支的跟踪关系,后续可以直接使用git push
。origin
:远程仓库的别名。master
:推送的目标分支名称。
后续推送
在设置了默认分支后,可以直接使用以下命令推送代码:
git push # 推送代码到远程仓库
# 7. 拉取代码(同步远程内容到本地)
拉取操作用于将远程仓库的最新内容同步到本地。使用以下命令:
git pull origin [分支名] # 从远程仓库拉取指定分支的最新内容
origin
:远程仓库的别名。[分支名]
:需要拉取的分支名称(例如master
)。
如果当前分支已跟踪远程分支,可以直接使用以下命令:
git pull # 拉取当前分支的最新内容
# 8. 强制推送到远程仓库
如果需要覆盖远程仓库的历史记录,可以使用强制推送。但需要谨慎操作,避免覆盖他人的提交记录。
git push --force # 强制推送本地代码,覆盖远程仓库内容
- 适用场景:
- 修改了提交历史后,需要将更改同步到远程。
- 清空远程提交记录。
# 9. 同步本地和远程分支
推送新分支到远程
当本地创建了一个新分支,需要将其推送到远程时,使用以下命令:
git push --set-upstream origin [分支名] # 推送新分支并设置上游分支
--set-upstream
:将本地分支与远程分支关联,后续可直接使用git pull
和git push
。
拉取远程新分支到本地
当远程创建了一个新分支,需要将其拉取到本地时,使用以下命令:
git fetch origin [分支名] # 获取远程新分支的内容
git checkout -b [分支名] origin/[分支名] # 在本地创建对应分支并切换
2
# 10. 查看远程分支
要查看远程仓库的所有分支,可以使用以下命令:
git branch -r # 查看所有远程分支
# 11. 删除远程分支
删除远程分支时,需要通过以下命令操作:
git push origin --delete [分支名] # 删除远程分支
--delete
:指定要删除的远程分支。
# 12. 检查远程状态
使用以下命令可以检查远程仓库和本地仓库的状态差异:
git remote show origin # 显示远程仓库的详细信息