• git使用和理解之一(不含分支)


    0、前言

    • Workspace:工作区
    • Index / Stage:暂存区
    • Repository:仓库区(或本地仓库)
    • Remote:远程仓库

    工作区和暂存区
      我们写代码的地方就是工作区,代码写完后,我们可以把他提交到暂存区,提交到暂存区后,我们可以对自己的代码进行更改,修改文件内容,删除或者增加文件,只需一个git checkout xx即可让暂存区内容覆盖当前工作区的内容,或者说还原!

    暂存区(暂时存用)和本地仓库
      我们可以把暂存区的内容提交到我们的本地仓库,此时会在仓库中生成一个快照,我们可以为这个快照打一个TAG信息,比如这个快照叫"完成了UI部分"这样,提交后暂存区中的内容就会被清空,此时我们可以调用reset指令,制定某个快照,然后还原到暂存区

    工作区和本地仓库
      我们可以直接走checkout某个版本的指令,直接让工作空间还原成某个本地仓库中的某个快照

    本地仓库和远程仓库

      我们可以将本地的某个快照push推送到远程仓库,push时可能还需处理一些冲突;也可以从拉取远程仓库到本地,也会有冲突出现。

    工作区和远程仓库

      这两者的协作一般是pull,即同步远程仓库的代码到工作空间而已~

    .git隐藏文件夹各种文件的含义

     .gitignore的文件  commit的时候会忽略,push pull的时候都会忽略

    git中文件的状态     Tracked(已跟踪)    Untracked(未跟踪)   Staged(暂存)    Unmodified(未修改)    Modified(修改)

     TrackedUntracked区分依据:该文件是否已经加入版本控制?当我们在项目中新增一个文件,这个文件此时就处于Untracked状态!

    git add指令将该文件加入暂存区,那么此时该文件此时处于Tracked状态,又或者说这个文件已经被我们的版本控制系统所跟踪了,而且他处于Staged(暂存)状态!

    把暂存区的文件commit后,此时该文件处于Unmodified(未修改)状态;此时假如我们编辑下该文件,文件又会变成Modified(修改)状态,接着git add又处于Staged(暂存)状态,然后commit...

     1、在master分支操作的五部曲(本地master到远端origin的master分支) --》这里的origin指的是远端的主机名字,可以自定义,默认为origin。

      ①  git status       ---    查看工作区对比上一个commit之后的工作区修改状态  

      ②  git add -A      ---    把工作区的内容提交到暂存区  也就是图中的Index中(-A代表的是全部,如果不想提交全部,那么换成指定的文件名)

      ③  git commit -m "备注的内容"   ---  把Index暂存区的内容提交到本地仓库中。

      ④  git pull    ---  拉去远端默认分支上的代码,并主动与本地仓库的内容进行合并,此处要注意conflict出现。

      ⑤  git push   ---   把本地仓库的代码推送到远端默认仓库

    备注:

    A  git status分别可以在②和③之前用,随时查看当前状态,②之前显示的是红色内容,③之前显示的绿色   Untracked是红色,git add后变成绿色色,git commit后变成普通颜色,

    B  ②③步两步可用git commit -a -m "备注的内容" (或者git commit -am "备注的内容"  ) 一步给代替,效果如图2。

    C  为什么会有②③这两个看似重复的步骤呢?直接改成一步不好吗?

    暂存区 Index的作用:在commit前面的暂存区是可以随意的将各种文件的修改放进去的,这样我们就可以用多个指令精确的挑选出我们需要提交的所有修改,然后再一次性的(原子性的)提交到版本库。

    原子性提交,每一个提交都是由多个文件的修改组成,而且这个提交是原子性的,要么这些修改全部成功,要么全部失败。
    原子性提交带来的好处是显而易见的,这使得我们把项目整体还原到某个阶段或者时间点变得极为简便

    D  出现了conflict怎么办?        (出现冲突会有两种情况------  一是:pull以后,远端和本地  二是:分支merge或者pop以后,本地的不同分支)

     合并冲突,最后重新走一遍上述步骤,add commit pull最后push(在合并冲突的过程会发现现在所处的位置 分支名/mergin)

     <<<<<<< HEAD

    自己本地的内容
      =======

    后加进来的内容
    >>>>>> 

    看看留哪个,把不用的和<<<<<<< =======>>>>>>>一起删去 ,注意把 <<<<<<< =======>>>>>>> 多出来的空行也删掉,否则下次还会冲突, git是按行来记录内容的,他不会智能的跳过空行

    E  如果想pull或者push任意分支到任意分支怎么办?origin代表远端仓库   (这里需要搞清楚本地的所站在的分支和远端的分支两个概念)

        ①  git pull origin "分支名a"   ---    代表把  远端的分支名a  拉取到到当前所站在的分支上  括号里的就代表当前所站在的分支

         同理  git push origin "分支b"   ---  代表把当前所站在的分支内容推送到 远端分支b 

        ②  git pull origin "远端分支名c" : "本地分支名d"  ---    代表推送或者拉去指定分支到指定分支

       git push origin "本地分支名d" : "远端分支名c"

     注意:分支推送顺序的写法是<来源地>:<目的地>   所以: git pull是<远程分支>:<本地分支>,git push是<本地分支>:<远程分支>

        ③  当推送push到远端的时候,远端并没有你所写的分支会怎么办??远端会自动创建你写的分支名,并进行push操作。

    F  git add -A进行了操作了哪些文件呢?  

    被修改过或已删除文件和所有untracted的文件(新建的文件),与之相对应的是 git add -u,它修改过或已删除文件的信息添加到索引库。它不会处理untracted的文件(未跟踪的新文件)

    G  git pull相当于git fetch+git merge,意思是:取回远程主机某个分支的更新,再与本地的指定分支合并(一下子进行了两步操作)

    2、git remote命令(让你和远端仓库打交道)

    Git要求每个远程主机都必须指定一个主机名。git remote命令就用于管理主机名。不带选项的时候,git remote命令列出所有远程主机

    命令列表:

    。$ git remote 命令列出所有远程主机。  ---  origin

    $ git remote -v 参看远程主机的网址   --- https://github.com/yang123guo/git_test.git 

    $ git remote add <主机名> <网址>     --  用于添加远程主机。

    $ git remote rm <主机名>          --  用于删除远程主机。

    $ git remote rename <原主机名> <新主机名>    --  用于远程主机的改名。

    3、本地项目和远端仓库建立连接(本地仓库推送到远端仓库)

    情况1:本地没有项目,从远端地址用git clone,这是会自动建立连接 

         在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动"追踪"origin/master分支。

    情况2:本地已经有项目

    a、首先先init,得到隐藏的git文件夹(两种方法,一种是在目录下右键选择  Git init Here,另外一种是在node环境下输入 git init)

    b、用git add -A 和git commit -m '' 先保存到本地git中

    c、

    第一句的意思是:添加一个远端的仓库,并申明地址url,其中git remote是操作远端的意思 add是添加的意思,origin代表远端的主机名(可以随便起,但第一个习惯用origin)最后的url是远端仓库地址

    第二句的意思是:把本地仓库push到远程仓库(git push),并把origin设为默认主机和master为主分支   -u是在本地分支与远程分支之间,建立一种追踪关系(tracking)

             -u 等于 --set-upstream(建立追踪关系)

    注意:在远端的github上的仓库里面不能内容(即使一个README.md文件也能让你push失败)

    4、追踪关系是个什么东东??

    在Git中‘追踪分支’是用与联系本地分支和远程分支的.

    如果你在’追踪分支'(Tracking Branches)上执行推送(push)或拉取(pull)时, 它会自动推送(push)或拉取(pull)到关联的远程分支上.

    git clone命令会自动在本地建立一个'master'分支,它是'origin/master'的‘追踪分支’. 而'origin/master'就是被克隆(clone)仓库的'master'分支.

    你之前push过(git  push origin dev:dev),但是不代表已经建立了追踪关系,要正真的关系需要git push --set-upstream origin dev建立关系,

    建立关系以后就可以用最简单的  (git push 主机名 分支名),当你只有唯一的主机和分支名(唯一追踪),用(git push)。

    5、git push与git pull的补充

    如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。

    $ git push origin :master     等同于    $ git push origin --delete master       表示删除origin主机的master分支。

    $ git push -u origin master     上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。(以上提到过)

    --force   (git push --force 强制推送)  尽量不用
     

    6、git config  配置 命令

     获得和设置配置变量,这些变量可以控制Git的外观和操作的各个方面,他们会在三个地方被保存

      1./etc/gitconfig 文件:   包含了适用于系统所有用户和所有库的值。如果你传递参数选项’--system’ 给 git config,它将明确的读和写这个文件。  

      2.~/.gitconfig 文件 :     具体到你的用户。你可以通过传递--global 选项使Git 读或写这个特定的文件。

      3.位于git目录的config文件 (也就是 .git/config) :   无论你当前在用的库是什么,特定指向该单一的库。每个级别重写前一个级别的值。因此,在.git/config中的值覆盖了在/etc/gitconfig中的同一个值。

    操作指令:

    git config --list    ----   列出所有git里面的配置信息        其中git config  具体属性(如:git config user.name)   ---   会给出相应的信息

    全局配置用户名和邮箱 ---  这个最常用,配置好以后就不用每次提交的时候输入了,这个地方配置我们的身份信息,作为自己参与团队协作的一个身份标记,比如谁对某个文件进行了修改。(用git config --list查看)

    $ git config --global user.name 用户名      

    $ git config --global user.email 邮箱

    私人配置用 git config --local   (user.name 用户名  或者 user.email 邮箱)

    其他配置

    $ git config --global core.editor  xx编辑器   配置你的缺省文本编辑器

    $ git config --global merge.tool xx diff工具  配置diff工具

    别名修改(嫌长难记),(git config --global alias.别名 '指定名称')

    比如把git status中的status变成st    $ git config --global alias.st status

    7、git  log日志       按q键退出

    git log    命令显示从最近到最远的提交日志。
    git log  --pretty=oneline    如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数,一行显示,只显示哈希值和提交说明
     
    还有许多许多参数。。。。。略
     
    按一定的条件来筛选log
     
    1. 按数量
      1. -n:显示前n条log      git log -2  显示最近两条
    1. 按日期
      1. --after=
      1. 比如git log --after="2014-7-1”,显示2014年7月1号之后的commit(包含7月1号)
      2. 后边的日期还可以用相对时间表示,比如"1 week ago"和”yesterday",比如git log --after="yesterday"
      3. 这里的格式可以是什么?
      1. --before=
      1. 同上
      2. 另外这两条命令可以同时使用表示时间段,比如git log --after="2014-7-1" --before="2014-7-4"
      3. 另外--since --until和 --after --before是一个意思,都可以用
    1. 按作者
      1. --author=
      1. 比如git log --author=“John",显示John贡献的commit
      2. 注意:作者名不需要精确匹配,只需要包含就行了
      3. 而且:可以使用正则表达式,比如git log --author="John|Mary”,搜索Marry和John贡献的commit
      4. 而且:这个--author不仅包含名还包含email, 所以你可以用这个搜索email
    1. 按commit描述
      1. --grep=
      1. 比如:git log --grep="JRA-224"
      2. 而且:可以传入-i用来忽略大小写
      3. 注意:如果想同时使用--grep和--author,必须在附加一个--all-match参数
    1. 按文件
      1. - -(空格)或[没有]
      1. 有时你可能只对某个文件的修改感兴趣, 你只想查看跟某个文件相关的历史信息, 你只需要插入你感兴趣文件的路径[对,是路径,所以经常是不太好用]就可以了
      2. 比如:git log -- foo.py bar.py ,只返回和foo.py或bar.py相关的commit
      3. 这里的--是告诉Git后面的参数是文件路径而不是branch的名字. 如果后面的文件路径不会和某个branch产生混淆, 你可以省略- -,比如git log foo.py 
      4. 另外,后边的路径还支持正则,比如:git log  *install.md 是,指定项目路径下的所有以install.md结尾的文件的提交历史
      5. 另外,文件名应该放到参数的最后位置,通常在前面加上--并用空格隔开表示是文件
      6. 另外,git log file/ 查看file文件夹下所有文件的提交记录
    1. 按分支
      1. - -
      1. --branchName branchName为任意一个分支名字,查看某个分支上的提交记录
      2. 需要放到参数中的最后位置处
      3. 如果分支名与文件名相同,系统会提示错 误,可通过--选项来指定给定的参数是分支名还是文件名
      1. 比如:在当前分支中有一个名为v1的文件,同时还存在一个名为v1的分支
      2. git log v1 -- 此时的v1代表的是分支名字(--后边是空的)
      3. git log -- v1 此时的v1代表的是名为v1的文件
      4. git log v1 -- v1 代表v1分支下的v1文件
    1. 按内容
      1. -S"<string>"、-G"<string>"
      1. 有时你想搜索和新增或删除某行代码相关的commit. 可以使用这条命令
      2. 假设你想知道Hello, World!这句话是什么时候加入到项目里去的,可以用:git log -S"Hello,World!"
      3. 另外:如果你想使用正则表达式去匹配而不是字符串, 那么你可以使用-G代替-S.
      4. 这是一个非常有用的debug工具, 使用他你可以定位所有跟某行代码相关的commit. 甚至可以查看某行是什么时候被copy的, 什么时候移到另外一个文件中去的
      5. 注:-S后没有"=",与查询内容之间也没有空格符
    1. 按范围
      1. git log <since>..<until>
      1. 这个命令可以查看某个范围的commit
      2. 这个命令非常有用当你使用branch做为range参数的时候. 能很方便的显示2个branch之间的不同
      3. 比如:git log master..feature,master..feature这个range包含了在feature有而在master没有的所有commit,同样,如果是feature..master包含所有master有但是feature没有的commit
      4. 另外,如果是三个点,表示或的意思:git log master...test 查询master或test分支中的提交记录
    1. 过滤掉merge commit
      1. --no-merges
      1. 默认情况下git log会输出merge commit.  你可以通过--no-merges标记来过滤掉merge commit,git log --no-merges
      2. 另外,如果你只对merge commit感兴趣可以使用—merges,git log --merges
    1. 按标签tag
      1. git log v1.0
      1. 直接这样是查询标签之前的commit
      2. 加两个点git log v1.0.. 查询从v1.0以后的提交历史记录(不包含v1.0)
    1. 按commit
      1. git log commit :查询commit之前的记录,包含commit
      2. git log commit1 commit2:查询commit1与commit2之间的记录,包括commit1和commit2
      3. git log commit1..commit2:同上,但是不包括commit1
      1. 其中,commit可以是提交哈希值的简写模式,也可以使用HEAD代替
      1. HEAD代表最后一次提交,HEAD^为最后一个提交的父提交,等同于HEAD~1
      2. HEAD~2代表倒数第二次提交

    8、版本切换和回退、删除 

       删除:工作区的文件       rm(linux命令)或者 右键  

       工作区的回退:1、只修改了工作区的内容,还没有add,忘记修改内容并且ctrl+s保存了很多次代码,或者是误删除了东西    采取的回退方式是:暂存区内容覆盖当前工作区的内容  git checkout  -- xxxx

                         2、修改并且已经add,但还没有commit ,这时候记录在index暂存区有了记录,此时checkout文件是没用了,得本地仓库回退覆盖(git reset)让当前文件回到上一次提交时的状态

                  此时先 git reset HEAD XX文件 (理解为:暂存区的修改撤销掉) 此时再调用: git checkout -- XX文件 (空暂存区覆盖工作区)  工作区的文件即可恢复原样!

         版本回退:    版本:用commit提交到本地仓库所生成的一个快照,用HEAD表示当前版本,用git log打印出来的版本ID是十六进制的哈希算法值,如:ea34578d5496d7dd233c827ed32a8cd576c5ee85

              上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

              所以表示版本信息有三种方法   1、 HEAD^n   2、HAED@{n}(1,2按版本保存顺序找,弊端:只能回退不能前进,回退以后比他还晚的就消失了)   3、版本ID  十六进制的哈希算法值 , 如:ea34578d5496d7dd233c827ed32a8cd576c5ee85 

              回退版本的指令是: git reset --hard 版本   (如:回到上一个版本 git reset --hard HEAD^ )    回到任意一个版本  (git reset --hard 3628164/版本ID输入几位就可以了)

             这里的版本回退主要是针对本地仓库来说的,本地的工作区和暂存区是同时会跟着的。

       重返未来(找回回退):git reflog  找回并列出所有版本序列(包括已经删除的,不过有几个月的时间限制,太久了也不行)   git reset --hard  版本  回到未来版本,此时你可以看见列表区域的HAED是重新计算过的,

              

             如图

              其中的    暂存---->工作区   的checkout意思是:checkout可以让暂存东西覆盖工作区,而不是add命令以后 修改内容进入了暂存区再使用checkout,这时候checkout已经无效了。(他的原理是 从 ..  到 ..  的指针指向导致的覆盖

              同理的还有git reset命令,也是从前到后的覆盖,按图中的意思是:版本回退的机理是仓库覆盖了index暂存。     ---- 对的,但是注意的是git reset HEAD XX文件最后是文件名而不是版本号

              问题:那么版本回退reset的时候只是本地覆盖暂存吗?本地仓库变了没?可不可以直接push??     结论:可以直接push,push以后是变更后了本地仓库内容,此时本地工作区也跟着变了。说明reset可以在本地仓库多个历史版本中切换。

    结论:git reset 有两种回退方法:图中给出了本地仓库到暂存区的回退 git reset HEAD XX文件 (HEAD 未加版本号代表当前最新版本) 

       本地仓库之间也可以相互回退跨越 git reset --hard  HEAD 版本  (此时相关的工作区也是跟着变化了)     对比    git reset  HEAD 版本(工作区不跟着变化)

          git checkout -- 文件名  命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令

    9、其他  

    Git命令的自动补全    ------      输入git命令后   按Tab就可以了

  • 相关阅读:
    利用Python进行数据分析_Pandas_绘图和可视化_Matplotlib
    利用Python进行数据分析_Pandas_数据清理、转换、合并、重塑
    利用Python进行数据分析_Pandas_数据加载、存储与文件格式
    利用Python进行数据分析_Pandas_层次化索引
    利用Python进行数据分析_Pandas_处理缺失数据
    利用Python进行数据分析_Pandas_汇总和计算描述统计
    利用Python进行数据分析_Pandas_基本功能
    利用Python进行数据分析_Pandas_数据结构
    fizzbuzz Python很有意思的解法
    javascript Array操作
  • 原文地址:https://www.cnblogs.com/faith3/p/6103218.html
Copyright © 2020-2023  润新知