文章目录
git 笔记
git 重要知识点
变更工作区------ git checkout
变更暂存区------ git reset
# git 重命名文件
git mv readme readme.rd
# git 删除 file
git rm 'file'
git 配置
git config --global/local/system user.name/email
--global # 对所有仓库有效
--local # 仅对当前仓库有效
--system # 对所有登录用户有效
.git folder
下图为 .git 文件夹中比较重要的文件夹和文件的结构和意义:
HEAD 指针
1 git HEAD
HEAD
指针可以指向一个分支,也可以指向 commit,指向 commit 时为分离头指针状态;
几个和 HEAD
相关的 git 命令:
git diff HEAD HEAD^ (HEAD^^)
or
git diff HEAD HEAD~1 (HEAD~2)
HEAD^
为 HEAD
的上一次 commit
2 恢复暂存区为HEAD状态
需求场景:将文件add到暂存区之后不想提交暂存区的内容
# 清除暂存区所有变更,提交到暂存区的变更将回到工作区
git reset HEAD
# file1 file2 为 add 到暂存区的文件
git reset HEAD -- 'file1' 'file2'
3 恢复工作区为暂存区状态
需求场景:add 文件到暂存区之后,工作区继续开发,发现工作区的变更不如暂存区,需要恢复暂存区的某些文件到工作区
# file 为 add 到暂存区的文件
git checkout -- 'file'
4 清空工作区
git checkout .
git commit
1 提交
# 提交修改
git commit -m 'message'
2 修改上次/某次 commit 的 message
# 修改最近一次提交的 message
git commit --amend
# 修改某次 commit 的 message,commit_id 应该为需要修改的 commit 的上一级 commit,之后会进入选择操作,改第一行为 reword/r,保存退出,然后会自动进入修改 message 的界面,修改 message,保存退出即可
git rebase -i 'commit_id'
3 合并连续的几次 commit
# commit_id 为需要合并的几次 commit 中最靠前的 commit 的上一个,即将几次 commit 合并commit_id 上,-i 表示进入选择操作交互
# 之后第一个选 pick,后面几次需要合并的选择 squash/s,即将这几次合并到第一次,然后保存退出,
# 之后会跳转到合并提交 commit 的页面,添加合并 log 即可
git rebase -i 'commit_id'
4 合并不连续的几次 commit
git rebase -i 'commit_id'
# commit_id 为需要合并的几次 commit 中最靠前的 commit 的上一个进入选择操作交互后,第一个选 pick,将需要合并的 commit copy 到将要合并到的 commit 的下面,改变状态为 squash/s,并删除刚刚复制的原 commit 记录,保存退出后会跳转到合并提交 commit 的页面,添加合并 log 即可。
- 若需要合并到的 commit 已经为根 commit,则选择该 commit 作为
rebase -i
的commit_id,进入 state 修改界面之后,先将最老的 commmit 拷到顶部,然后同上述操作… - 多个 commit 合并只能将新的 commmit 合并到老的commmit。
5 消除最近几次 commit
# 这个命令会将工作区和暂存区回退到 commit_id 这个状态,会消除这个 commit 之后的记录!
git reset --hard 'commmit_id'
git log
最简单的看log的命令:git log
,后面可带的参数:
--one line # 简介显示 log,不包含修改者信息
--all # 查看所有分支的 log
--n4 # 显示最近的 4 条记录
--graph # 以 tree 的方式查看 commit 的变化(多分支时好用)
以上几个参数可以同时使用!!
git diff
1 查看暂存区和HEAD的差异
git diff add 'file'
git diff --cached
2 查看暂存区和工作区的差异
git diff add 'file'
git diff
注:
git add
之后,再修改工作区,则git diff
命令查看的是工作区和暂存区的差异。
3 查看两个分支/commit之间的差异
# 查看两个分支最新 commit 间的差异,会列出所有文件的差异
git diff 'branch1' 'branch2'
# 查看两个分支 file 文件的差异
git diff 'branch1' 'branch2' -- 'file'
# 查看两个/同一个分支的 commit 间的差异
git diff 'branch1_commit' 'branch2_commit' -- 'file'
git tag
tag 相关操作,包括:
# 查看tag
git tag
# 可以查看 v0.1. 开头的 tag,-l 为通配符,或使用 --list
git tag -l "v0.1.*"
# 打 tag,-a 添加附注标签,-m 为 tag 添加信息
git tag -a v1.0 -m "tag v1.0"
# 查看 tag v1.0 的信息和提交信息
git show v1.0
# 为过去的提交打 tag
git tag -a v1.0 commit_id(839b19)
# 推送 tag v1.0 到远程
git push origin v1.0
# 一次性推送多条 tag 到远程
git push origin --tags
# 删除本地 tag v1.0
git tag -d v1.0
# 删除远程标签
git push origin --delete v1.0
git stash 操作
场景:开发过程中,工作区有修改,临时有新任务需要处理,需要将工作区的改动保存,等任务处理完之后在进行先前的开发工作
# 将工作区和暂存区的改动先保存起来,清空工作区
git stash
# 查看保存堆栈的信息
git stash list
# 将保存在 stash 堆栈的改动返回到工作区,stash 中的保存记录还在,多条 stash 记录的话需要加 id
git stash apply (stash_id)
# 将保存在 stash 堆栈最顶层的改动返回到工作区,stash 中的保存记录删除
git stash pop
# 删除 stash 第一个记录
git stash drop stash@{0}
# 清空 stash 所有记录
git stash clear
git branch 操作
常见操作
# 查看所有分支
git branch -va
# `-r`,查看远程分支
git branch -r
# 切换分支
git checkout 'branch_name'
# 新建本地分支
git checkout -b 'branch_name'
# 从 commit_id 新建本地分支
git checkout 'commit_id' -b 'branch_name'
# 删除本地分支,-d 报错,-D 强制删除
git branch -d/-D 'branch_name'
# 删除远程分支
git push origin --delete 'origin_branch_name'
# 显示两个分支有差异的所有文件
git diff branch1 branch2 --stat
# 显示指定文件的详细差异
git diff branch1 branch2 fileName(带路径)
# 显示出所有有差异的文件的详细差异
git diff branch1 branch2
从远程拉取分支到本地
# 方法一:采用此种方法会自动切换到本地新的分支,并在本地分支会和远程分支建立映射关系。
git checkout -b 本地分支xx origin/远程分支xx
# 方法二:采用此种方法不会自动切换到本地新的分支,也不会在本地分支会和远程分支建立映射关系。
git fetch origin 远程分支xx:本地分支xx
.gitignore file
# .idea 后缀的文件和 .idea 文件夹及下面的文件都不会被 add
*.idea
git仓库备份
1 常用传输协议
常用传输协议有:
- 哑协议传输进度不可见,智能协议进度可见;
- 智能协议传输速度快;
远端仓库
# 备份本地仓库,--bare不带工作区的 clone,用于本地 backup
git clone --bare 'path/.git' 'backup.git'
# 查看远端仓库
git remote -v
# 添加远端仓库
git remote add 'remote_repo_.git'
sample:
# 使用哑协议添加远程仓库
git remote add 'name' /d/Work/Learning/AndroidLearning/backtest/zhineng.git
# 使用智能协议添加远程仓库
git remote add 'name' file:///d/Work/Learning/AndroidLearning/backtest/zhineng.git
# 'd/Work/Learning/AndroidLearning/backtest/zhineng.git' 是备份的裸仓库, name 为命名远端仓库名称
添加远端仓库,既可以是github这样的远端,也可以是本地backup的仓库作为远端
拉分支:
# clone github 上的项目
git clone https://github.com/cgwang1580/OpenGLES3_NDK.git
# clone github 项目制定分支 dev_native_mediacodec
git clone -b dev_native_mediacodec https://github.com/cgwang1580/OpenGLES3_NDK.git
推送:
# 推送本地 dev_test 分支到远程 dev_test 分支
git push origin dev_test:dev_test
从远端更新
# 从远程分支 main 拉取和本地 test 分支合并
git pull origin main:test
# 从远程分支 main 拉取和本地当前分支合并
git pull origin main
Github新建仓库
新建一个本地仓库并与远端仓库连接的步骤:
-
Github创建新的仓库,赋值仓库链接LINK(https://…)
-
本地
git init
创建一个本地git仓库 -
使用如下命令连接:
git add . git commit -m 'log' # 添加远程仓库 git remote add origin ${LINK} # 推送本地仓库至远程 git push -u origin master # 后续本地新建分支推送至远程 local_branch--本地分支名 origin_branch--远程分支名 git push origin local_branch:origin_branch
git 常见问题处理方法
git 撤销 merging 状态
有时错误执行 merge 命令导致出现一堆错误编码,如果需要撤销 merging 状态,可以使用如下方法:
# 恢复到最新一次 commit 状态,清除工作区
git reset --hard HEAD
恢复被删除但 add 到暂存区的文件
有时候,某个文件已经add到暂存区,但是这个本地文件在之后的开发中被删除了,如何恢复仓库中的该文件?
此时直接
git check out
是不行的,这个时候需要先用git reset
命令,先将删除的文件找回来,然后再git check out --[file]
git clone 速度太慢
由于网络问题,git clone
速度巨慢,可以使用代理方式:
首先查看本地 socks5 代理的本地监听端口号:1080
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCckbUKq-1608562431714)(./resource/local_ss_port.png)]
接着使用如下命令设置只针对 Github 的代理:
git config --global http.https://github.com.proxy socks5://127.0.0.1:1080
git config --global https.https://github.com.proxy socks5://127.0.0.1:1080
设置之后可以使用如下命令查看是否设置成功:
git config -l
如果需要清除代理,则用如下命令:
git config --global --unset http.https://github.com.proxy
git config --global --unset https.https://github.com.proxy
同样也可以 git config -l
查看是否已经清除。
注意:LFS 大文件与代理不能共存,不建议将大文件上传到 Github。
git 拉分支处理临时问题
参考本文:分支 - 分支的新建与合并
有几个注意事项:
- 新建分支处理问题,当需要切换分支时需要先将本次改动下提交或者 stash 一下,否则会出现头指针分离的情况
分离头指针出现即解决方法
仓库 log:
$ git log --oneline
e2f7cb3 (HEAD -> master) update2
420c125 update
699507e add 1.txt
当用户执行
git checkout <commit_id>
执行命令之后会有如下提示,提示当前处在分离头指针状态,在这个状态下所做的提交不会提交到正常的分支下:
$ git checkout 699507e
Note: switching to '699507e'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 699507e update
使用 git status
可以看出头指针位于 699507e
的位置,如果要回到分支正常状态,直接执行git checkout master
即可。
如果在头指针分离状态下进行了 git add
和 git commit
的操作,会得到如下提示:
$ git commit -a -m 'update for head detched'
[detached HEAD ab6abde] update for head detched
1 file changed, 1 insertion(+)
ab6abde
为分离头指针状态下提交的 commit id,这个 commit id 回到 master
分支是看不到的,在 master
分支使用 checkout ab6abde
找回代码。这种情况下,切换到 master
分支有如下提示:
$ git checkout master
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
ab6abde update for head detched
If you want to keep it by creating a new branch, this may be a good time
to do so with:
git branch <new-branch-name> ab6abde
Switched to branch 'master'
此时可以考虑
git branch <branch_name> ab6abde
即基于刚刚在分离头指针状态下作的修改的拉取新的分支。
基于当前分支改动新建分支
比如我在 A 分支做了一些修改,现在由于某种原因不能直接在 A 分支上提交修改,希望将这个修改提交到新的分支便于继续开发,可以有两种简单的做法完成这一需求。
- 第一种方法
不需要在 A 分支做 commit,只需要在 A 分支新建 B 分支,然后切换过去。这个时候你会发现修改的东西在 A,B 分支都有。这个时候在 B 分支 commit,那么这些修改保留在 B 分支上,再切换到 A 分支上会发现修改都没有保留下来。
- 第二种方法
使用 git stash
将 A 分支暂存起来,然后在某一个分支(如 master 分支)新建一个分支 B,然后在 B 分支上使用 git stash pop 将修改弹出到 B 分支上,然后这些修改就在 B 分支上了。