Git介绍

  • git是分布式版本控制工具,可以快速高效管理项目代码。git有廉价本地库、方便暂存区。

  • 版本控制是一种记录文件内容变化以方便历史查阅、修订的系统。
    image-20240125143443972

  • 版本控制目的:从个人开发过渡到团队协作开发

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

  • 分布式版本控制工具

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

    image-20240125154547521

    • 工作区:代码存放的目录位置,可以删除,无法追溯。
    • 暂存区:工作区的文件添加到临时存储区间,可以删除,无法追溯。
    • 本地库:暂存区的代码提交到本地库后生成历史版本,代码就可以被追溯了,再也删不掉了。
    • 历史版本是无法单独删除的,除非删除本地库。
  • 代码托管中心(远程库)
    远程库:本地库可以推送到远程库,网络中的所有用户都可使用。

git安装

git命令

  • 设置用户名签名,作用:区分不同操作者身份,注:用户签名和github的账号没有任何关系
    git config —global user.name
    git config —global user.email

  • 初始化本地库:获取本地库的管理权,会生成.git目录,不要修改该目录
    git init

  • 查看本地库状态: 显示分支,提交|没有提交的记录,未被追踪的记录|追踪到的记录(需要被add)
    git status

  • 添加到暂存区
    git add *|\

  • 从暂存区删除文件,取消追踪的文件
    git rm —cached \ 或*.ext
    git rm —cached -r \

  • 显示追踪的文件
    git ls-files

  • 恢复工作区文件
    git checkout <版本id> 文件名

  • 提交本地库:显示新增和删除行信息,git安行管理
    git commit -m “\<日志信息>“ \
    image-20240125164103112

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

    image-20240125170814112
    git log —graph —oneline —all

历史版本

  • 版本穿梭:移动head指针
    git reset —hard 版本号
    git reset —soft 版本号

changes not staged for commit:
image-20240409091333996

git分支

分支特性

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

head指针,分支指针

  • 使用git checkout 来移动HEAD指针,移动的对象可以是分支指针也可以是快照(快照就是版本号)
  • 使用git branch -f 来移动分支指针,移动的对象只能是快照。当且仅当HEAD指针指向分支指针的时候,提交才会有效。
  • HEAD指针默认指向当前的分支指针,用星号表示,如master*image-20240914104204320
  • 移动HEAD指针,git checkout C1, 这个时候HEAD指针指向的是快照,这个时候指针的状态称之为游离状态,detached,可以理解为没有和任何分支绑定。image-20240914104314043
  • 详情查看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 查看远程分支名
    image-20240125174135152

  • 切换分支(最新版本) or 切换版本
    git checkout <分支名>
    git checkout <版本号>

  • 分支合并: 把指定分支合并到当前分支上, 如果当前分支发生改动则会出现分支冲突
    git merge 分支名
    image-20240125175028291

  • 本地分支推送到远程分支
    git push origin :

  • 将提交应用到分支而非分支合并(另一个分支的版本放到当前分支最新的版本之后而非之前)
    git cherry-pick
    可以是分支名或者分支某次提交的哈希值
    应用场景:

    1. 合并单个提交:当我们只想应用某个分支上的一个提交到当前分支时,可以使用cherry-pick命令,而不需要合并整个分支。
    2. 修复bug:当我们在一个分支上修复了一个bug,并希望将这个修复应用到其他分支上时,可以使用cherry-pick命令。
    3. 提取特定功能:当我们在一个分支上开发了一个新功能,并希望将该功能应用到其他分支上时,可以使用cherry-pick命令。
    4. cherry-pick后无法pull
    5. Cherry-pick 合并1,8号版本
    6. Cherry-pick .. 合并(1,8]号版本
    7. Cherry-pick ^.. 合并[1,8]号版本
  • git merge是合并整个历史版本,cherry-pick是遴选若干想要的版本进行合并,rebase是在当前分支上对当前分支和另一个分支的共同的历史版本之后的某个历史版本上追加另一个分支的所有历史版本讲解1讲解2git沙盒学习工具

    • rebaseimage-20240914110735349image-20240914110902578
      image-20240618100059701
    • mergeimage-20240914110337770
    • cherry-pick
      image-20240618102241507
  • git stash or git stash save “注释”
    可以将没有提交的内容(包括工作区和暂存区)保存至堆栈中。注意: 如果工作区新建了个文件,此文件从来没有被添加到暂存区,那么这个文件就不能被git管理,也就不能被保存到堆栈。特别说明:

    当使用 git stash 将工作区内容提交到堆栈临时存储后,工作区的内容会立刻变为上一次提交的内容。
    此时如果使用 git stash pop将堆栈内容弹出,工作区内容立马恢复。
    
    • git stash list列出所有保存的临时提交(stash)
      image-20240618141724745
      您当前只有一个保存的临时提交,它的标识为 stash@{0}。该临时提交的消息是 “WIP on master: 6b63346 第三次提交”,表示该临时提交是在 master 分支上进行的工作,并且是提交对 6b63346(提交的哈希值)的更改。

    • git stash show
      查看堆栈中最新保存的stash 更改信息
      image-20240618142115734
      t1 | 1 +
      有一个文件发生了更改。文件名为 t1,文件中插入了一行内容
      1 file changed, 1 insertion(+)
      输出还显示了更改的摘要信息:
      1 file changed:一个文件发生了更改。
      1 insertion(+):插入了一行内容。

    • git stash pop
      将当前stash中的内容弹出,并应用到当前分支对应的工作目录上。注:该命令将堆栈中最近保存的内容删除(栈是先进后出)
      image-20240618142811811
      已经恢复了之前工作区的内容了。
      image-20240618143042239
      此时堆栈区也没有内容了。

    • git stash apply
      将堆栈中的内容应用到当前目录,不同于git stash pop,该命令不会将内容从堆栈中删除,也就说该命令能够将堆栈的内容多次应用到工作目录中,适应于多个分支的情况。

    • git stash drop + 名称
      从堆栈中移除某个指定的stash

    • git stash clear
      清除堆栈中的所有 内容

