Git补充/Git

  • 这是基于上篇Git项目常用命令的一些额外补充,如有错误,请大家指针

一、前备知识

1.1分布式vs集中式

1.1.1集中式版本控制系统(CVCS)
  • 核心代码存放:所有代码和历史记录都存储在一个中央服务器上,开发者在本地只保存当前所需的部分代码副本。

  • 优点

    • 权限控制:集中式系统可以更好地管理和控制代码的访问权限,避免未经授权的更改。
    • 简单的操作:初学者容易理解,因为它符合“一个中心”的概念。
  • 缺点

    • 单点故障:如果中央服务器出现问题,所有人都无法提交或获取代码,影响工作进度。
    • 网络依赖:每次提交、更新代码都需要与中央服务器通信,网络状况直接影响工作效率。
1.1.2分布式版本控制系统(DVCS)
  • 核心代码存放:每个开发者的本地仓库都是完整的代码库副本,包括项目的完整历史记录。以 Git 为代表的 DVCS 没有单一的中央服务器。

  • 优点

    • 无单点故障:每个开发者都有完整的代码库,即使某台机器故障,也不会丢失项目历史。
    • 更快的操作:大多数操作(如提交、查看历史等)在本地进行,无需网络,速度更快。
    • 灵活的协作方式:可以轻松创建分支和合并,更适合团队协作。
  • 缺点

    • 分布式管理:如果没有一个主仓库作为参考,项目的合并和版本管理会变得复杂。

1.2暂存区vs工作区vs栈区

  • 图解(暂存区、工作区)

    在这里插入图片描述

  • git stash将修改放入栈区

  • git管理的是修改,而不是文件

    • 通过git add将修改放入暂存区,commit将修改提交
      • 快照机制:每次提交(commit)时,Git 实际上会为项目中的所有文件创建一个快照,但它不会为没有变化的文件重新存储内容。Git 只会为发生更改的文件创建新的快照,并将指针指向这些修改。这样,Git 可以通过这些快照追踪整个项目的历史变化。
    • 文件 vs. 修改:虽然 Git 存储了文件的快照,但它更关注的是这些文件在各个时间点的状态以及状态之间的变化。也就是说,Git 的工作方式是通过记录一系列的修改来追溯项目的历史,而不是对每个文件逐个进行管理。

1.3推送分支

  • 分支各作用
    • master分支是主分支,因此要时刻与远程同步;
    • dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
    • bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
    • feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

三、进阶(扩充)

3.1时光机穿梭

3.1.1版本回退
  • 参看版本提交日志

    git log

  • 回退到上一个版本 <--hard会将HEAD指针移动到上个版本的已提交状态,暂存区、工作区全部回退,而--soft只移动 HEAD 指针到指定的提交位置,保留更改在暂存区和工作区中,--mixed(默认)移动 HEAD 指针到指定的提交位置,并将更改从暂存区移到工作区。不删除工作区的更改。

    git reset --hard HEAD^

  • 回退到指定版本

    git reset --hard <id>

  • 查看gitHEAD的变动日志:记录的是对 HEAD 的移动、分支的切换、提交(commit)、合并(merge)、重置(reset)等操作的历史。

    git reflog

3.1.2管理修改
  • 查看工作区和版本库最新版本的区别,常用分支名填入HEAD指针

    git diff <分支名> -- <文件名>

