git教程
Git介绍
-
git是分布式版本控制工具,可以快速高效管理项目代码。git有廉价本地库、方便暂存区。
-
版本控制是一种记录文件内容变化以方便历史查阅、修订的系统。

-
版本控制目的:从个人开发过渡到团队协作开发
-
集中式版本控制工具svn
一台单一集中管理服务器保存所有修订版本,团队人员通过客户端连接这台服务器,取出最新的版本作修改并提交更新。优点:1、看到其他人在干什么,2、权限管控,3、管理轻松。缺点:1、服务器单点故障,2、无法协同。

-
分布式版本控制工具
- 每个人在自己的电脑上维护版本,并有一个远程库用来推送和拉取最新版本
- 每个客户端都有完整的包含历史记录的代码

-
git工作机制

- 工作区:代码存放的目录位置,可以删除,无法追溯。
- 暂存区:工作区的文件添加到临时存储区间,可以删除,无法追溯。
- 本地库:暂存区的代码提交到本地库后生成历史版本,代码就可以被追溯了,再也删不掉了。
- 历史版本是无法单独删除的,除非删除本地库。
-
代码托管中心(远程库)
远程库:本地库可以推送到远程库,网络中的所有用户都可使用。
git安装
git命令
-
设置用户名签名,作用:区分不同操作者身份,注:用户签名和github的账号没有任何关系
git config --global user.name
git config --global user.email -
初始化本地库:获取本地库的管理权,会生成.git目录,不要修改该目录
git init -
查看本地库状态: 显示分支,提交|没有提交的记录,未被追踪的记录|追踪到的记录(需要被add)
git status -
添加到暂存区
git add *|<file> -
从暂存区删除文件,取消追踪的文件
git rm --cached <file> 或*.ext
git rm --cached -r <folder_name> -
显示追踪的文件
git ls-files -
恢复工作区文件
git checkout <版本id> 文件名 -
提交本地库:显示新增和删除行信息,git安行管理
git commit -m “<日志信息>” <file>

-
查看日志: 显示版本号,签名,日期, head指针指向哪个版本哪个版本就是当前版本
git loggit log --oneline
git reflog


