Git工作技巧碎片
Git^1 (opens new window) 是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理。
特性:
- 适合分布式开发,强调个体。
- 公共服务器压力和数据量都不会太大。
- 速度快、灵活。
- 任意两个开发者之间可以很容易的解决冲突。
- 离线工作。
# 1. 专有名词
- 拉取: 拉去远程仓库工程代码并合并到当前本地仓库
- 获取: 拉去远程仓库资源,并不参与合并
- 工作区: 内容编辑区
- 暂存区: 内容编辑,在提交到本地仓库前暂存,随时方便撤销、退回
- 本地仓库: 客户端本地仓库
- 远程仓库: 服务端仓库
- 分支: 工程代码索引分支,分为主分支、其他分支
- 远程分支: 服务端分支
- 推送: 将本地仓库数据推送到服务端进行合并(在这之前最好先拉取远程仓库代码)
# 2. 工作方式
# 3. 原理
Git 把数据看作是小型文件系统的一组快照。 每次提交更新时 Git 都会对当前的全部文件制作一个快照并保存这个快照的索引。 为了高效, 如果文件没有修改,Git 不再重新存储该文件, 而是只保留一个链接指向之前存储的文件。 所以 Git 的工作方式可以称之为快照流。
注意: 若文件没有修改,则通过指针指指向前一个版本文件如 Version3的A1 为发生修改,则可以通过一个指针指向Version2的A1
git 是基于hash实现保证文件的唯一完整性的。
哈希是一个系列的加密算法, 各个不同的哈希算法虽然加密强度不同, 但是有以下几个共同点:
- 不管输入数据的数据量有多大,输入同一个哈希算法,得到的加密结果长度固定。
- 哈希算法确定, 输入数据确定, 输出数据能够保证不变
- 哈希算法确定, 输入数据有变化, 输出数据一定有变化, 而且通常变化很大
- 哈希算法不可逆
- Git 底层采用的是 SHA-1 算法。哈希算法可以被用来验证文件。 原理如下图所示:
# 4. git基础操作
# 4.1. 配置
# 配置
# 查看git所在系统目录基础信息
git config --system --list
# 查看git全局配置信息
git config --global --list
# 这里设置的签名和登录远程库(代码托管中心)的账号、 密码没有任何关系
# 就近原则: 项目级别优先于系统用户级别, 二者都有时采用项目级别的签名
# 如果只有系统用户级别的签名, 就以系统用户级别的签名为准,二者都没有不允许
git config --global user.name "你的名字或昵称"
git config --global user.email "你的邮箱"
# 设置指定仓库中的email,针对特定的仓库,不错
git config user.email "你的邮箱"
2
3
4
5
6
7
8
9
10
11
12
# 4.2. 历史记录操作
# 4.2.1. 查看日志记录信息
# 日志查看
# 查看提交的日志信息
git log
# 格式化日志为一行输出
git log --pretty=oneline
# 格式化日志为一行输出
git log --oneline
# 查看仓库状态
git status
# 查看每一次命令参数信息
git reflog
# 查看详细的变动
git log -p
# 查看大变动
git log --stat
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4.2.2. 打标签
在开发的一些关键时期,使用标签来记录这些关键时刻, 例如发布版本, 有重大修改, 升级的时候, 会使用标签记录这些时刻, 来永久标记项目中的关键历史时刻;
Git中的标签分为 轻量级标签(lightweight) 和 带注释的标签(annotated), 一般情况下推荐使用带注释的标签, 如果标签是临时的可以采用轻量级标签;
- 轻量级标签 : 轻量级标签中的信息含量很少, 这种标签只代表某时刻代码的提交, 相当于指向这个提交的指针;
- 带注释标签 : 这种标签是一种校验和, 包含标签名, 邮箱, 日期, 标签信息, GPG签名 和 验证, 它相当于一个对象, 封装了这些信息;
# 查看仓库的标签
git tag
2
# 4.2.3. 暂存区
# 暂存区
# 暂存到git栈中
git stash
# 从git栈中读取最近一次的备份内容
git stash pop
# 显示git栈中的所有备份列表,恢复指定内容
git stash list
# 清除git栈中的所有内容
git stash clear
# 撤销暂存区文件需要制定文件名
git rm --cached <file>
2
3
4
5
6
7
8
9
10
11
# 4.2.4. 版本回退
# 往后退,注意^ 一个^表示后退一步, n 个表示后退 n 步
git reset --hard HEAD^
# 后退n 步,n表示回退几个版本
git reset --hard HEAD~n
# 本地库版本HEAD指针移动到指定版本,同时重置暂存区和工作区
git reset --hard <版本号hash(索引)>
# 本地库版本HEAD指针移动到指定版本,但是只回退本地仓库,暂存区、工作区不会回退
git reset --soft <版本号hash(索引)>
# 本地库HEAD指针移动到指定的版本,同时重置暂存区,但是工作区不会被重置
git reset --mixed <版本号hash(索引)>
2
3
4
5
6
7
8
9
10
# 4.2.5. 文件删除找回
文件需要找回,前提是当前编辑文件已经提交到本地仓库;本地仓库若没提交则无法找回 若要找回当前工作区删除的文件,则执行git reset --hard HEAD 指向当前版本
# 4.2.6. 差异比较
# 比较当前工作区与暂存区的文件差异
git diff
# 比较指定文件与暂存区的差异
git diff <文件名>
# 比较本地版本库与工作区文件差异
git diff <本地版本库><文件名>
2
3
4
5
6
# 4.3. 分支操作
# 分支管理 dev 是分支名
git branch --查看本地分支
# 查看远程分支
git branch -r
# 查看分支详细,显示提交的备注说明,和时间
git branch -v
# 创建分支dev
git branch dev
# 创建分支并切换到创建的分支dev
git branch dev -b
# 切换分支dev
git checkout dev
# 合并分支,name的分支与当前分支合并dev
git merge dev
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4.4. 仓库交互
# 4.4.1. 本地
git commit –amend 修改上一次提交,也就是将当前提交合并为上一次提交内容中(commit message 相同)
git commit --signoff 签名
2
# 4.4.2. 远程
# 远程仓库交互
# 初始化本地仓库,让文件夹变成一个git仓库
git init
# 添加一个远程仓库
git remote add origin url(远程仓库地址)
# 移除远程仓库
git remote rm origin
# 将远程仓库的文件拉取到本地并合并
git pull origin master
# 推送
git push origin master
#
git push -u origin master
# 相当于是从远程获取最新版本到本地,不会自动merge
git fetch origin master
# 从远程仓库获取最新并合并本地
git pull origin master = fetch+merge
# 合并从远程仓库拉去的代码
git merge [远程库地址别名/远程分支名]
# pull=fetch+merge
git fetch [远程库地址别名] [远程分支名]
git merge [远程库地址别名/远程分支名]
git pull [远程库地址别名] [远程分支名]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 4.5. SSH登录
# 按照步骤操作
# 进入当前目录
cd ~
# 删除.ssh 目录
rm -rvf .ssh
# 运行命令生成.ssh 密钥目录
ssh-keygen -t rsa -C "rickwork@163.com" -- 生成sshkey github仓库中绑定
# 进入.ssh 目录查看文件列表
cd .ssh
# 查看 id_rsa.pub 文件内容,复制key 放自己的仓库SSH秘钥
cat id_rsa.pub
# 回到 Git bash 创建远程地址别名
git remote add origin_ssh [ssh远程仓库地址]
# 验证是否绑定成功(前提,你把生成的id_rsa.pub复制到你的远程仓库)
ssh -T git@github.com
2
3
4
5
6
7
8
9
10
11
12
13
14
15
多ssh登录
- 创建key
# ed25519
ssh-keygen -t ed25519 -C "xxxxx@163.com" -f C:/Users/Rick/.ssh/gitcode/ssh_key
# rsa 与ed25519 推荐后者,更安全
# ssh-keygen -o -t rsa -b 4096 -C "xxxxx@163.com" -f C:/Users/Rick/.ssh/gitcode/ssh_key
# -t 指定要创建的密钥类型
# -b 指定密钥长度
# -C 提供一个新注释 这里需要填写你注册的github 或者 gitlab 邮箱号
# -f 指定密钥文件名(路径)
2
3
4
5
6
7
8
- 配置key
在.ssh目录下新增config文件
# gitcode
Host gitcode.net
HostName gitcode.net
User xxxxx@163.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/gitcode/ssh_key
# gitee
Host gitee.com
HostName gitee.com
PreferredAuthentications publickey
User xxxxx@163.com
IdentityFile ~/.ssh/gitee/ssh_key
# github
Host github.com
HostName github.com
User xxxxx@163.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/github/ssh_key
# Host 代表关键词
# HostName 代表 主机地址
# User 代表用户名
# IdentityFile 代表 认证文件
# PreferredAuthentications 登录类型
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 5. 其他技巧
# 5.1. 设置全局忽略文件
- 在用户目录下找到.gitconfig全局配置文件,加入如下配置;当然你也可以使用命令
git config --global core.excludesfile "%USERPROFILE%\.gitignore"
添加
[core]
excludesfile = C:\\Users\\Rick\\.gitignore
2
- 默认情况下,在windows不能通过创建文件方式创建.gitignore,可以使用
touch .gitignore
创建 - 然后在.gitignore文件中添加需要忽略的文件(支持glob表达式),如
.idea
*.iml
2
# 5.2. Git易错命令
- 后悔药
git reflog
# 你将看到你在 git 上提交的所有改动记录被列
# 了出来,而且囊括了所有的分支,和已被删除的
# commit 哦!
# 每一条记录都有一个类似 HEAD@{index} 的索
# 引编号
# 找到在犯错前的那个提交记录的索引号,然后执
# 行:
git reset HEAD@{index}
# 哈哈,这就是你要的时光机!
2
3
4
5
6
7
8
9
10
- 修改提交备注
切记: 别对已经推送到远程仓库的 commit 做 amend 操作,会影响仓库变动提交信息可读性
# 继续改动你的文件或者你可以添加指定的文件
git add .
# 你这次的改动会被添加进最近一次的 commit 中
git commit --amend --no-edit
# 按照提示修改信息就行啦
git commit --amend
2
3
4
5
6
- 变动提错分支
该操作对push变动至远程仓库分支无效
# 基于当前 master 新建一个分支
git branch some-new-branch-name
# 在 master 上删除最近的那次 commit
git reset HEAD~ --hard
git checkout some-new-branch-name
# 只有在这个新分支上才有你最近的那次 commit 哦
2
3
4
5
6
- commit 提交错分支
- 通过暂存区来实现
# 撤回这次提交,但保留改动的内容
git reset HEAD~ --soft
git stash
# 现在切到正确的那个分支去
git checkout name-of-the-correct-branch
git stash pop
git add . # 或者你可以添加指定的文件
git commit -m "your message here";
# 现在你的改动就在正确的分支上啦
2
3
4
5
6
7
8
9
- cherry-pick 来实现
git checkout name-of-the-correct-branch
# 抓取 master 分支上最新的那个 commit
git cherry-pick master
# 然后删掉 master 上的那个 commit
git checkout master
git reset HEAD~ --hard
2
3
4
5
6
- 撤销 commit
# 先找到你想撤销的那个 commit
git log
# 如果在第一屏没找到你需要的那个 commit,可以用上下
# 箭头来滚动显示的内容,找到了以后记下 commit 的
# hash 值
git revert [刚才记下的那个 hash 值]
# git 会自动修改文件来抵消那次 commit 的改动,并创
# 建一个新的 commit,你可以根据提示修改这个新 commit
# 的信息,或者直接保存就完事了
2
3
4
5
6
7
8
9
# 撤销某个文件改动
# 找到文件改动前的那个 commit
git log
# 如果在第一屏没找到你需要的那个 commit,可以用上下
# 箭头来滚动显示的内容,找到了以后记下 commit 的
# hash 值
git checkout [刚才记下的那个 hash 值] -- path/to/file
# 改动前的文件会保存到你的暂存区
git commit -m "这样就不需要通过复制粘贴来撤回改动啦"
2
3
4
5
6
7
8
9
10
- 远程仓库分支变更名称,本地需要同步变更
# master为旧名,main为新名
git branch -m master main
# 重命名
git fetch origin
# 拉取远程仓库
git branch -u origin/main main
# 设置分支名
git remote set-head origin -a
# 设置默认分支
2
3
4
5
6
7
8
9
Git下载:https://git-scm.com/ (opens new window) Git文档:https://git-scm.com/docs (opens new window)