3.1.3撤销修改
  • 不会被日志记录

    1. git checkout -- <file>
    • 命令git checkout -- <file>

    • 作用:撤销工作区的修改,将文件恢复到当前分支的最新提交(HEAD)的状态。

    • 具体操作

      • 工作区修改:如果你在工作区对文件进行了修改,并且这些修改还没有被暂存(即没有执行 git add),git checkout -- <file> 将丢弃这些未暂存的修改。
  • 恢复到 HEAD 状态:这个命令通过将工作区的文件内容替换为 HEAD 指向的最新提交的内容来实现撤销。这是基于 Git 提交时保存的快照来操作的。

    1. git reset <branch> <file>
    • 命令git reset <branch> <file>

    • 作用:撤回暂存区的内容,将文件从缓存区(暂存区)移除,但不影响工作区。

    • 具体操作

      • 缓存区(暂存区):如果你已经用 git add 将文件添加到缓存区,但决定不将这些修改提交,git reset <branch> <file> 将把这些文件从缓存区中移除,使它们不再被包含在下次提交中。
  • 恢复到 HEAD 状态:这个命令将文件从缓存区中移除,并恢复到 HEAD 指向的最新提交的状态。虽然工作区的内容不会被改变,缓存区的内容会恢复到指定提交的状态。

    1. 撤销方式与快照机制
    • 撤销操作

      • git checkout --git reset 都不涉及直接生成新的提交 ID,因此这些操作不会在提交日志中记录版本号。
      • 这些操作的实现依赖于 Git 的快照机制,而不是版本号。
    • 快照机制

      • 快照:每次提交都会创建一个新的快照,记录文件在该提交时的完整状态。Git 使用这些快照来跟踪文件的历史状态。

      • 恢复状态

        • git checkout --:通过将工作区文件恢复到最新提交的快照来撤销修改。这个快照来源于 HEAD 指向的提交。
      • git reset:通过将缓存区恢复到指定提交的快照来撤销暂存区的内容。这个快照来源于你指定的 <branch> 或提交 ID。

    • 撤销实现

      • 快照使用:撤销操作依赖于 Git 之前的提交快照。即使缓存区和工作区没有直接的 ID,每次提交的快照都保存了文件的状态。通过恢复这些快照,Git 能够实现撤销操作。
  1. git restore

    • --source <commit>: 指定要恢复的提交。如果不指定,默认为最新的提交(HEAD)。

      --staged: 仅恢复暂存区内容,保持工作区内容不变。

      --worktree: 恢复工作区的内容,保持暂存区内容不变(通常默认已启用)。

  2. 总结

  • git resotre是较新的语法

    • git checkout -- <file>:撤销工作区的修改,将文件恢复到最新提交的状态。
    • git reset <branch> <file>:撤回暂存区的内容,将文件从缓存区中移除,恢复到指定提交的状态。
    • 撤销机制:这些操作依赖于 Git 的快照机制,通过快照来恢复文件的状态,而不是通过版本号。每次提交都会保存文件的快照,通过这些快照,Git 实现了有效的撤销功能。
3.1.4删除修改
  • git rm <file>
    • 与删除的git add <file>,后面也要git commit

3.2远程仓库

3.2.1建立本地仓库和远程仓库链接
  • git remote add (origin)<远程仓库自定义名称> <远程仓库连接>

  • 推送代码

    git pull origin main

  • 删除远程库

    $ git remote -v
    origin  git@github.com:michaelliao/learn-git.git (fetch)
    origin  git@github.com:michaelliao/learn-git.git (push)
    
    $ git remote rm origin
    
  • clone代码

    git clone <链接>

  • 查看远程仓库名称,加上-v显示的信息更加全面

    git remote -v

  • 推送分支

    git push origin <分支名>

3.3分支管理

3.3.1创建并合并分支
  1. 创建分支并合并

    git checkout -b <分支名>
    
    // ==
    git branch <分支名>
    git checkout <分支名>
    
    // 查看所有分支
    git branch
    
    // 删除分支
    git branch -d <分支名>
    // 强行删除
    git branch -D <分支名>
    
    // 合并分支,合并该分支到当前分支
    git merge <分支名>
    
  2. 切换分支

    • git switch

      git switch -c <分支名>==git checkout -b <分支名>

      git switch <分支名>==git checkout <分支名>