git log --graph --oneline --all
历史版本
-
版本穿梭:移动head指针
git reset --hard 版本号git reset --soft 版本号
-
# 回退到上一个提交,保留所有本地修改 git reset --soft HEAD~1 # 或者回退到指定提交,保留所有本地修改 git reset --soft <commit-hash>1
2
3
4
5
6
7
8
* ```
# 回退到上一个提交,保留工作区修改,但取消暂存
git reset --mixed HEAD~1
# 或者简写
git reset HEAD~1
--soft:回退提交历史,但保留工作区和暂存区的所有修改--mixed:回退提交历史,保留工作区修改,但取消暂存(默认选项)--hard:危险 - 回退提交历史,并删除所有本地修改
changes not staged for commit:

在Git中,如果你想回退到一个较早的版本并删除之后的更改(包括最新的版本),你可以使用git reset或git revert命令,具体取决于你想要保留的历史记录的方式。下面是两种常见的方法:
方法1:使用git reset
回退到特定版本并删除之后的更改
-
查看提交历史:首先,你需要知道你想回退到的那个提交的哈希值(commit hash)。你可以使用
git log命令来查看提交历史。1
git log
-
回退到特定版本:使用
git reset命令回退到特定的提交。这会改变你的当前分支的HEAD到指定的提交,并且可以选择性地保留或丢弃工作目录中的更改。1
git reset --hard <commit-hash>
其中
<commit-hash>是你想回退到的那个提交的哈希值。--hard选项会丢弃工作目录中的所有更改。
方法2:使用git revert
如果你想要回退到某个版本,但是又想保留之后的所有提交历史(即创建一个新的提交来“撤销”后面的更改,而不是直接修改历史),你可以使用git revert。
-
查看提交历史:同样,先查看提交历史,找出你想回退到的那个提交的哈希值。
1
git log
-
回退特定版本:使用
git revert命令来“撤销”某个提交的更改。这会在当前分支上创建一个新的提交,这个新提交会撤销指定提交所做的所有更改。1
git revert <commit-hash>
对于一系列连续的提交,你可以一次性撤销多个提交:
1
git revert <commit-hash-1> <commit-hash-2>
注意:
-
使用
git reset会重写历史,这可能会影响到已经推送到远程仓库的提交。如果你已经将更改推送到远程仓库,建议先使用git push --force(或git push -f)来强制推送你的本地更改到远程仓库。但是,这样做需要谨慎,因为它会覆盖远程仓库的历史。1
git push -f origin <branch-name>
-
使用
git revert则不会重写历史,它会在当前分支上添加一个新的提交来“撤销”之前的更改,这对共享仓库更为友好和安全。 -
在执行这些操作之前,确保你已经备份了重要数据或至少理解了将要进行的更改。这些操作可能会丢失你的工作进度,除非你已经将这些更改保存到了其他地方(如另一个分支或补丁文件)。
git分支
分支特性

版本控制过程中同时推进多个任务,每个任务相互独立,将自己的工作从主线上分离开来,开发自己的分支不影响主线分支运行,底层实现也是指针。

head指针,分支指针
- 使用git checkout 来移动HEAD指针,移动的对象可以是分支指针也可以是快照(快照就是版本号)
- 使用git branch -f 来移动分支指针,移动的对象只能是快照。当且仅当HEAD指针指向分支指针的时候,提交才会有效。
- HEAD指针默认指向当前的分支指针,用星号表示,如master*

- 移动HEAD指针,git checkout C1, 这个时候HEAD指针指向的是快照,这个时候指针的状态称之为游离状态,detached,可以理解为没有和任何分支绑定。

- 详情查看https://blog.csdn.net/HandsomeHong/article/details/112759075
分支创建、删除分支、分支转换、分支合并
-
创建分支
git branch 分支名
git checkout -b 分支名
git checkout --orphan 分支名 创建空白(没有记录历史)分支 -
删除分支
git rm -rf . 删除当前分支内的所有文件
git branch -d 分支名
git branch -D 分支名(强制) -
分支重命名
- git branch -m 旧分支名 新分支名
- git branch -m 新分支名
-
查看分支
git branch -v
git branch -r 查看远程分支名

-
git ls-remote --heads <远程仓库URL>: 这个命令会列出指定远程仓库的所有分支。 -
git remote show <远程仓库名称>: 这个命令会显示指定远程仓库的详细信息,包括其分支。 -
切换分支(最新版本) or 切换版本
git checkout <分支名>
git checkout <版本号> -
分支合并: 把指定分支合并到当前分支上, 如果当前分支发生改动则会出现分支冲突
git merge 分支名

-
本地分支推送到远程分支
git push origin <local_branch>:<remote_branch> -
将提交应用到分支而非分支合并(另一个分支的版本放到当前分支最新的版本之后而非之前)
git cherry-pick
可以是分支名或者分支某次提交的哈希值
应用场景:- 合并单个提交:当我们只想应用某个分支上的一个提交到当前分支时,可以使用cherry-pick命令,而不需要合并整个分支。
- 修复bug:当我们在一个分支上修复了一个bug,并希望将这个修复应用到其他分支上时,可以使用cherry-pick命令。
- 提取特定功能:当我们在一个分支上开发了一个新功能,并希望将该功能应用到其他分支上时,可以使用cherry-pick命令。
- cherry-pick后无法pull
- Cherry-pick
合并1,8号版本 - Cherry-pick
… 合并(1,8]号版本 - Cherry-pick
^… 合并[1,8]号版本
-
git merge是合并整个历史版本,cherry-pick是遴选若干想要的版本进行合并,rebase是在当前分支上对当前分支和另一个分支的共同的历史版本之后的某个历史版本上追加另一个分支的所有历史版本讲解1,讲解2,git沙盒学习工具
- rebase



- merge

- cherry-pick

- rebase
-
git stash or git stash save “注释”
可以将没有提交的内容(包括工作区和暂存区)保存至堆栈中。注意: 如果工作区新建了个文件,此文件从来没有被添加到暂存区,那么这个文件就不能被git管理,也就不能被保存到堆栈。特别说明:
当使用 git stash 将工作区内容提交到堆栈临时存储后,工作区的内容会立刻变为上一次提交的内容。
此时如果使用 git stash pop将堆栈内容弹出,工作区内容立马恢复。-
git stash list列出所有保存的临时提交(stash)

您当前只有一个保存的临时提交,它的标识为 stash@{0}。该临时提交的消息是 “WIP on master: 6b63346 第三次提交”,表示该临时提交是在 master 分支上进行的工作,并且是提交对 6b63346(提交的哈希值)的更改。 -
git stash show
查看堆栈中最新保存的stash 更改信息

t1 | 1 +
有一个文件发生了更改。文件名为 t1,文件中插入了一行内容
1 file changed, 1 insertion(+)
输出还显示了更改的摘要信息:
1 file changed:一个文件发生了更改。
1 insertion(+):插入了一行内容。 -
git stash pop
将当前stash中的内容弹出,并应用到当前分支对应的工作目录上。注:该命令将堆栈中最近保存的内容删除(栈是先进后出)

已经恢复了之前工作区的内容了。

此时堆栈区也没有内容了。 -
git stash apply
将堆栈中的内容应用到当前目录,不同于git stash pop,该命令不会将内容从堆栈中删除,也就说该命令能够将堆栈的内容多次应用到工作目录中,适应于多个分支的情况。 -
git stash drop + 名称
从堆栈中移除某个指定的stash -
git stash clear
清除堆栈中的所有 内容
-
代码合并冲突解决(团队协作机制)
合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改(即同一个位置内容不一样)。git无法决定使用哪一个,需人工决定。 

手动vim修改冲突文件,三个特殊符号:
1 | <<<<HEAD |
根据需求修改当前分支代码和另一个分支的代码,保存修改后的代码,之后git add和git commit,注:git commit时不能再带文件名了否则报错

在原132行删除了代码"set last_result_content=%s \“,在新132处添加了代码"set status=%s, \”。

-
底层逻辑:head文件指向分支文件,分支文件指向版本号文件
-
团队内协作

-
跨团对协作

忽略文件追踪
- .gitignore 只在工作目录中有文件但是在本地暂存区和版本以及远程版本都没有被忽略的文件,可以切换分支
- git update-index --assume-unchanged
忽略追踪一个文件的更改, 关闭文件与远程仓库的跟踪,无法切换分支(本地远端不一致) - git update-index --no-assume-unchanged
停止忽略文件更改,并让 Git 跟踪这个文件的更改,可以切换分支 - git ls-files -v | grep “^h” 检查哪些文件被忽略
- git ls-files -v | grep ‘^h’ | cut -c 3- | xargs git update-index --no-assume-unchanged 取消所有被设置"assume-unchanged"忽略的文件
- git update-index --skip-worktree
文件虽进行了更改,但让Git不标记为已修改,无法切换分支 - git update-index --no-skip-worktree
恢复上述操作,可以切换分支 - git ls-files -v | grep “^s” 检查哪些文件被标为未修改
- git ls-files -v | grep ‘^s’ | cut -c 3- | xargs git update-index --no-skip-worktree 取消所有被设置"skip-worktree"标记的文件
Idea集成开发git
github(国外)

创建远程库

new repository->repository name->权限public|private
远程库链接:http|ssh用于推送和拉取库,链接太长起别名
- 查看当前所有远程地址别名
git remote -v - 起别名:别名最好和库名一致,默认clone建的别名是origin
git remote add 别名 远程地址
删除原有的远程仓库引用(可选)
如果你想要完全从你的本地仓库中移除旧的远程仓库引用(例如,如果你不再需要与旧的GitHub或Gitee仓库同步),你可以使用以下命令:
1 | git remote remove origin |
这里的origin是默认的远程仓库名称。
添加新的远程仓库
克隆新的仓库后,你需要添加这个新的远程仓库到你的本地仓库配置中。
对于GitHub:
1 | git remote add origin(仓库别名自定义) https://github.com/username/new-repo.git |
切换远程仓库
1 | git remote set-url origin 新仓库的URL |
查看管理仓库
1 | git remote -v |
代码推送push
- 推送本地分支上的内容到远程仓库
git push 别名 本地分支名(源,默认):远程分支名(目的)

登录方式:1、口令,2、浏览器账号 - 推送时需要让团队库赋权限
- 团队:repository->settings->manage access->invite a collaborator->生成邀请函pending invite->发送邀请函给待邀请的成员
- 待邀请成员:访问邀请函->接受或拒绝->可以看到团队的项目了
代码拉取pull
将远程仓库对于分支最新的内容拉下来后与当前本地分支直接合并
-
git pull 远程库地址别名 远程分支名(源,默认):本地分支名(目的)
-
git fetch 远程库地址别名(eg. origin) 远程分支名:本地新分支名

-
git pull --rebase origin 远程分支名:本地分支名
这条指令的意思是把远程库中的更新合并到本地库中,-–rebase的作用是取消掉本地库中刚刚的commit,并把他们接到更新后的版本库之中。 -
fetch和pull区别
- git fetch:
- 用途:git fetch 用于从远程仓库下载新的提交和对象,但它并不会自动合并或修改你的工作目录。
- 不会自动合并:git fetch 只是将远程仓库的最新内容拉取到本地,但不会自动合并这些变化到你的当前工作分支。
- 本地分支不受影响:你可以查看远程分支的更新情况,然后手动决定是否要合并这些更新到你的本地分支。
- git pull:
- 用途:git pull 也从远程仓库拉取更新,但它自动将这些更新合并到当前工作分支。
- 自动合并:git pull 实际上包含了 git fetch 和 git merge 两个步骤,它会自动将远程仓库的变化合并到当前工作分支。
- 可能导致冲突:由于自动合并的特性,如果远程和本地的修改发生冲突,git pull 将会触发合并冲突。
- fatal: refusing to merge unrelated histories
- git pull xingyun-eff master --allow-unrelated-histories
- git fetch:
代码克隆clone
将远程仓库的内容克隆到本地,克隆不需要登录账号的,克隆完成三件任务:1、拉取代码,2、初始化本地仓库,3、创建别名origin
- git clone 远程地址 本地文件目录(默认当前目录)
- git clone --branch 远程分支名 远程地址(<remote_repository>)
- git remote add 别名(默认origin) 远程地址
团队内协作
- git clone --branch 远程分支名 远程地址(<remote_repository>) 克隆仓库
- git remote add 别名(默认origin) 远程地址 远程地址起别名
- git pull origin cloud 用于获取最新远程分支cloud代码(可能别人在不停修改),本地也生成了个cloud分支
- 新建一个自己的分支名, 例如me,用于之后的分支合并解决冲突
- 在me分支维护自己的代码,提交版本
- me提交版本后,先切到本地cloud分支拉取最新版本,在cloud分支上合并me分支
- cloud分支有a.txt,而me分支没有,合并后cloud分支依然有a.txt
- cloud分支没有a.txt,而me分支有,合并后cloud分支有a.txt
- cloud分支有a.txt, 而me分支也有,合并后会有冲突或没有
- 合并后两个分支共同的文件中的代码是一致的
- 在cloud分支上push到远程
跨团队协作
- 团队1:
- github上左上角搜项目或账号/项目
- 右上角fork,自己账号有了一个别人账号的项目
- Pull requests->new pull request->create pull request->可以相互评论


- 团队2:
- Pull requests->点击链接文件->查看修改的代码->有疑问可以评论->确认别人的修改->merge pull request



- Pull requests->点击链接文件->查看修改的代码->有疑问可以评论->确认别人的修改->merge pull request
ssh免密登录
没有创建.ssh目录无法使用ssh链接

- 生成.ssh, -t指定加密算法, -C描述账户
ssh-keygen -t rsa -C github账户 - 在.ssh中找公钥*.pub,复制内容,添加到github的SSH and GPG keys中
- git pull ssh链接 分支名 或git push ssh链接 分支名
idea集成github
gitee码云(国内)
创建远程库
idea集成gitee
gitee连接github进行代码的复制和迁移
gitlab(局域网)
gitlab服务器搭建和部署
idea集成gitlab
Git配置多个SSH-Key
背景
当有多个git账号时,比如:
a. 一个gitee,用于公司内部的工作开发;
b. 一个github,用于自己进行一些开发活动;
解决方法
- 生成一个公司用的SSH-Key
1 | $ ssh-keygen -t rsa -C 'xxxxx@company.com' -f ~/.ssh/gitee_id_rsa |
- 生成一个github用的SSH-Key
1 | $ ssh-keygen -t rsa -C 'xxxxx@qq.com' -f ~/.ssh/github_id_rsa |
- 在 ~/.ssh 目录下新建一个config文件,添加如下内容(其中Host和HostName填写git服务器的域名,IdentityFile指定私钥的路径)
1 | # gitee |
4.用ssh命令分别测试
1 | $ ssh -T git@gitee.com |
这里以gitee为例,成功的话会返回下图内容

如何在本地环境自由地切换Gitee、Github与Gitlab?
原创
coder2plus2020-08-04 17:09:21博主文章分类:架构©著作权
文章标签*gitgithubgitlabgitee*****文章分类*软件研发*****阅读数**2763**
1.简介
我们在现实工作之中,会经常出现以下情况,我们自己在github、gitlab、gitee上都有账号的同时,可能有些公司环境也是购买的gitee或github的私有代码托管服务,或者在局域网部署一套gitlab服务并分配账号给公司内的开发人员。于是,就会出现一个开发人员同时存在多个git账号(公司局域网内的gitlab账号、自己或公司分配的github或gitee账号)的情况,我们希望把不同的git代码托管服务账号和提交内容进行隔离,从而实现各个账号各自管理自己的代码,互不干扰!在提交代码的同时,能够实现既可以通过 git命令提交,又可以通过TortoiseGit 工具提交代码到各自的git代码托管服务器上。
那么,在多git账号的情况下,如何在本地电脑上,做到自由切换账号,从而做到不同git服务上代码的隔离呢?下面会详细阐述。
2.方案
通常,我们通过ssh的方式连接到Github/Gitee/GitLab服务,ssh连接需要一对秘钥。因此,如果想在同一台电脑上绑定不同的Github/GitLab/Gitee帐号,需要满足以下条件:
- 能够为每个账号生成私钥/公钥对;
- 在提交或更新代码时,可以区分不同账户,推送代码到相应的仓库或从相应的仓库拉去代码;
具体方案如下:
- 生成私钥/公钥时,密钥文件命名避免重复;
- 设置不同Host对应同一HostName,但密钥不同;
- 取消 git全局用户名/邮箱设置,为每个仓库独立设置用户名/邮箱;
3.实施
公司局域内的gitlab账号由于经常使用,可设置为全局账号,具体方法不再阐述。本文主要演示如何在公司git
3.1 Git安装
Git for windows与TortoriseGit的安装不是本文重点,不再演示。
3.2 生成SSH key
Git使用的是SSH加密协议,Gitee与Github网站里,用户设置中需要配置相应的SSH keys。通常,需要管理多少个账户,一般就需要生成多少套SSH keys。在.ssh文件夹下打开Git Bash或CMD窗口,输入下面指令生成第一个SSH key(以gitee环境举例,github环境类似):
公钥可命名为gitee_id_rsa(公钥名需根据环境进行区分),密码为空或者输入,为空直接点击两次回车。
3.3 配置config文件
在.ssh文件目录下创建 config文件,可以通过touch config方式创建,具体添加内容如下代码所示:
1 | # github |
此时用户.ssh目录下,内容如下所示:
3.4 把github与gitee对应的公钥对应的公钥上传到服务器
下面以gitee服务器举例。
首先,查看本地生成的公钥:
然后,打开gitee上的SSH公钥配置页面,将上一步得到的公钥粘贴到指定位置:
将公钥上传到Github服务器与将公钥上传到Gitee服务器类似,不再演示。
3.5 测试
可通过ssh -T git@gitee.com或ssh -T git@命令,测试已建立的本地环境与gitee、github的连通性。
若遇到以下Connection refused问题,不要紧张,是由于公司内部屏蔽了github与gitee引起
docker
macos 查看镜像文件时访问/var/lib/docker的方法
docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
大部分镜像托管平台支持多平台镜像,这意味着镜像仓库中单个标签可以包含不同平台的多个镜像,以 docker hub 的 python 镜像仓库为例,3.9.6 这个标签就包含了 10 个不同系统和架构的镜像(平台 = 系统 + 架构)。
通过 docker pull 或 docker run 拉取一个支持跨平台的镜像时,docker 会自动选择与当前运行平台相匹配的镜像。由于该特性的存在,在进行镜像的跨平台分发时,镜像的消费端是无感知的,我们只需要关心镜像的生产,即如何构建跨平台的镜像。
默认的 docker build 命令无法完成跨平台构建任务,需要为docker 命令行工具安装 buildx 插件扩展其功能。buildx 能够使用由 Moby BuildKit 提供的构建镜像额外特性,它能够创建多个 builder 实例,在多个节点并行地执行构建任务,以及跨平台构建。可能需要开vpn才能构建成功
docker打包(打包成x86架构)
docker buildx build --platform=linux/amd64 -t efficiency:latest .
docker打包(打包成arm架构)
docker buildx build --platform=linux/arm64 -t efficiency:latest .
docker打包(混合)
docker buildx build --platform=linux/amd64, linux/arm64 -t efficiency:latest .
1、启动能效项目docker
注释掉:-v ~/efficiency/logs:/app/logs -v ~/efficiency/result:/app/result -v ~/efficiency/configs:/app/configs -v ~/efficiency/faultcode:/app/faultcode
docker run -d -p 0.0.0.0:8889:8889 --name eff -v ~/efficiency/app/:/app/ efficiency
2、启动docker的myslq
(1)docker拉镜像
docker pull mysql:8.4.3
(2)启动
docker run -d --name mysql -p 13306:3306 -e MYSQL_ROOT_PASSWORD=Zhang123. -v 自己的目录/docker/mysql/data:/var/lib/mysql --restart=always -d mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
3、启动 docker的minio
(1)docker拉镜像
docker pull quay.io/minio/minio
或
docker pull minio/minio
(2)启动
docker run -d -p 19000:9000 -p 19090:9090 --name minio -e “MINIO_ROOT_USER=minioadmin” -e “MINIO_ROOT_PASSWORD=Zhang123.” -v 自己的目录/docker/minio:/data minio/minio server /data --console-address “:9090”



