zoukankan      html  css  js  c++  java
  • Git和GitHub的学习记录

    本篇博客记录关于Git和GitHub的知识以及在Linux(Manjaro)的使用

    GitHub

    参考资料 参考资料
    起步:创建新仓库->创建新分支->修改新分支的内容并commit->open and merge pull request

    基本概念

    repository版本库/仓库:仓库是一个存储各种文件的地方,比如你可以用来存储一个python项目

    branch分支:一个仓库默认会有一个main分支,创建一个新分支会复制main分支的所有内容,之后我们可以在这个分支上自由的修改、提交,甚至最后整合如main分支中

    commit提交:保存分支的修改操作成为commit
    open a pull request打开拉取请求:当你修改了分支内容(与主分支的内容发生了差异)时,可以打开拉取请求,让别人审核是否能够代替主分支的内容

    merge the pull request:审核人可以审核你的拉取请求,并且可以与申请人交流,如果审核人通过请求,那么main分支会被申请人申请的分支覆盖。

    Git

    参考资料

    Git的简介

    定义:Git是分布式版本控制系统。那什么是分布式?版本控制系统又是什么?
    分布式:
    集中式版本控制系统有服务器和客户端之分,服务器上才有完整的版本库;这意味着一名开发者需要先从服务器下载最新的版本,然后在自己的客户端上修改,修改完毕后在推送到服务器中

    集中式版本控制系统受网络影响很大,如果网络很慢甚至没网,下载和上传会花太长的时间甚至无法进行。
    而git时分布式的,这意味着没有服务器和客户端之分(或者说每个开发者同时扮演着服务器和客户端的角色),每个开发者都可以在本地建立完整的版本库;因为每个人都有完整的版本库,就不要联网才能进行版本控制了。那么不同的开发者要如何合作呢?只需要互相推送修改信息即可。当需要和别人合作时,往往我们会建立一个中央服务器,来方便大家的交换大家的修改,而不是把修改直接推送别人的电脑上(因为他可能没开机呀)。

    下面通过一个比喻来区别集中式和分布式版本控制系统的区别。假如10同学一起修改作文,却只有一张作文纸和版本记录表放在讲台上,每个人要修改作文都必须先从讲台抄写下文章的内容,修改完毕后在提交上去整合;而分布式每个人都有属于自己的作文纸和版本记录表,各种修改,最后在汇集在一起交流修改信息进行合并。
    版本控制系统:
    举个例子,假如目前你有一篇放在word文档里面的作文,你想对他进行修改,因为你害怕修改不成功或者出什么意外,所以你想保存着原来的文件,并复制一份新的文件在上面修改,最后保存,后面你可能又想接着修改,又是复制一份新文件并修改保存,以此类推,就会有一个又一个的修改文件。有一天,你想还原某一除修改的部分,就需要一个个地去查找原先的文件,查看修改的轨迹,非常麻烦;
    同样是你有一篇存放在word中的作文,你和你的好朋友一起对它修改,当你们修改完毕后,还需要相互交流具体修改了哪里,以便把两个的修改合并在一起,这也是不方便的。
    上面不方便的原因就是需要人去管理一个又一个的版本(一个又一个的修改文件),如果能开发一个软件,让机器帮我们管理就好了,软件使用起来应该是下面这个样子,

    这就是版本控制软件

    Git的使用

    Git之创建标识

    因为Git是分布式版本控制系统,所以每个机器都需要自报家门,即用户名和电子邮件

    git config --global user.name "your name"
    git config --global user.email "your email"
    

    建议用户名和邮件于自己github帐号一致

    Git之创建版本库

    首先让我们来建立一个空的版本库

    midir ~/git/Hello
    cd ~/git/Hello
    git init
    

    我们先新建了一个空目录~/git/Hello,然后进入该目录,接着执行初始化命令,把该目录变成版本库,这时候我们会发现该目录下出现了./git目录,里面的内容就是来管理版本库的。
    接着在这个仓库中新建readme.txt文件,然后依次输入命名

    git add readme.txt
    
    git commit -m "Create readme.txt"
    

    我们就进行了一次版本更新。
    我们还可以上述命令下git状态的变化
    git status可以查看git状态,该命令会显示那些文件被修改了,那些文件放在暂存区等信息
    git diff <文件名> 可以具体查看文件修改的情况

    版本改变

    git是版本控制软件,记录了版本的变化情况,就像单机游戏会记录没一个关卡的存档一样,我们可以根据版本号进行版本的改变
    版本回退
    输入命令:

    git log
    

    会显示当前版权前的历史信息,如图所示:

    commit后面的是版本号,用来唯一表示版本;还有作者信息,时间,具体修改的文件信息。其中HEAD用来指代当前的版本号,HEAD、HEAD...用来指代上一个上上个...版本号,如果不想写太多,可以HEAD~n指代上n个版本号
    如果我们觉得上面的输出太繁琐,可以输入下面的命令

    git log --pretty=oneline
    


    输出结果明显精简多了

    根据git log提供的版本信息,我们可以通过版本号来返回之前的版本,命令如下:

    git reset --hard <版本号>
    

    <版本号>可填具体的版本号,也可以是HEAD指代

    版本前进
    如果你对版本回退后悔了,想回到之前那个更新的版本该怎么办呢?
    输入git log命令你会发现,该命令只会显示当前版本之前的版本,最新的版本号已经没有了。我们可以通过输入以下的命令来解决

    git reflog
    

    这个命令记录了在不同版本下的操作,其中就能找到你需要的版本号,在通过git reset --hard <版本号>命令即可前进到新的版本

    撤销修改

    (1)如果你乱改了某一个文件,想还原,输入命令git checkout filename即可
    (2)如果你乱改了某一个文件,并且已经输入了命令git add filename,就需要输入命令git reset --hard HEAD
    (3)如果你乱改了某一个文件,同时输入了添加和提交命令,就需要利用版本回退的知识来还原,例如,git reset --hard HEAD^

    删除命令

    我们往往删除一个文件,在把修改添加到暂存区都会输入以下命令

    rm filename
    git add filename
    

    上面的命令等效于

    git rm filename
    

    远程仓库

    首先我们先在github上创建一个远程仓库Hello

    远程仓库的地址如图可以获取:

    http:push时需要输入用户名和密码,clone则不用
    ssh:使用前要为了自己的电脑配置好ssh密钥,然后在添加到你的github中(添加ssh教程)
    关联远程仓库

    git remote add origin 远程仓库地址
    

    本质上就是变量赋值,让origin存储这远程仓库的具体地址,方便我们后面的使用(在使用远程仓库地址时输入变量名origin就可以了)
    本地仓库推送到远程仓库
    输入

    git push [-u] origin main
    

    将本地仓库的main推送到远程仓库origin的main中
    我们可以看到远程仓库的内容和本地仓库一样了

    远程仓库克隆到本地仓库

    git clone 远程仓库地址
    

    你会发现当前目录下新出现一个目录,即是对远程仓库克隆。

    分支

    每次提交,都会生成一个提交点,git将一个个的提交点根据时间,串成一条时间线,一条时间线就是一条分支。
    一开始,只有master一个分支,从物理结构上我们可以看到master指针指向最新的提交点,HEAD指针指向master。

    这时候我们创建了一个新的分支dev,并让HEAD指向它(表示当前分支为dev)

    从现在开始,提交针对dev分支,其实就是master指针固定不动

    我们最后把dev合并到main中,其中就是master指向dev指向的提交点

    最后删除dev分支,其中就是删除dev指针

    分支的常用命令
    查看分支:git branch
    创建分支:git branch 新分支名
    删除分支:git branch -d 分支名
    切换分支:git switch 分支名git checkout 分支名
    创建并切换分支:git switch -c 分支名git checkout -b 新分支名
    合并某分支到当前分支:git merge 分支名
    解决合并冲突
    一般情况下,在新建分支下提交,最后在main分支下通过git merge 新建分支名命令,即可将新建分支合并与main分支上


    但是加入,在新建分支后,新建分支和main分支都进行了提交,使用git merge 新建分支名命令就会发生冲突,这时我们需要解决冲突
    举个例子:
    (1)创建并切换分支git switch -c feature1
    (2)修改README.md文件并提交(将"feature"添加到最后一行)
    (3)接着通过git switch main切换为main分支,修改README.md文件并提交(将"main"添加到最后一行)
    (4)执行命令git merge feature1,你会发现出现了冲突信息

    (5)解决冲突:打开冲突文件README.md,我们能看到具体的冲突写进了文件中

    "<<<<<<<HEAD"到"="之间的内容 与 "="到">>>>>>>feature1"之间的内容 分别为main分支和feature分支冲突的具体内容,其他的内容一致。接着我们手动修改文件为

    再提交即可。整个流程用下图表示:


    分支管理策略
    main分支:作为发布新版本的地方
    dev分支:用来工作
    bug分支:用来修改bug
    feature分支:有来增加新功能

    Git之管理下的目录结构(逻辑结构)

    Git管理的目录分为工作区和版本库,工作区就是我们能看到的文件,版本库就是隐藏文件.git;版本库可以进一步分为暂存区(stage/index)和分支(默认有一个main/master分支)。

    上图工作流程的类比:假如你出生在电脑发明前的年代,正在写一本教材,你会怎么做呢?你会有一个工作台,上面是你写书的地方,写好了书,就把复印件放在书架上,觉得是时候发表了,就在把书架上的书复印一份,寄到出版社发表,于是你有了书籍1.0。但是,知识是不断更新变化的,你肯定需要对他进行修改,于是你在工具区修改了书籍一部分后,就会把修改的部分copy到书架上的复印件上,等到书架上的复印件修改成熟后,你就接着把书架上的书复印一份发至出版社,就有了书籍2.0......
    在上面的概念下,重新理解之前学到的命令。
    (1)git init:该命令的作用是将当前目录变成git能够管理的目录,即添加了.git文件这个版本库
    (2)git add filename该命令的作用是将工作区的文件的修改添加到暂存区中,为最后提交到分支做准备
    (3)git diff filename该命令的作用是查看工作区的某个文件相较于暂存区的差异
    (4)git checkout -- filename该命令的作用是通过暂存区存储的文件撤销工作区的修改,具体就是用暂存取的内容覆盖工具区的内容。是git add filename命令的反向操作
    (5)git commit -m <message>该命令的作用是将暂存区的内容添加到分支中
    (6)git diff --cached filename该命令的作用是比较暂存区和分支HEAD版本某个文件的差异
    (7)git reset 版本号 filename该命令的作用是将分支的某个版本的文件覆盖暂存取
    (8)git reset --hard 版本号该命令的作用是将分支的某个版本覆盖暂存区和工作区

    Git内部原理(物理结构)

    参考资料
    .................................TO DO.................................................................

    Git和GitHub实战

    参考链接
    参考链接

  • 相关阅读:
    Vijos1986
    vijos1790
    洛谷1005
    洛谷3381
    bzoj4034
    bzoj1564
    bzoj2648
    洛谷3348
    jzoi4964
    codevs3990
  • 原文地址:https://www.cnblogs.com/Serenaxy/p/14090335.html
Copyright © 2011-2022 走看看