Git用法总结

Git用法总结
分区
工作区🧱:这是平时编辑代码的地方,也就是的项目文件夹。
暂存区🗃️:当使用 git add
把修改加入暂存区时,Git 会把这些改动标记为准备提交的状态。
本地仓库📦:当运行 git commit
后,改动就会被记录在本地仓库中(也就是 .git
目录下的历史记录)。
远程仓库🌐:通常托管在 GitHub、GitLab、Gitee 等平台上。通过 git push
可以将本地提交同步到远程仓库。
HTTP和SSH
HTTP对应用户名和令牌。令牌通过Settings-Developer Settings-Personal access tokens-Tokens(classic)生成。
SSH对应SSH密钥。密钥通过ED25519或者RSA算法生成都可以。
ED25519:
$ ssh-keygen -t ed25519 -C "my_linux_laptop"
#密钥保存地址,按回车就行
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
RSA:
#生成2048位密钥
$ ssh-keygen -t rsa -b 2048 -C "email@example.com"
#密钥保存地址,按回车就行
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
生成后,以ED25519为例,在主文件夹/.ssh/id_ed25519.pub
中复制内容,粘贴在Github-settings-SSH and GPG keys-Authentication keys
中。
新建项目
远端新建项目:
从远端拉空项目
命令行
本地通过新建一个库然后SSH关联到远端:
git init
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:hljmssjg/git_blog.git
git push -u origin main
IDE
实战中用Jetbrains的IDE可以通过新建-通过版本控制的项目...
直接从远端拉项目,不用输入这些乱七八糟的命令:
从本地推代码到远端空项目(推荐)
命令行
可以将本地现有的代码库ssh推到远端。
git remote add origin git@github.com:hljmssjg/git_blog.git
git branch -M main
git push -u origin main
IDE
实战中用Jetbrains的IDE可以直接通过定义远程、提交并推送:
提交代码
任务描述:完成需求A后使用命令行向远端main分支提交。
命令行:
git pull
git status
git add .
git commit -m "A"
git status
git push origin main
IDE实战:
-
更新项目:
-
将文件添加到git:
- 提交并推送
- 结果:
创建开发分支
任务描述:在当前的main分支上,新建开发分支dev
,并开发任务B。
常用命令:
#查看所有分支
git branch
#创建新分支
git branch <branch-name>
#切换分支
git checkout <branch-name>
#创建并切换分支
git checkout -b <branch-name>
实战:
#创建并切换分支
git checkout -b dev
#开发完成后
git status
git add .
git commit -m "Task B"
git status
git push origin dev
实战(IDE):
结果:
Fetch
任务描述:我和同事一起在dev
分支上基于B节点进行开发。同事先提交了C,我需要把同事的提交拉下来看看他更新了什么,但不想影响我本地的代码。
# 确保在 dev 分支
git checkout dev
# 从远程同步最新的主分支
git fetch --prune
实战IDE:
这个提取对应的是高级的fetch操作:
git -c credential.helper= -c core.quotepath=false -c log.showSignature=false fetch origin --recurse-submodules=no --progress --prune
结果:
显示有一个传入提交:
Merge
任务描述:我和同事一起在dev
分支上基于B节点进行开发。同事先提交了C,我把同事的提交拉下来看了一下,现在想把我的提交D和他的合并:
# 确保在 dev 分支
git checkout dev
# 从远程同步最新的主分支
git fetch --prune
# 合并
git merge origin/dev
手动打开冲突文件,当前头节点HEAD的内容(也就是dev
)和远端的origin/dev
分支有冲突了。
<<<<<<< HEAD
D
=======
C
>>>>>>> origin/main
这里选择保留dev
的内容,把其他的删干净.
把处理好冲突的文件添加到提交区并提交,完成合并操作:
git add .
git commit -m "E"
IDE实战:鼠标右键远程提交,选择将“origin/dev”合并到“dev”中,或者使用“合并”拉入“dev”都可以。
解决冲突:
编辑提交信息为E:
推送到远端:
Pull
git pull = 先git fetch ,再 git merge 或者git rebase
任务描述:我和同事一起在dev
分支上基于E节点进行开发。同事先提交了F,我把同事的提交拉下来直接把我的提交G和他的合并。
如果没有冲突,那下列方法将会直接成功:
git checkout dev
git pull
如果有冲突,需要显示指定如何处理冲突:
#用merge
git pull --no-rebase
#用rebase
git pull --rebase
#只快速合并
git pull --ff-only
对于IDE,可以直接使用更新项目:
这段过程等价于:
git -c credential.helper= -c core.quotepath=false -c log.showSignature=false fetch origin --recurse-submodules=no --progress --prune
git -c credential.helper= -c core.quotepath=false -c log.showSignature=false merge origin/dev --no-stat -v
git -c credential.helper= -c core.quotepath=false -c log.showSignature=false add --ignore-errors -A -f --sparse -- main.py
git -c credential.helper= -c core.quotepath=false -c log.showSignature=false commit -F /home/jiangeng/WebstormProjects/git_blog/.git/MERGE_MSG -- [dev 6f5c216] Merge remote-tracking branch 'origin/dev' into dev
结果:
Rebase
git rebase
可以压缩提交,也可以合并代码。
压缩提交
命令行
任务描述:当前develop/terminal
分支又开发了CM1、CM2、M。使用命令行进行rebase压缩提交,保持提交的干净整洁。
#查看最近的五次提交
git log --oneline -n 5
#压缩最近的三次提交
git rebase -i HEAD~3
pick
CM1为基,squash
CM2 和M。
写commit:
结果:
注意,如果远程Task CM1、CM2和M都推送过去了,那这个时候直接push会被拒,因为用 git rebase
对本地分支 develop/terminal
进行了“压缩提交”,这就相当于改写了分支的历史。Git 默认不允许把历史被改写的分支强行推送到远程,除非明确表示想覆盖远程的旧历史。
解决办法:
#我知道我改了历史,只要远程分支没有被别人改,我就强推。
git push --force-with-lease
但是这样做,共同开发的队友就需要抛弃掉本地的提交,强行拉一下远程保持一致。
git fetch origin
git checkout develop/terminal
git reset --hard origin/develop/terminal
所以rebase最好是在自己一个人的feature分支里用。
IDE
任务描述:当前develop/IDE
分支又开发了CN1、CN2、N。使用命令行进行rebase压缩提交,保持提交的干净整洁。
选中Task CN2和Task N,点击压缩按钮。然后启动变基。
编辑commit内容,推远端时使用强制推送:
结果:
变基分支
任务描述:我和同事一起在dev
分支上基于H节点进行开发。同事先提交了I,我把同事的提交拉下来看了一下,现在想把我的提交J和他的合并。
# 确保在 dev 分支
git checkout dev
# 从远程同步最新的主分支
git fetch --prune
# 合并
git rebase origin/dev
IDE实战:
最终推送到远端后结果:
rebase是没有额外的线的,整个git praph简洁美观,但是会更改提交历史。
在实战中,本地feature分支用rebase + squash
保持提交整洁。多人协作的 dev
、main
等最好用merge
。
删除分支
命令行
#删除本地
git branch -d develop/terminal
#删除远端
git push origin --delete develop/terminal
#更新git pragh
git pull
IDE
最终的git graph:
撤销提交
撤销commit
分几种情况:
#commit了还没push,需要撤销提交并保留代码修改
git reset --soft HEAD~1
#commit了还没push,需要撤销提交,同时取消暂存区中代码(但保留代码改动)
git reset --mixed HEAD~1
#commit了还没push,需要撤销提交并清除代码改动
git reset --hard HEAD~1
#改commit内容
git commit --amend
IDE实战:
假设本地有一个useless commit
复制想要回退的commit的修订号:
点击重置HEAD:
将修订号粘贴在为提交这一栏中,设置重置类型(以hard为例)。可以点验证看看是不是那个想要回去的commit:
重置后:
也直接点击提交右键直接操作:
撤销提交对应soft,删除提交对应hard,编辑提交信息对应git commit --amend
。
假如已经push到远端了,如果是自己一个人开发的分支,直接git reset
然后强推git push -f
就好。
如果是多人协作,最好用revert
:
#获取commit的hash
git log --oneline
#revert 对应commit
git revert <commit_hash>
也可以直接右键选择还原提交:
结果:
会在git graph里明确“还原”这个操作,不会改变git history。
撤销merge
#检查log,查看对应的hash值
git log --oneline
#根据hash查看合并的情况
git show 89f5b17
可以看到这是HEAD -> dev fb7222f
和origin/dev e48978b
的合并。
使用revert
选择保留HEAD的提交:
# 对origin/dev做一次反向提交
# 以 第1个 parent 为主干,撤销合并时引入的另一个 parent(e48978b) 的变更
git revert -m 1 89f5b17
或者如果分支只有自己开发,那么选择reset
并强推:
#直接回到合并前的状态,抛弃之后的提交
git reset --hard fb7222f
git push -f
IDE只支持简单的撤销操作,对于这种撤销merge的操作要用命令行。
那假如我又反悔了,不想revert“H”
,怎么办?可以撤销这次撤销。
撤销rebase
远程先根据G提交了H,本地根据G提交了I,然后rebase到远程H。
如果想要撤回rebase,两种方法:
#使用ORIG_HEAD
git reset --hard ORIG_HEAD
#或者根据git reflog查看:
0dd2433 (HEAD -> dev, origin/dev) HEAD@{8}: rebase (continue): I
9740a81 HEAD@{9}: rebase (start): checkout refs/remotes/origin/dev
bf45968 HEAD@{10}: commit: I
#reset
git reset --hard HEAD@{10}
结果:
总结一句话:创建自己的分支随便瞎折腾。和别人分支合并要慎重。
PR/MR
PR对应github,MR对应gitlab,本质都是合并请求。
开启代码审查
添加经典分支保护规则:
这样设置即使是管理员也无法推送。
本地将dev合并到main后推送到远端:
无论是推送还是强推,都会被拒绝。这里就需要提PR。
提PR
首先确保个人分支已经被推送到远端,然后Github-pull requests-New pull request
选择分支:
- base branch:目标分支(通常是
main
或master
)。 - compare branch:开发分支(如
dev
)。
选择Create Pull request。
然后选择另一个人来审批:
此时审核人的帐号中,可以添加评论:
审核代码,然后批准:
Merge 这个PR:
最终主帐号上会显示PR成功,且会收到邮件提示: