一.Git 基础
1.mac 安装 git
$ brew install git
### 2.查看 git 版本
git--version
3.git 的基本流程
4.git-commit 类别
type 用于说明 commit 的类别
- feat:新功能(feature)
- fix:修补 bug
- docs:文档(documentation)
- style:格式(不影响代码运行的变动)
- refactor:重构(即不是新增功能,也不是修改 bug 的代码变动)
- test:增加测试
- chore:构建过程或辅助工具的变动
- feat:新功能(feature)
- perf: 性能 (提高代码性能的改变)
- ci: 对 CI 配置文件和脚本的更改
- revert: 撤销提交
5.GIT 人员
- owner 是最高权限的,谁去创建组,这个组就被谁拥有,它可以开除管理员,但管理员无法操作 owner 的角色。
- maintainer(管理员-只是具备 sudo 权限的用户)管理员一般是给小组的组长,或者是给产品线的总监设定。
- developer 是干活的人,就是写代码的程序员,可以进行代码的上传以及代码的下载,不能下载其他的组内的代码,只能下载它们组的代码。
- repoter:比如现在有需求,其他组的大牛到我们组过来指导工作,要审视我们的代码,人家就提出需要一个权限,我不能给它 developer 因为它会改你代码,其他组的人不能改我们组的代码,所以就给一个 repoter 权限,他只能看,只读权限。
- guest:不用看,匿名,直接去掉。一般出现在从 ldap 中把离职人员的信息删掉,再去 gitlab 查这个人的时候,它就是一个 guest 用户(匿名)需要再到 gitlab 把它删掉(不删也没事)。
二.git 命令
1.常用命令
#通过链接clone代码
git clone xxx
#初始化本地库
git init
#将改动文件加入暂存区
git add .
2.branch 相关
#查看本地所有分支
git branch
#查看所有分支(本地+远程)
git branch -a
#查看远程所有分支
git branch -r
#强制删除本地库develop
git branch -D develop
#删除本地库develop
git branch -d develop
#建立一个新的本地分支dev_3,并切换到 dev_3 分支
git checkout -b dev_3
#将分支dev与当前分支进行合并
git merge origin/dev
#切换到本地dev分支
git checkout dev
#从主分支dev_3创建branch_3分支
git branch branch_3 dev_3
#将branch_3重命名为branch_5
git branch -m branch_3 branch_5
#切换到branch_1.0/master分支
git checkout branch_1.0/master
#切换到上一个分支
git checkout -
#建立追踪关系,在现有分支branch与指定的远程分支remote-branch之间
git branch --set-upstream [branch] [remote-branch]
3.tag 相关
#列出所有tag
git tag
#新建一个tag并且指定commit,tag名称最好和branch名称分开,可以加个-tag
git tag [tag] [commit]
git tag v2.0.2.9_2023-08-17 5ae44897;
#提交所有tag
git push --tags
git push [remote] --tags
#新建一个tag在 当前 commit
git tag [tag]
#查看tag信息
git show [tag]
#提交指定tag
git push [remote] [tag]
#新建一个分支,指向某个tag
git checkout -b [branch] [tag]
git checkout -b v2.0.2.9 v2.0.2.9_2023-08-17
#删除本地tag
git tag -d [tag]
git tag -d v2.0.2.9_2023-08-17
#删除远程tag
git push origin :refs/tags/[tagName]
git push origin :refs/tags/v2.0.2.9_2023-08-17
4.stash 使用
#保存当前进度;
#git stash命令的作用主要如果当前分支所做的修改你还不想提交,但又需要切换到其他分支去查看,就可以使用git stash保存当前的修改。
git stash
#看已经保存的历史记录
git stash list
#重新应用最近的
git stash apply
#重新应用某个已经保存的进度,但不删除进度记录
git stash apply stash@{2}
#将文件从临时空间pop下来
git stash pop
#重新应用某个已经保存的进度,并且删除进度记录
git stash pop stash@{2}
#删除某个历史进度
git stash drop stash@{2}
#删除所有的历史进度
git stash clear
5.status 相关
#显示仓库文件状态
git status
#以极简的方式显示文件状态(下面是显示内容解析):git status -s
A:本地新增的文件(服务器上没有)
C:文件的一个新拷贝
D:本地删除的文件(服务器上还在)
M:红色为修改过未被添加进暂存区的,绿色为已经添加进暂存区的
R:文件名被修改
T:文件的类型被修改
U:文件没有被合并(你需要完成合并才能进行提交)
X:未知状态(很可能是遇到git的bug了,你可以向git提交bug report)
?:未被git进行管理,可以使用git add fileName把文件添加进来进行管理
#看你commit的日志
git log
#显示commit历史,以及每次commit发生变更的文件
git log --stat
#搜索提交历史,根据关键词
git log -S [keyword]
#显示过去5次提交
git log -5 --pretty --oneline
#显示某个日期之前的记录,如git log --before=“2020-01-01”(包含2020年1月1号的记录)
git log --before=“yyyy-MM-dd”
#显示某个日期之后的记录,如git log --after=“2020-01-01”(包含2020年1月1号的记录)
git log --after=“yyyy-MM-dd”
#查看某个人的提交记录
git log --author='name'
#显示前n条记录
git log -n
#显示所有提交过的用户,按提交次数排序
git shortlog -sn
#显示指定文件是什么人在什么时间修改过
git blame [file]
#退出查看
按q
#显示当前分支的最近几次提交
git reflog
6.暂存区
#加入到暂存区
git add .
#查看已经被提交的
git ls-files
#从git中删除指定文件
git rm 文件名(包括路径)
#移除文件(只从暂存区中删除)
git rm --cached a.a
#强行移除修改后文件(从暂存区和工作区中删除)
git rm -f 111.sql
#查看尚未提交的更新
git diff --cached
git diff --staged
#恢复暂存区的指定文件到工作区
git checkout [file]
#恢复暂存区的所有文件到工作区
git checkout .
7.commit 相关
#提交并且加注释
git commit -am "init"
#添加commit信息
git commit -m "This is the message describing the commit"
#查看历史commit
git reflog
8.remote 相关
#查看关联的远程地址
git remote -v
#将文件给推到服务器上
git push origin master
#显示远程库origin里的资源
git remote show origin
#切换到远程dev分支
git checkout --track origin/dev
#查看远程库
git remote show
#从服务器上将代码给拉下来
git clone git://github.com/schacon/grit.git
#关联仓库
git remote add origin git@github.com:username/Hello-World.git
#相当于是从远程获取最新版本到本地,不会自动merge
git fetch
#删除远程分支
git push origin --delete [remote-branchname]
#下载远程仓库的所有变动
git fetch [remote]
#显示所有远程仓库
git remote -v
#显示某个远程仓库的信息
git remote show [remote]
#从远端库更新内容到本地
git pull
#取回远程仓库的变化,并与本地分支合并
git pull [remote] [branch]
#上传本地指定分支到远程仓库,如:git push origin master(同步到远程master仓库)
git push [remote] [branch]
#删除远程[branch]分支
git push origin --delete dev
9.reset 相关
#回退到上一个版本
git reset --hard HEAD^
#回退到前3次提交之前
git reset --hard HEAD~3
#回退到指定提交版本
git reset --hard 15c8682d
#强制提交,因为远程已经发生了变化,如何合并就会出现问题
git push -uf origin dev
还有一个比较笨拙但是不会出错的方法,先根据某个提交建立分支,再进行处理
10.对比 differ
#查看尚未暂存的更新
git diff
#显示本地分支和master对比
git diff master
#显示本地与远程feature/v1.8.5.1 对比的不同点
git diff origin/feature/v1.8.5.1
#显示某次提交的元数据和内容变化
git show [commit]
#显示某次提交发生变化的文件
git show --name-only [commit]
#显示某次提交时,某个文件的内容
git show [commit]:[filename]
11.查询关键词
#从当前目录的所有文件中查找文本内容
git grep “陈哈哈”
#在某一版本中搜索文本
git grep “陈哈哈” v2.5
12.squash 使用
Squash 指令通常用于将一系列相关的提交合并成一个单独的提交,以便更好地组织提交历史。例如,当你在开发一个新功能时,可能会提交多个小的修改,这些修改都是为了实现同一个目标。在将这些修改合并到主分支之前,可以使用 Squash 指令将它们合并成一个新的提交,以便更好地描述这个新功能的实现过程。
使用 Squash 指令的步骤如下:
- 在分支上进行一系列提交。
- 切换到需要合并这些提交的分支上。
- 运行 git rebase -i commit,其中commit是需要合并的提交序列中的最早的提交。
- 在编辑器中打开交互式 rebase 的 TODO 文件。
- 将需要合并的提交行的前面的 pick 替换为 squash。
- 保存并关闭编辑器。
- 在编辑器中打开提交信息文件,编辑新的提交信息。
- 保存并关闭编辑器。
- 运行 git rebase --continue。
- 如果出现冲突,解决冲突并运行 git add 命令,然后运行 git rebase --continue。
- 当 rebase 完成后,使用 git log 命令查看提交历史,确认新的提交已经添加到提交序列中。
需要注意的是,使用 Squash 指令合并提交时,会对提交历史进行修改。因此,在合并提交之前,最好先备份当前分支的提交历史,以便在需要时可以恢复到之前的状态。
git merge 和 git merge – –squash 的区别:
squash 是将其他分支内容合并和重新进行一次提交封装。这样方便我们对主分支的管理。dev 分支开发可能会随心所欲的进行提交已经对提交日志的细小记录。但是对于主分支根本不关心这些或者需要进行一些提交信息的规则定义。这时候我们可以 squash 先合并内容然后在重新一次性提交
- git merge:直接将其他的提交记录合并进来。
- git merge – –squash:是提交内容的合并。
- squash 可以合并提交备注
如何将5次合并为1次?
主要命令
#查看提交日志
git log
#找到要合并的最先提交的id
git rebase -i f83d9306
#继续编辑
git rebase --edit-todo
#编辑合并日志
git rebase --continue
#跳过
git rebase --skip
#推送
git push -f
#查看提交日志
git log
可以看到最新的在最下面,最上面的要选为 pick,下面的为 s,表示合并
13.cherry-pick
作用:把指定提交合并到指定分支
需求:把 dev 分支的 commit2 提交合并到 master 分支
实现:
git checkout master
git cherry-pick commit2
14.git 统计提交信息
1.统计个人
git log --author="327782001@qq.com" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -
2.统计所有人
git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done
3.统计某一段时间
git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --since='2017-01-01' --until='2022-03-05' --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done
4.统计整个项目
git log --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -
5.统计用户提交次数
自 2017-01-01 号以来的提交次数:
git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --no-merges --since='2017-01-01' | grep -e 'commit [a-zA-Z0-9]*' | wc -l;done
三.常用配置
1.全局信息
git config -l
git config --list
2.gitlab 分支权限
3.Git 全局设置
git config --global user.name "檀越剑指大厂"
git config --global user.email "327782001@qq.com"
4.设置网络代理
#cmd输入一下设置:
git config --global http.proxy http://127.0.0.1:1080
git config --global https.proxy http://127.0.0.1:1080
#查看代理设置:
git config --global -l
#设置本地代理
set http_proxy=http://127.0.0.1:1080
set https_proxy=http://127.0.0.1:1080
#使用完后重置即可
git config --global --unset http.proxy
git config --global --unset https.proxy
5.添加忽略文件
创建.gitignore 文件
target/
.settings/
.idea/
.mvn/
*.classpath
*.options
*.project
四.GIT 分支
1.Git 分支模型
经典 Git-Flow
两个常驻分支(master & develop),代码开发都在临时分支上进行。需要做好日常管理(如及时删除已合并的临时分支),否则容易导致混乱。
2.主要分支
- master 主干分支,稳定版代码,生产环境版本代码 (prd 正式环境; Tag)
- develop 主干分支,开发版代码,dev/qa 环境版本代码 (dev、qa 环境)
- feature 功能开发分支 (dev 环境)
- release 发布分支, 不允许直接修改代码 (uat 环境)
- hotfix 修复分支 (qa、uat、prd 环境)
3.临时分支
1 版本功能分支(feature)
从 develop 分支创建,用于版本功能开发,完成后要合并回 develop 分支
2 个人特性分支(feature)
从 feature 分支创建,用于个人版本功能开发,完成后要合并回 feature 分支
3 稳定分支(release)
从 feature 功能分支创建,用于预发布环境进行测试及产品验证,完成后要合并回 develop 和 master 分支
4 修复分支(hotfix)
从 master 分支创建,用于预发布 / 生产环境上的 Bug 修复,完成后要合并回 develop 和 master 分支
4.分支清理
1 谁创建谁负责清理
2 临时分支在发布生产环境后清理
5.项目分支
1 新项目需从原工程 gitlab 上 fork, 不允许 checkout 新分支
6.命名规则
- 创建版本功能分支,名称要以 feature/ 开头,加上产品迭代版本号;如:feature/1.1.3
- 创建个人特性分支,名称要以 feature/ 开头,加上产品迭代版本号,加上个人标识;如:feature/1.1.3-yy
- 创建发布分支,名称要以 release/ 开头,加上产品迭代版本号;如:release/1.1.3
- 创建 Bug 修复分支,名称要以 hotfix/ 开头,加上已发布产品迭代版本号 (即上个版本号);如:release/1.1.2
- 创建标签 Tag,名称要以 v 开头,加上发布版本号和日期;如:v1.1.3-2022-01-26
五.常见问题
1.代码如何回滚?
- 使用 reset,不建议用这种方式,除非对 git 非常熟练和了解,且遇到强制覆盖错误能知道如何解决,优点快速(记得备份被覆盖的分支,其实备份的过程就是第二种方式)
- 使用新建分支的方式,安全快捷,不会冲掉自己和别人的代码,能快速解决分支冲突,代码冲突问题,保证版本正常上线.commitid 为要回退到的提交记录,建议使用这种方式
git checkout -b 新分支名 <commitid>
2.如何找回删除的分支?
使用场景:
- 自己的代码被别人覆盖了;
- 自己的代码被自己覆盖了;
- 在某个分支开发,还没合并到测试分支,开发分支删除了,代码没了,如何找回代码;
#查看历史提交记录,可以翻页
git reflog --date=iso
#需要自己看注释找回分支,一定要找带commit的
git checkout -b 新分支名 <commitid>
3.删除文件
#删除./idea 删除某个目录
git rm --cached -r .idea
4.设置合并方式
解决 git 未指定冲突处理方法的问题
hint: Pulling without specifying how to reconcile divergent branches ishint: di_Rudon
git config pull.rebase false
5.dev 合并到 master
1.dev 运行
#查看当前分支
git branch -a
#切换到 dev
git checkout dev
#暂存所有更改
git add .
#将修改 提交到本地仓库,双引号内是提交的备注信息
git commit -m "更改的备注信息"
#拉取远程 dev 分支代码
git pull origin dev
#拉取远程 dev 分支代码
git pull origin master
#将本地修改的代码提交到远程的 dev 分支上
git push origin dev
#切换到 master 分支
git checkout master
2.master 运行
#将 dev 分支的代码合并到 master 上
git merge dev
#将当前的更改推送到远程的 master 分支上
git push origin master
执行完以上命令,此时 dev 分支与 master 分支的代码已同步。
6.退出 git 的编辑
- 直接按 q 键
- 使用 esc,在用:q
7.pull 失败
git config pull.rebase false
8.当前分支从哪里拉的?
git log --oneline --graph --decorate
9.每次需要输入密码
解决办法:
进入到项目目录,输入:
git config --global credential.helper store
然后你会在你本地生成一个文本,上边记录你的账号和密码。当然这些你可以不用关心。
然后你使用上述的命令配置好之后,再操作一次 git pull,然后它会提示你输入账号密码,这一次之后就不需要再次输入密码了。
六.merge 和 rebase
1.介绍
merge
和 rebase
都是 Git 中用于合并分支的命令,但它们的合并方式和结果略有不同。
merge
命令的作用是将两个分支合并成一个新的提交,新的提交有两个父提交。这种合并方式会创建一个新的提交,它包含了被合并的分支的所有更改。这样就可以将两个不同的分支中的代码变更合并到一起。
rebase
命令的作用是将当前分支的提交移动到另一个分支的最新提交之后,相当于重新应用一遍当前分支的所有提交。这种合并方式会使得提交历史变得更加线性,因为提交会被“重放”在新的基础分支上。在执行 rebase
命令之后,当前分支的提交历史会变为基于另一个分支的最新提交。
因此,merge
的合并方式更加保守,它将两个分支中的更改合并到一起,产生一个新的合并提交。而 rebase
的合并方式则更加激进,它将当前分支的提交历史改写为基于另一个分支的最新提交。在使用这两个命令时,需要根据实际情况选择适当的合并方式。
2.不同点
- 合并历史记录不同
- 修改历史记录的能力不同
- 处理冲突的方式不同
- 使用场景不同
下面是更详细的比较 merge
和 rebase
的区别:
1.合并历史记录不同
使用 merge
命令合并分支会创建一个新的合并提交,该提交拥有两个父提交,即源分支和目标分支的最新提交。因此,使用 merge
命令合并分支会保留每个分支的提交历史记录,而且可以很容易地看出哪些提交属于哪个分支。
使用 rebase
命令合并分支则会将当前分支的提交“移动”到目标分支的最新提交之后,并创建一个新的提交历史记录。因此,使用 rebase
命令合并分支会使得提交历史记录变得更加线性,但是也可能会使得分支之间的关系不太清晰。
2.修改历史记录的能力不同
使用 merge
命令合并分支时,每个分支的提交都会被保留,而且可以轻松地撤销合并操作。如果发现合并后的代码有问题,可以使用 git revert
命令撤销合并提交,然后再次尝试合并。
使用 rebase
命令合并分支时,当前分支的提交历史记录会被重新应用,因此可能会改变提交历史记录。如果发现 rebase
后的代码有问题,想要撤销操作就比较困难了。因为重新应用的提交已经修改了提交历史记录,如果要撤销 rebase
操作,就需要使用 git reset
命令,这会删除重新应用的提交,同时也会删除后续的提交。
3.处理冲突的方式不同
在合并分支时,可能会遇到代码冲突,需要手动解决冲突。使用 merge
命令合并分支时,Git 会自动创建一个合并提交,其中包含两个分支的所有更改。如果存在冲突,需要手动解决,然后再提交合并结果。
使用 rebase
命令合并分支时,每个提交都会被逐个应用到目标分支上。如果存在冲突,Git 会停止 rebase
操作,提示解决冲突。解决冲突后,需要使用 git add
命令将更改加入缓存区,然后使用 git rebase --continue
命令继续 rebase
操作。这意味着 rebase
操作会在每个提交上进行冲突解决,而不是在整个分支上进行冲突解决。
4.使用场景不同
在实际使用中,选择 merge
还是 rebase
取决于你想要达到的目标以及你所在的团队的工作流程。以下是一些常见的使用场景和选择合适命令的建议:
使用 merge
:
- 当两个分支的历史相对独立,并且需要保留各自的提交历史时,使用
merge
命令。 - 当两个分支之间存在冲突时,
merge
命令会自动解决这些冲突,并创建一个新的合并提交。
使用 rebase
:
- 当你想要将当前分支的提交历史重写为基于另一个分支的最新提交时,使用
rebase
命令。 - 当你希望提交历史保持线性,避免出现不必要的合并提交时,使用
rebase
命令。 - 当你想要使得你的提交历史更加清晰明了,尽可能避免出现分叉时,使用
rebase
命令。
无论使用 merge
还是 rebase
,都需要注意合并过程中可能出现的冲突和其他问题,及时进行解决。在进行 Git 分支合并时,最好先对代码进行备份,避免出现不可逆的问题。
3.使用
git merge 会让 2 个分支的提交按照提交时间进行排序,并且会把最新的 2 个 commit 合并成一个 commit。最后的分支树呈现非线性的结构
git reabse 将 dev 的当前提交复制到 master 的最新提交之后,会形成一个线性的分支树
七.上传到仓库
1.创建一个新仓库
git clone https://gitcode.net/qyj19920704/blog.git
cd blog
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
2.推送现有文件夹
cd existing_folder
git init
git remote add origin https://gitcode.net/qyj19920704/blog.git
git add .
git commit -m "Initial commit"
git push -u origin master
3.推送现有的 Git 仓库
cd existing_repo
git remote rename origin old-origin
git remote add origin https://gitcode.net/qyj19920704/blog.git
git push -u origin --all
git push -u origin --tags
4.一键发布博客
echo`ps -ef | grep /blog/blog/node_modules | grep -v grep | awk '{print $2}'`
kill-9 `ps -ef | grep /blog/blog/node_modules | grep -v grep | awk '{print $2}'`
cd /blog
rm-rf blog
git clone https://gitcode.net/qyj19920704/blog.git
cd /blog/blog
npm install
nohup npm run dev >/dev/null 2>&1 & exit