基本使用
设置用户名/邮箱
安装git后先设置,相当于本机器自报家门
1 | git config --global user.name "Your Name" |
查看git配置信息
1 | git config --list |
注意 git config
命令的 --global
参数,用了这个参数,表示你这台机器上所有的 Git 仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和 Email 地址。
也可以通过修改git配置文件,配置文件位置:用户-.gitconfig
提交步骤
把目录变成 Git 可以管理的仓库
1 | git init |
查看文件状态
1 | git status |
把文件提交到暂存区
1 | git add 文件名 |
向仓库中提交代码
1 | git commit |
参数:
-m 本次提交的说明
: 附带提交说明提交-a
: 同时保存暂存区(该操作对未添加到暂存区的文件无效)
提交文件原则:每一次提交只包含一个功能,不要在一次提交中包含多个功能
查看提交记录
1 | git log |
这是一个强大的日志输出命令,提供了众多可选选项,通过 git log --help
查看所有选项。
默认情况下,git log
按照默认输出格式,通过交互式滚动输出全部的提交日志,默认格式为:
1 | commit 00e59eb74e217cbb70022b02b2b5a67afcde5a1e (origin/dev-3.2.2, dev-3.2.2) |
这其中 commit
后较长的 SHA-1 字符串为 commit id
。
我们可以通过自定义选项来修改默认的输出格式,常用格式化输出结果选项:
选项 | 说明 |
---|---|
–format | 使用给定格式输出提交日志内容,可选项有 oneline 、short 、medium 、reference 、email 、raw 、format:<string> |
–abbrev-commit | 仅显示 SHA-1 的前 6 个字符,而非全部的 40 个字符 |
–oneline | –format=oneline –abbrev-commit 组合选项的简写 |
–date | 使用给定的格式输出提交日志中的日期内容,可选项有 local 、relative 、format:<string> 等其中 format:<string> 后跟随 strftime 格式占位符,例如 --date=format:"%Y-%m-%d %H:%M:%S" |
–relative-date | 等同于 --date=relative ,展示相对时间(例如 3 weeks ago ) |
默认情况下,git log
不生成任何 diff 输出,下面是常用 diff 输出选项:
选项 | 说明 |
---|---|
-p | 按补丁格式显示每个更新之间的差异 |
–stat | 直观展示每个文件的增删修改统计信息 例如: src/modules/plugin.ts | 5 +-- |
–shortstat | 仅展示 --stat 的最后一行的文件改动信息 7 files changed, 64 insertions(+), 12 deletions(-) |
–name-only | 仅展示改动文件的列表 |
–name-status | 在 --name-only 的基础上新增改动文件的状态,例如: M .gitignore |
–graph | 在左侧追加提交线 |
一些可选选项可以对输出结果进行一层过滤:
选项 | 说明 |
---|---|
-n | -3 显示最近 3 条 commit 记录 |
–author | 仅显示指定作者相关的提交 |
–committer | 仅显示指定提交者相关的提交 |
–before | 仅显示指定时间之前的提交 |
–after | 仅显示指定时间之后的提交 |
–grep | 仅显示含有指定关键字的提交 |
撤销操作
删除文件
删除文件并添加到暂存区
1 | git rm /test/path/test-file.md |
等效于下面两步
- 手动删除 /test/path/test-file.md
git add /test/path/test-file.md
撤销暂存
旨在让 git 不再管理此文件
1 | # 取消托管指定路径下的所有文件 |
撤销当前改动
即回退到最近一次提交,有如下几种操作
1 | # 将整个项目回退到最近一次提交,非常激进的操作 |
版本回退
在 Git 中,用 HEAD
表示当前版本,上一个版本为 HEAD^
,上上个版本为 HEAD^^
,往上第 100 个版本为 HEAD~100
。
注:当执行版本回退操作时,会清空所有当前未提交与未暂存的代码。
1 | # 整体回退到最新版本(还原全部未提交改动) |
总结:HEAD 指向的版本就是当前版本,因此,Git 允许我们在版本的历史之间穿梭,使用命令 git reset --hard commit_id
。
穿梭前,用 git log
可以查看提交历史,以便确定要回退到哪个版本。要重返未来,用 git reflog
查看命令历史,以便确定要回到未来的哪个版本。
分支操作
Git鼓励大量使用分支
基本操作
1 | # 查看分支 |
合并分支
将指定分支内容合并至当前分支,分为两种合并方式
若两个分支同时改动了一处地方,则会出现冲突,需要解决冲突
本文 gif 图来源: 🌳🚀 CS Visualized: Useful Git Commands - DEV Community
merge
1 | git merge <branch_name> |
这种合并方式将会创建一个新的 merge commit
节点来合并两个分支的改动
提交线的效果图如下
而当当前分支未作任何提交,仅目标分支存在改动时,将会移动目标分支的 commit 节点至当前分支,不会创建 merge commit
节点。
优点:保留提交线原始格式,易于溯源,非常安全绝对不会出错的合并方式
缺点:提交线杂乱难以阅读
rebase
1 | git rebase <branch_name> |
这种合并方式将会提升当前分支的 commit 节点,并将被合并分支的 commit 节点插入到当前分支 commit 节点之前
提交线的效果图如下
优点:不会出现新的 merge
节点,提交线整洁易于阅读,完全使用 rebase
合并分支的项目会只有一条提交线
缺点:打乱了提交线,不懂原理的新手随意操作会造成无法挽回的结果
解决冲突
在多人同时开发一个顶目时,如果两个人修改了同一个文件的同一个地方,就会发生冲突。根据拉取代码方式,分为两种情况
- git pull: 解决冲突后,需要手动
commit
一个 merge 提交。若存在手动改动的部分,还需要在commit
之前手动保存至暂存区 - git rebase: 解决冲突后执行
git rebase --continue
,继续处理其他后续可能存在的冲突。全部解决完毕后与git pull
后续操作一致
合并某分支到当前分支
1 | # 应当切换到合并分支上,来合并被合并分支(如要将dev合并到master分支,则应切换到master分支,进行合并操作) |
暂时保存更改
在 git 中,可以暂时将分支上所有的改动保存到临时存储区,让开发人员得到一个干净的工作副本,临时转向其他工作。
使用场景:分支临时切涣、存储临时改动
1 | # 保存当前所有未提交的改动 |
stash 区域是独立于分支的,不管在哪个分支执行 pop
或 apply
都会将改动恢复到此分支,因此需要注意所在的是哪个分支
PowerShell 中
{}
被认作代码块执行标识符,需要对{
与}
使用`
转义,写法为git stash apply stash@`{n`}
更改已存在的提交信息
git commit 的 --amend
参数可以将当前工作目录中的修改添加到最新一次提交中,并可以修改最新的这次提交的相关信息
我们可以利用这个特性来直接修改最后一次提交的相关信息,例如修改最后一次提交的作者信息
1 | # 不需要修改提交信息时,可以添加 --no-edit 跳过提交信息修改 |
修改多条已存在的提交信息
可以借助 rebase
依次编辑的特性,来实现对多条 commit 信息进行修改
例如修改最近 10 条 commit 的作者信息
1 | git rebase -i HEAD~10 |
同步提交时间与创建时间
每一个提交都存在创建时间与提交时间两个时间,通常情况下这两个时间是相同的。
但在执行 --amend
或 rebase
等修改分支的操作后,提交时间会和创建时间存在一定的差异
为了避免出现昨天的提交在今天的提交之后的诡异情况,我们需要将提交时间与创建时间均同步为当前时间。
首先我们需要获取当前的系统时间,根据不同命令行系统有各自不同的获取操作:
- Command Prompt:
echo %date% %time%
- PowerShell:
Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
- Git Bash/Linux:
date
之后可借助 --date
参数来对分支创建时间进行修改,在参数值中,可以使用 $()
执行系统命令
1 | # Command Prompt |
最后可通过 [修改多条已存在的提交信息][#修改多条已存在的提交信息] 来批量修改分支的提交时间
远程仓库使用(以github为例)
创建仓库
- 仓库名:不能和其他仓库名称重复
- Description:描述信息,可选
- README.md:对仓库的详细描述,给其他人看的
邀请合作者
setting-manage access
复制 invite link
(邀请链接)发送给合作者
远程仓库别名相关
可以给远程仓库定义别名,来简化操作
1 | # 查看别名列表 |
向远程仓库推送本地仓库
首先记得先在当前仓库设置用户名和邮箱(优先级大于全局设置,该设置不会被推送至远程仓库)
1 | git config user.name "Your Name" |
推送本地仓库的不同方式
1 | # 正常推送 |
不同分支推送
默认情况下将本地内容推送至与本地同名的线上分支,可以修改这个默认行为
1 | git push <origin_respository_alias> <local_branch_name>:<origin_branch_name> |
查看远程仓库分支
1 | # 查看指定别名的远程仓库信息 |
删除远程仓库分支
1 | git push origin -d <origin_branch_name> |
删除后再次执行 git remote show
查看远程状态时,会发现该分支依旧存在,并被添加了备注标记:
1 | refs/remotes/origin/dev-3.0.1 stale (use 'git remote prune' to remove) |
此时需要执行以下命令来同步本地与远程分支改动
1 | git remote prune origin |
拉取远程仓库内容
获取远程仓库内容的操作分为完整克隆和拉取更新指定分支内容两种操作
克隆远程仓库
完整克隆下载远程仓库内容,这对本地来说是一个从无到有的过程。
使用此种方法下载的仓库文件包含完整的 .git
托管记录文件,这与直接点击 Download ZIP
下载源码压缩包有本质上的区别
1 | # 克隆远程仓库到本地 |
拉取远程仓库内容
拉取更新远程仓库内容,这是建立在已经存在一个本地仓库的前提下进行的。
其拥有两种拉取方式 fetch
和 pull
严格意义上讲,后者包含前者
fetch
fetch 会将远程分支内容拉取到本地,以 <origin_respository_alias>/<branch_name>
的命名方式定义为一个远程分支的本地副本(非本地分支)
可通过 git branch -a
来查看这些副本分支。
1 | # 更新远程仓库的所有分支至本地副本 |
pull
pull 会拉取远程指定分支内容,并合并至本地分支,其合并方式有两种 merge
与 rebase
1 | # 默认 merge 方式合并 |
他其实是 fetch
和 merge
/ rebase
两个命令的组合操作
1 | git pull origin dev |
既然 pull
的操作包含 merge
/ rebase
,他也存在出现冲突的可能,在必要的情况下需要手动解决冲突。
git pull 和 git clone 的区别
命令 | 区别 |
---|---|
git pull | 和本地版本进行对比,仅仅拉取最新版本,在已经有本地仓库的基础上进行 |
git clone | 完全克隆远程仓库,在没有本地仓库的基础上进行 |
当本地仓库版本落后于远程仓库版本时,不能进行提交,需要先进行 git pull
拉取最新版本
跟踪仓库
设置后再次使用 push 与 pull 时,无需指定仓库地址与分支名称,直接 git pull
与 git push
即可
1 | git branch --set-upstream-to=远程仓库别名/分支名称 本地分支名称 |
公钥和私钥
只有在远程仓库中存入了公钥,才能使用 ssh 提交。
ssh
相比 http
提交的好处:让远程仓库认识本机,免于 pull
或 push
时需要输入 github 用户密码
需要开发者用命令生成,实际就是两个文件,其中公钥要放在 github 账户
中,私钥保留在开发者电脑
中。
生成密钥
1 | ssh-keygen -t ed25519 -C "your_email@example.com" |
密钥默认存储目录
1 | # windows |
生成的密钥默认名:
- 私钥(rsa:非对称加密方式):
id_rsa
- 公钥:
id_rsa.pub
github 公钥存放地址
1 | 头像 - setting - SSH and GPG keys - New SSH key |
即将生成的 id_rsa.pub
文件里面的内容复制进去
设置好后,推送时会对电脑中的私钥和github中的公钥配对,配对成功即成功推送