在这里插入图片描述

  • 过程(这是本地合并的过程)

    1. 主分支与分支创建:
    • 一开始,主分支(例如 mainmaster)指向某个提交(也就是时间线上的一个点)。
    • 当你创建一个新分支(例如 feature-branch)时,这个子分支会从主分支的当前位置(提交)上分叉,创建一个新的分支指针。
    1. 工作区和 HEAD:
    • HEAD 代表当前活动的分支,它指向你当前工作的分支的最新提交。
    • 在分支创建时,HEAD 指向的是你当前检出的分支,即 main 分支。
    1. 在分支上进行更改:
    • 你在子分支上进行更改并提交,子分支的指针会向前移动,记录这些更改。
    1. 合并分支:
    • 当你准备将子分支的更改合并到主分支时,首先需要切换到主分支(例如使用 git checkout main)。
    • 使用 git merge feature-branch 命令将 feature-branch 的更改合并到 main 分支。
    • 合并操作会将子分支的更改整合到主分支的历史中。这通常会创建一个新的合并提交,记录这两个分支的历史。
    1. 合并的结果:
    • 合并后,主分支(例如 main)的指针会移动到新的合并提交,这个提交包含了子分支的更改。
    • 子分支仍然存在,可以选择继续开发或删除。
3.3.2分支管理策略
  • 默认是开启Fast forward模式的,可以强制禁用,这样merge的时候会生成一个新的commit

    git merge <分支名> --no-ff

    $ git log
    commit 05adea23be1fa9d08617659535f5ccc0136bfc3a (HEAD -> master)
    Merge: 2b7011b 0db3fe7
    Author: chenhao 2212348854@qq.com
    Date: Mon Sep 16 20:29:24 2024 +0800

    Merge branch 'test'
    

    commit 0db3fe7d74f7de862e97ef185cf9c4a9f16ab7f0 (test)
    Author: chenhao 2212348854@qq.com
    Date: Mon Sep 16 20:29:12 2024 +0800

    test2
    

    commit 2b7011bafa741f4b63e3f8310741392a351b720f
    Author: chenhao 2212348854@qq.com
    Date: Mon Sep 16 20:26:37 2024 +0800

    test
    
  • 不使用就像这样,合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

    在这里插入图片描述

  • 在正式开发中,master是要求稳定的,我们可以通过dev子分支来做测试,再在下面添加子分支一步步实现

    在这里插入图片描述

3.3.3分离头指针问题
  • 当你使用 git checkout <commit-id> 切换到某个特定的提交(而不是分支的最新提交)时,你就进入了“分离头指针”(detached HEAD)状态。
    • 这个时候推荐先将修改的内容git stash,然后再切换分支,把最新代码拉到当时那个分支,避免冲突,但最好还是用完的分支及时删除。
3.3.4bug分支
  • 将修改隐藏

    git stash

  • 查看隐藏列表

    git stash list

  • 指定版本stash pop

    git stash apply stash@{0}

  • git stash applygit stash pop 的区别

    • git stash apply stash@{0}:应用指定的 stash,但不会删除 stash 列表中的该项。
    • git stash pop:应用最近的 stash,并从 stash 列表中删除该项。
  • 如果一个分支的修改与另一个分支相同,可以使用 cherry-pick 命令将指定的提交应用到当前分支。首先,获取想要的提交的 commit-id,然后在需要修改的分支上输入:

    git cherry-pick <commit-id>

3.3.5多人合作冲突
  • 总结

    • 从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
    • 在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
    • 建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name
    • 从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。
  • git rebase

    • 若自己提交代码前,别人提交了,如果git pull后再提交,会导致,git log混乱,可以通过git rebase <分支名>来将分支移动到另一个分支的最新提交

    • 原先

      A—B—C (main)

      D—E—F (feature)

      git checkout feature
      git rebase main
      
    • 现在

      A—B—C (main)

      D’—E’—F’ (feature)

    • 注意不要随意改动别人的分支哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值