电子商务网站建设 代码,网络营销模式有哪些?,软文广告的案例,网站后台在哪里一、总论
1.1 写在前面的话
这已经是我第三遍学Git相关操作了#xff0c;可以说这个玩意是真的狗#xff0c;因为确实用不到#xff0c;不知道下个学期会不会用到#xff0c;直到现在我刚刚学完#xff0c;处于知识水平的巅峰#xff0c;知道Git的具体功能#xff…一、总论
1.1 写在前面的话
这已经是我第三遍学Git相关操作了可以说这个玩意是真的狗因为确实用不到不知道下个学期会不会用到直到现在我刚刚学完处于知识水平的巅峰知道Git的具体功能我也觉得真没啥必要学。我一开始学Git是因为以为这个跟Github有啥关系似的其实对于个人来说使用Github完全没有必要学习Git。
这就引出了Git最重要的一个认识了就是Git的基本上所有的功能都是为了团队协作开发的而不是所谓的版本控制当然也可能是反正我理解的不是。Github上面那些看似唬人的branchtagrespositoryssh keytoken之类的概念其实都是为了团队协作设计的而不是为了版本控制或者其他啥目的简而言之就是与我现在的需求无关。
对于Git的学习大致分为两个部分即版本控制和团队协作。之后会详细介绍。
所有的版本控制系统只能跟踪文本文件的改动比如txt文件网页所有程序的代码等Git也不列外版本控制系统可以告诉你每次的改动但是图片视频这些二进制文件虽能也能由版本控制系统管理但没法跟踪文件的变化只能把二进制文件每次改动串起来也就是知道图片从1kb变成2kb但是到底改了啥版本控制也不知道。所以我当时搭博客的时候希望能够回退到没有安装某个插件的版本应该是不可能了不过我应该可以控制配置文件的版本。
1.2 一个比喻
为了理解三个概念即工作目录暂存区和版本库我们进行一个比喻。我们在工作台上工作当我们做出一个东西的时候就可以考虑把他放到一辆货车上。我又做了一个东西做完以后把他扔货车上了但是做别的时候突然觉得不行我得重新做于是我就把第二个东西从货车上取下来重新做。当我们做了一系列东西以后我们的货车相当于就装载了我们一系列的东西我们看了看觉得没啥毛病就开着货车把这一个系列的东西都放到仓库里去了。为啥要放到仓库里是因为我们恋旧保不齐哪天就想把之前的东西拿出来看看呢。
在这个比喻里工作台就相当于我们的工作目录货车就相当于我们的暂存区仓库库就相当于我们的版本库。
我一开始学的时候觉得暂存区贼没有因为反正版本库可以记录那么为什么还得要个中间层在这里碍事这是因为版本是一个很大的概念修改一份代码一般不值当作为一个版本就好像没人做一个东西就风尘仆仆地让仓库里去而是应该攒一堆东西一起放入仓库。而暂存区就是提供这样一个攒东西的容器。相当于一个小而精的版本库虽然只能存储一个版本但是可以一个一个文件的取回。
在 git 中有一组名词叫做检入checkin和检出checkout所谓的检入就是把工作台上的东西放到货车上或者把货车上的的东西放到仓库中的过程而检出与之相反是把货车上的一个文件取到工作台上或者把仓库里一系列东西取到工作台上的过程。
1.3 版本库管理
最难理解的就是这个我花了很久才明白这是一个什么样子的结构。我们看看我们的需求是什么我觉得版本控制就是在我们的工作进行到了一定程度以后比如说实现了某个功能以后我们存一个档有一说一我觉得存档这个词比快照更加方便理解这样之后的工作的时候哪怕搞砸了还是能够恢复的就跟过BOSS前存个档这样就随便浪一样。
那么其实就暴露了一个问题就是对于存档的管理问题我们在游戏中一般是有存档限制的比如只能存五个档存多了就覆盖原来的存档了。但是想想也知道我们当然不希望自己做版本控制的时候也有数量限制当然实现一个无限制的版本控制肯定不难啊。我们假设已经实现了那么怎么管理呢面对很多的版本怎么去检索出自己想要的版本呢如果用一个数组去存版本检索起来不会容易的比如我们在开发的时候希望维持一个既有的稳定版本的同时又可以有一个分支快速开发那么也就是说需要标记这个稳定版本又是如何标记的呢这就是一个问题。还有一个问题就是我们有的时候是不希望存档是完全覆盖的就比如我打游戏的时候虽然最后死在了BOSS我前期打小怪的经验还是希望保留的当然一般游戏如果是存档的话那就是直接覆盖了。如果我们进行版本控制的时候可以挑选两个存档的长处进行融合那么显然是很好的功能这个功能又如何实现呢
那么针对上面的三个问题无限存档查找存档融合存档git 给出了自己的方案他用了一个有向图结构来存储版本库而且采用了指针来进行版本的查找一张比较标准的版本库的数据结构就是下面这样 里面的一个个圆圈就是一个个存档也就是一个个版本里面的标签也就是指针版本之间会用黑色的箭头相连。我们来解释一下是啥意思。无限存储面临的一个问题是显然是不能每个版本就把所有内容全都复制一遍我做过一个项目一个项目就 1 个G这要是一个256G 的硬盘顶多存档 256 次。显然是不能满足需求的。可是如果在版本之间建立逻辑关系那么就不一样了相当于我们记录的是版本间变化而不是一个独立的版本。这样说其实不准确git 采用的是如果版本中的一个文件没变化就记录上一个版本如果有变化就记录这个版本如图 为了实现前一个版本的概念我们用了黑色箭头来指明这种逻辑关系。
那种标签一样的东西可以帮助我们快速查找特定版本比如说我们想要 C3 版本了那么只需要说检出 main 就好了。在诸多标签中有一个标签最重要就是我们的 HEAD 我们可以说我们只能操纵HEAD和HEAD指向的标签而不能操作其他标签。
此外还需要强调的是这只是 git 的版本库的内部数据结构而不是他给用户的抽象结构他的抽象结构更像是这样
分支的概念被引入版本被串联成了不同的分支这会使版本的管理更加容易理解因为我们相当于对版本进行了一个在不同分支上的分类。所谓分支就是同名可变指针的移动路径。
之前我老觉得每一条分支就是一个“分支”这句废话的意思是就像上面的图一样比如说 Develop 是一条分支橙色那么它就对应的是由橙色的版本库连接起来的东西其实是不是的由版本库做节点的树结构因为合并操作的存在其实不是严格的树结构是存在的但是一个分支并不代表一个路径也就是一串相连的节点们而只是一个指针指向了具体的一个节点。具体图景如下 从图中可以看到尽管main应该是个“分支”但它其实就是个指针。指向了某个节点而已。
1.4 Github
对于如何使用Github其实我觉得就当成网盘那样使就可以了可以自己将各种资料上传到网上也可以从网上下载各种资源可能跟网盘不太一样就是有搜索功能还有提问功能吧如果不涉及团队协作那么理解到这个层次我绝对对我自己是够用了。其唯一与网盘不同的是对于删除操作似乎不太方便我没有细致研究不敢妄下断语似乎只用网页端是没有办法完成删除操作的。 二、建库
2.1 建库方式
一共有两种建库方式一种是直接在本地建库在所处的文件夹下输入以下代码就可以完成建库建立的库文件夹就是所处文件夹。
git init 然后这样的仓库需要通过下面这条命令与远程仓库进行关联
git remote add origin https://github.com/Thysrael/仓库名 需要注意origin也只是一个名字我们用它来指代关联的远程仓库。
还有一种是通过clone Github上的库进行建库也就是在Github里面建好了库然后在clone到本地输入以下命令建立的库会以文件夹的形式出现在Git bash所在的目录换句话说git bash所在的目录不是库而是其中的一个子文件夹是这是与前一种方法不同的地方。这个子文件夹的名字就是github的仓库名。
此外需要强调的是clone下来的仓库拥有所有分支可能只是不显示但是是可以进行切换的。
git clone url 可能是我学业不精我还是觉得第二种方法更好是因为第一种方法建立的分支叫做master而github默认的分支是main按照理论来讲可能可以由本地不同名的分支向github的分支提交但是我捣鼓了很久都发现只能向同名的分支提交更新所以第一种方法就很废物因为它会在远端产生一个新的分支master而过去的main分支则没有更新。
2.2 .gitignore
建完库以后第一件事情要做的就是先把 .gitignore 文件写了这个文件的作用是当执行 git add . 操作的时候可以把这个文件里列出的内容屏蔽掉也就是并不追踪这些文件。具体写法如下
### Example user template template
### Example user template# IntelliJ project files
.idea
*.iml
*.txt
out
gen举例 此时我有两个文件然后我的 .gitignore 文件写法如下 也就是会忽略所有的 .zyqs 文件我们进行一个 git add . 操作 可以看到b.zyqs 文件并没有被提交到暂存区。 三、暂存区的使用
3.1 直观理解
之前我一直忽略了这个方面是因为我平时就直接
git add . 类似于我先把一个版本里所有东西都做好了然后直接进行一次装车然后开着车就把所有东西都运仓库里去了。但是这是因为当时比较年轻啊当我开始做学校布置的作业的时候一个仓库里有四道题我做完第一二三题想着回头一起交就这么先撂这了开始做第四道题结果一不小心把前三道题都删了呜呜呜麻了。但是其实有两种预防手段一种是我交三个版本但是这也不合逻辑啊我的第一个版本只能获得四分之一的分数只做了一道题我认为每个版本都应该是具有满分的可能性的就跟每个项目版本都具有可运行的可能性一样。所以应该选择另一个手段也就是完成一道题就把一道题移到暂存区这样就可以起一个比较便捷的存档作用。
3.2 原理
只是工作原理有下面这张图
所谓 stage 就是已经提交到暂存区了。
Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存, 文件状态为Modified
这些状态都可以用下面的命令查询
git status 这种命令输出的信息太乱了可以用下面的命令完善
git status -s 其中 ? 表示未被追踪M 表示被修改A 表示是新增文件。左侧那一列是暂存区相对于版本库前一版可以看出a.txt 在暂存区中是相对于版本库是修改过的b.txt 是相对于前一个版本库新增的而 c.txt 是未被追踪的 。右侧的一列是工作目录相对于暂存区的可以看出 a.txt 在工作目录中是与暂存区相同的b.txt 相对于暂存区是修改过的而 c.txt 是未被追踪的 。
3.3 命令
我们用这条命令可以把某些文件加入暂存区
git add filename关于恢复其实有两种操作
一种这样
git restore filename另一种是这样
git checkout -- filename据说 restore 可以应用的范围更广但是我做了好多实验没发现它俩有啥区别
如果想要将暂存区的记录撤销也有两种方法
第一种会让暂存区的操作回归到修改状态
git restore --staged filename第二种会让暂存区的文件直接变成未追踪状态
git rm --cached filename具体效果如下图其中对 a.txt 使用的是第一条命令对 b.txt 使用的是第二条命令。 四、版本控制
4.1 提交版本
我们一般是整个文件夹中的内容一起上传也就是下面这条指令
git add . 当我们把需要用的文件交到了暂存区就可以用下面这条指令提交到版本库
git commit -m 注释 里面的 -m 就是为了添加注释注释相当重要。
如果写好了 .gitignore 那么其实可以将 commit 和 add 命令进行一个合并
git commit -a -m 注释 那么为什么要设置一个暂存区呢我个人理解是由本地目录向暂存区提交的时候是可以一件一件的提交的那么就存在新版本中还有与老版本一样的文件这时候如果没有提交那么就用老版本文件代替暂存区提供了一个全是新文件的地方让我们可以看清楚我们的修改。只不过我们习惯于全部提交所以这个功能就很鸡肋了。
4.2 版本查看
我们还可以用下面这条指令看我们的提交版本记录
git log 但是只有 git log 会显得比较单调乏味但是如果用的是这条命令会显得好看很多只是好看
git log --graph
git log 只能看当前版本所在分支并且位于当前版本之前的版本记录所以我更习惯下面这条指令提供的信息更多
git reflog4.3 版本控制
有了 1.3 的讲解其实对于分支的理解可以更深一些其实分支名不过是一个指针指向了具体的版本库。当然众多指针中有一个比较特殊的就是 HEAD 指针。我现在对它的理解是我们大部分的操作都是针对与 HEAD 指针而言的。HEAD就是当前的意思。
所谓的 checkout 其实就是改变 HEAD 的指向使工作目录变成 HEAD 指向的版本。那么其实 HEAD 有两种指向一种是指向具体的版本库一种是指向分支也就是 HEAD 指针指向了一个分支指针。当指向分支的时候呈现这种形式 当指向具体的版本库的时候呈现这种形式 此时 HEAD 指向C1版本库也被称为 HEAD 分离状态)。
如果想要 HEAD 重新指向一个分支可以使用命令
git checkout branch-name 如果想让某个分支强制指向 HEAD 所指向的目录可以用命令平时分支指针的移动需要 HEAD 指在其上面一般只能前进和后退不能跳转
git branch -f branch-name HEAD 其实只要熟悉了上边的操作我们就可以在任何版本之间进退自如了。当然如果利用上git的树结构节点是有父节点信息的与之相对没有子节点信息所以回退的时候会发生版本丢失。可以用 reset 命令其实就是顺着数向上回溯。
如果想要实现版本回退可以使用如下命令其中 n 是
git reset --hard HEAD~n 然后如果只是一个版本的回退两个版本就是两个^可以用下面的指令来实现。从上面这两条指令可以看出HEAD其实是一个指向不同版本的指针指向谁就显示哪个版本。
git reset --hard HEAD^ 如果想实现版本的跳转那么可以用下面的指令
git reset --hard 版本号 版本号的查询可以用这条指令
git reflog4.3 分支操作
当我们想要查看分支的时候可以用如下命令
git branch 如果想要创建一个分支可以用如下命令
git branch 分支名 如果想要删除一个分支可以用如下命令
git branch -d 分支名 如果想要跳转到某个分支可以用如下命令
git checkout 分支名 如果想要创建并跳转到这个分支可以用如下命令
git checkout -b 分支名 关于分支的合并其实应当这样理解两个版本之间存在差距执行如下命令可以让其合并即在当前分支融合某一分支
git merge 分支名 当然经常融合不了这个时候需要重新提交然后仔细修改然后提交版本就没有问题了有问题的时候控制台会在分支名后跟一个“merging”。
还有一种操作叫做变基其实也很与merge很类似如下命令
git rebase branch-name执行
git rebase main五、远程仓库
5.1 分布式管理
对远程仓库的处理其实可以引出 git 的另一个重要特性那就是分布式管理他的意思是说任何一台电脑上的版本库都存着这个版本库的全部版本信息也就是保存着那个树结构。这样相对于集中式管理丢失全部版本数据的概率小多了。但是同样的每台机子上的版本库都必须与中心库保持一致这无疑增加了学习的难度。
其中最重要的一个思想是有一组远程分支指针出现在本地版本库中来记录本地版本库与远程库的差距我们一般的移动分支指针的操作是没有办法对远程分支指针使用的。换句话说远程分支指针的移动条件更为苛刻大概就像这样 5.2 命令
远程仓库的命令呈现就是基础的命令没人用常用的命令都是由几条命令复合而来的。
比较基础的 fetch 他可以把远端仓库的版本全都拷贝下来而且还会移动远端指针到相应位置示例如下 git fetch 但是 fetch 并不会移动本地的指针。所以我们为了比较自然的操作其实是需要把本地指针更新一下的那么更新就一般会涉及 merge 操作因为版本分支问题如果不 merge没法移动指针这是没有操作的时候 进行如下命令
git fetch git merge o/main上面两条指令可以合成一条就是我们熟悉的
git pullpush 是另一个可以更新远端分支指针的操作未使用命令前 git push 如果提交不成功那么就是因为本地的版本落后与远端版本了别人也在修改这个分支所以需要先把远端的版本从新拉取过来在拉取的过程中可能会需要解决冲突解决完应该就可以提交了。
git pull git push