代码合并冲突解决(团队协作机制)

合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改(即同一个位置内容不一样)。git无法决定使用哪一个,需人工决定。 image-20240125175833371image-20240125175927291
手动vim修改冲突文件,三个特殊符号:

1
2
3
4
5
<<<<HEAD
当前分支代码
=======
另一个分支的代码
>>>> 分支名

根据需求修改当前分支代码和另一个分支的代码,保存修改后的代码,之后git add和git commit,注:git commit时不能再带文件名了否则报错
image-20240125180144371
在原132行删除了代码”set last_result_content=%s \“,在新132处添加了代码”set status=%s, \“。
image-20240305100601459

  • 底层逻辑:head文件指向分支文件,分支文件指向版本号文件

  • 团队内协作
    image-20240126092130539

  • 跨团对协作
    image-20240126092223346

忽略文件追踪

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

Idea集成开发git

github(国外)

image-20240312134109242

创建远程库

image-20240126093404953
new repository->repository name->权限public|private
远程库链接:http|ssh用于推送和拉取库,链接太长起别名

  • 查看当前所有远程地址别名
    git remote -v
  • 起别名:别名最好和库名一致,默认clone建的别名是origin
    git remote add 别名 远程地址

代码推送push

  • 推送本地分支上的内容到远程仓库
    git push 别名 本地分支名(源,默认):远程分支名(目的)
    image-20240126095020397
    登录方式:1、口令,2、浏览器账号
  • 推送时需要让团队库赋权限
    • 团队:repository->settings->manage access->invite a collaborator->生成邀请函pending invite->发送邀请函给待邀请的成员
    • 待邀请成员:访问邀请函->接受或拒绝->可以看到团队的项目了

代码拉取pull

将远程仓库对于分支最新的内容拉下来后与当前本地分支直接合并

  • git pull 远程库地址别名 远程分支名(源,默认):本地分支名(目的)

  • git fetch 远程库地址别名(eg. origin) 远程分支名:本地新分支名
    image-20240220160456539

  • 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 将会触发合并冲突。

代码克隆clone

将远程仓库的内容克隆到本地,克隆不需要登录账号的,克隆完成三件任务:1、拉取代码,2、初始化本地仓库,3、创建别名origin

  • git clone 远程地址 本地文件目录(默认当前目录)
  • git clone —branch 远程分支名 远程地址()
  • git remote add 别名(默认origin) 远程地址

团队内协作

  • git clone —branch 远程分支名 远程地址() 克隆仓库
  • 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:
    1. github上左上角搜项目或账号/项目
    2. 右上角fork,自己账号有了一个别人账号的项目
    3. Pull requests->new pull request->create pull request->可以相互评论
      image-20240126102907208
      image-20240126103026071
  • 团队2:
    1. Pull requests->点击链接文件->查看修改的代码->有疑问可以评论->确认别人的修改->merge pull request
      image-20240126102740136
      image-20240126103136503
      image-20240126103303057

ssh免密登录

没有创建.ssh目录无法使用ssh链接
image-20240126103623842

  • 生成.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

docker

macos 查看镜像文件时访问/var/lib/docker的方法
docker run -it —privileged —pid=host debian nsenter -t 1 -m -u -n -i sh