美文网首页
Git学习笔记

Git学习笔记

作者: sayonara_yoyo | 来源:发表于2017-06-28 10:56 被阅读0次

    git学习笔记

    声明

    本文是本人学习Git过程中所做的笔记,以便日后查阅,文中多有错漏之处,不建议用作学习材料,文章内容来自网络,如需学习请移步原文:

    Git教程-廖雪峰的官网网站
    Git远程操作讲解-阮一峰的网络日志

    Git诞生

    2002年BitMover授权Linux社区免费使用BitKeeper版本控制系统
    2005年有人试图破解BitKeeper的协议导致BitMover要收回Linux社区的使用权限

    Linus花费两周时间使用C语言写了一个分布式版本控制系统,即git

    集中式&分布式

    什么是集中式版本控制系统

    • 集中式版本控制系统的版本库统一存放在中央服务器,每次编程时都要先从中央服务器取得最新版本,完成后再把自己的版本推送给服务器
    • 缺陷:需要联网才能工作

    分布式版本控制系统(distributed version control system)

    • 分布式版本控制系统没有中央服务器,每台电脑都是一个完整的版本库,可以通过推送获取最新版本

    • 优点:

      1. 没有中央服务器,不需要联网

      通常分布式版本控制系统中有一台充当服务器的电脑,方便交换大家的修改

      1. 安全性高:每个人的电脑都是版本库
      2. Git的分支管理功能强大(branch)

    安装git

    git命令可以查看系统有没有安装git

        $ git
        usage: git [--version] [--help] [-C <path>] [-c name=value]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]
    

    Linux系统安装

    • Linux 使用命令即可直接安装
      sudo apt-get install git

    Windows上安装git

    • Windows上安装git需要通过模拟Linux运行环境来完成,这里直接使用msysgit下载地址

    至此Git的安装已经完成,下面是Git的学习阶段

    Git学习-版本库

    1. 什么是版本库
      版本库(Repository)又名仓库,仓库里的文件都可以由git管理起来,git会对每个文件的修改删除进行跟踪,一遍将来的某个时刻可以还原

    2. 创建版本库
      创建版本库只需要创建一个文件夹然后通知Git讲次文件夹作为仓库管理

       $ mkdir gitlearn
       $ cd gitlearn
       $ pwd
       /c/Users/lc/learngit
       //创建git文件夹
       $ git init
       Initialized empty Git repository in C:/Users/lc/learngit/.git/
      
    3. 版本控制系统只能跟踪文本的改动,不能跟踪文本的内容,Microsoft Word的格式是二进制的,版本控制系统无法跟踪改动

    Git学习-版本提交

    • 版本提交分为两步
      1. git add <file>命令把文件添加到暂存区
      2. git commit命令告知Git,将文件提交到仓库
        $ git commit -m "wrote a readme file"
        //-m 命令是对本次提交的说明,输入本次提交的内容

    Git学习-时空穿梭

    git status命令可以查看是否有文件被修改过

    git status 主要用于查看仓库当前状态,比如哪些文件被修改,是否准备提交

    git diff可以查看修改的内容

    只限于文件被添加到暂存区之前,一旦执行了git add命令,git diff就不能查看更改了

              git diff 常用的命令
              HEAD commit版本
              Index staged版本
              git diff//比较工作目录和暂存区快照之间的差异
                     //即修改单还没有暂存的内容
              git diff --cached
              git diff --staged
              //未发现区别
    
              git diff HEAD
              //显示工作版本(work tree)和HEAD之间的查表
    
              git diff topic master
              git diff topic..master
              //显示两个分支最新提交的区别
              git diff HEAD^ HEAD
              //显示上次提交commit和上上次提交之间的差别
    

    git add的各种区别

          git add -A   // 添加所有改动
          git add *     // 添加新建文件和修改,但是不包括删除
          git add .    // 添加新建文件和修改,但是不包括删除
          git add -u   // 添加修改和删除,但是不包括新建文件
    

    在commit前撤销add:

        git reset <file> // 撤销提交单独文件
        git reset        // unstage all due changes
    

    add/commit前撤销对文件的修改:

        git checkout -- README.md  // 注意, add添加后(同commit提交后)就无法通过这种方式撤销修改
    

    Git学习-版本回退

    查看历史记录:

        $ git log
        //长串的编码是commit id(版本号)
        commit 75d2bf408c157c0b5c9255f81a6dd7116670f1cb
        Author: Shenglong <liushenglong@wemarklinks.com>
        Date:   Tue Jun 27 11:45:28 2017 +0800
    
            2.0 version
    
        commit 2b9e2e1c667378bf00662c173d70581724d53bd0
        Author: Shenglong <liushenglong@wemarklinks.com>
        Date:   Tue Jun 27 11:13:53 2017 +0800
    
            find some Syntax Error
    
        commit b193cdc3b9951c23279d45e04aed326ec3a866c5
        Author: Shenglong <liushenglong@wemarklinks.com>
        Date:   Tue Jun 27 09:52:12 2017 +0800
    
            test git
    

    Git中 HEAD表示当前版本,HEAD表示上一个版本,HEAD^ 表示上上个版本
    HEAD~100表示向上100个版本

    版本回退git reset

        $ git reset --hard HEAD^
        HEAD is now at 2b9e2e1 find some Syntax Error
        //已经回退到上一个版本
    

    再来查看版本库的状态

        $ git log
        commit 2b9e2e1c667378bf00662c173d70581724d53bd0
        Author: Shenglong <liushenglong@wemarklinks.com>
        Date:   Tue Jun 27 11:13:53 2017 +0800
    
            find some Syntax Error
    
        commit b193cdc3b9951c23279d45e04aed326ec3a866c5
        Author: Shenglong <liushenglong@wemarklinks.com>
        Date:   Tue Jun 27 09:52:12 2017 +0800
    
            test git
    

    回退了一个版本,可以通过之前的版本id恢复版本或者继续回退

        $ git reset --hard 75d2bf408c
    

    查看readme.txt内容

        $ cat readme.txt
        git is a distributed version control System
        i'm alittle confuse about how this worked
        git is free software
    

    版本回退的原理:Git内部有一个指向当前版本的HEAD指针,回退版本的时候git仅仅是把指针前移了一位

    后悔药:git reflog,回退一个版本之后如果想退回原来的版本必须使用之前版本的commit id,然后使用git reset --hard commit id即可返回最新提交的版本

    Git学习-工作区与暂存区

    工作区(Working Directory)工作目录
    版本库(Repository)工作区有一个隐藏目录,版本库中包含stage(暂存区也可以称为Index),以及Git创建的第一个分支master,以及指向master的一个指针HEAD

    0.jpg

    Git学习-管理修改

    git commit的作用是将暂存区中的修改应用到版本库中,未提交到暂存区的修改不会保存

    git diff HEAD --readme.txt可以查看工作区里和版本库里最新版本的区别

    Git学习-撤销修改

    在修改未被提交到工作区之前可以使用git checkout -- <file>命令丢弃工作区的修改

    exam:

        $ cat readme.txt
        git is a distributed version control System
        i'm alittle confuse about how this worked
        git is free software
        git is full of fun!
        wrong message(i don't wanna this to be commit)
        //我在这里犯了个错误,但是修改还没有被提交到暂存区
        //于是..
        $ git checkout -- readme.txt
        //这里看起来什么都没有发生
        $ cat readme.txt
        git is a distributed version control System
        i'm alittle confuse about how this worked
        git is free software
        git is full of fun!
        //但是我错误的修改已经被丢弃了
    

    如果修改被提交到暂存区,可以使用git reset丢弃暂存区的记录回到上一步,然后丢弃工作区的记录即可

    Git学习-删除文件

    如果不小心删除了工作区的文件,git status查看时git 会告诉你哪些文件被删除了

        $ git status
        On branch master
        Changes not staged for commit:
          (use "git add/rm <file>..." to update what will be committed)
          (use "git checkout -- <file>..." to discard changes in working directory)
    
                deleted:    test.txt
    
        no changes added to commit (use "git add" and/or "git commit -a")
    

    此时有两个选择:

    1. 从版本库中删除改文件

       $ git rm test.txt
       rm test.txt
       $ git commit
       $ git commit
       [master 502080a] test.txt has been removed
       1 file changed, 1 deletion(-)
       delete mode 100644 test.txt
       //此时版本库和文件系统中都没有test.txt了
      
    2. git checkout -- <file>如果误删了文件可以使用这个命令,用版本库中的版本替换工作区中的版本

    > `git checkout`命令本质是从版本去检出版本替换掉工作区的版本,虽然可以将文件恢复到最新版本,但是会丢失最近修改的内容
    

    远程仓库

    准备工作

    1. 创建SSH Key

       $ ssh-keygen -t rsa -C "email@url.com"
       Your identification has been saved in /c/Users/lc/.ssh/id_rsa.
       Your public key has been saved in /c/Users/lc/.ssh/id_rsa.pub.
       The key fingerprint is:
       SHA256:R0Qr3PkLDR7RD4Xrn1pUWrzo+TpA+tusnr0eMYT3qB4 liushenglong@wemarklinks.com
       The key's randomart image is:
       +---[RSA 2048]----+
       |         .+. o.  |
       |       . o +=  . |
       |        o B. *  +|
       |         + *+ =+.|
       |        S *.o=oo |
       |         o o+o+  |
       |          .Eo=.. |
       |          ..*o=  |
       |          .*=O+. |
       +----[SHA256]-----+
      
    2. 登录GitHub(Gitlab),进入Account setting,"SSH Key"页面,在Add SSH Key中填入id_rsa.pub中的内容

    添加远程库

    1. 在git上创建库 new Repository

    2. 在本地添加远程库

       $ git remote add origin https://GitHub.com/Sakura3754/learngit.git
       //把本地库推送到远程库上
       $ git push -u origin master
       //第一次向远程库推送时使用了-u参数.Git不但把本地的master分支推送到远程新的master分支,还会把本地的master分支和远程的master分支关联起来
      
    0.png

    提交完成

    1. 从现在起,只要本地做了提交就可以通过git push origin master提交到远程库

    从远程库克隆

    git clone git@github.com:Sakura3754/gitskills.git

    分支管理

    分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN。

    创建与合并分支

    每次提交,git将操作记录串成一条时间线,这条时间线是一个分支,在git里这个分支叫主分支,即master分支.严格来说HEAD不是指向commit,而是指向master,master才是指向commit的

    1.png

    当我们创建分支,例如dev时,Git新建一个指针叫dev,指向master相同的提交,再把HEAD指向dev就表示当前分支在dev上

    2.png

    从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,master指针不变

    4.png

    合并分支:将master指向dev当前的提交就完成了分支的合并

    3.png

    删除分支就是把指针删除掉

    实战:

    1. 创建分支

      $ git checkout -b dev//-b 表示创建并切换
      Switched to a new branch 'dev'
      //上面的命令等价于
      git branch dev//创建分支
      git checkout dev//切换分支

    2. git branch查看当前分支

    - 创建分支`git branch dev`
    - 切换分支`git checkout dev`
    - 创建并切换分支`git checkout -b dev`
    - 查看当前分支`git branch`
    - 合并分支到当前分支`git merge dev`
    - 删除分支`git branch -d dev`
    - 合并冲突时必须手动解决之后再提交
    

    分支管理

    1. 如果使用Fast forword 模式合并分支,删除分支后会丢掉分支信息,可以使用--no-ff参数禁用fast forword模式
    > 使用no-ff模式提交时,由于master不能直接将指针指向dev分支的最新提交,所以master分支只能独立进行一次提交操作,因此有内容一样,但是commit id不同的问题
    
    1. 分支管理原则:
    * `master`分支应该是非常稳定的,仅用来发布新版本,不能在上面干活
    * 所有的操作都在`dev`分支上进行
    * 团队成员都在dev上干活,每个人有自己的分支,时不时往`dev`上合并就可以了
    

    BUG分支

    • 用临时分支来修复bug时,可以将当前分支未提交的内容储存到stash中,等bug修复完成后继续操作
      • git stash保存当前工作进度
      • git stash list读取保存的进度列表
      • git stash apply将保存的进度恢复到工作区但是保留stash中的存档
      • git stash drop删除保存的stash
      • git stash pop取出存档,同时删除stash
      • git apply stash@{0}恢复指定的stash

    Feature分支

    • 在添加一个新功能之前,为了防止实验代码影响主分支内容可以创建一个feature分支,在上面开发完成后合并
    • 丢弃一个没有被合并过的分支可以通过git branch -D强行删除

    多人协作

    • 查看远程库的信息

      • git remote
      • git remote -v查看更加详细的信息
    • 分支推送

      • git push origin dev
      • master分支时主分支,因此要随时与远程库同步
      • dev 时开发分支,所有成员在上面工作,所以也需要同步
      • bug分支无需推送
      • feature 是否推送取决于是否有多人协同开发
    • 抓取分支

      • 从远程库克隆时,只能看到远程库的master分支,如果要在dev分支上开发,就必须创建远程的dev分支到本地

          $ git checkout -b dev origin/dev
          $ git pull <remote> <branch>
        
      • dev上修改并时不时推送到远程

          $ git push origin dev
        
      • 如果碰巧别人也push了对同样文件的修改,则会发生冲突导致提交失败,这是可以用git pull

          //如果提示no tracking information,说明本地分支尚未与远程分支建立连接
          //指定本地dev分支与远程origin分支的链接
          $ git branch --set-upstream dev origin/dev
          $ git pull
          //手动解决冲突之后commit,push
          $ git commit
          $ git push origin dev
        

    标签管理

    创建标签

    • 创建一个标签,总共分三步

      1. 切换到需要打标签的分支git checkout <name>
      2. 打标签 git tag <tagname>
      3. 查看标签git tag

      git show <tagname>查看标签信息

    • 给一个只有id 的commit打标签

      1. git log --pretty=oneline --abbrev-commit找到历史提交的commit id
      2. 打标签git tag <tagname> <commitid>
    • git tag -a <tagname> -m <message> <commitid>创建带有说明的标签,-a指定标签名,-m添加说明文字

    • -s命令可以用PGP签名标签

    操作标签

    • 删除标签git tag -d <tagname>
    • 推送标签到远程git push origin <tagname>
    • 一次推送全部标签git push origin --tags
    • 删除远程标签
      • 先删除本地标签git tag -d <tagname>
      • 然后从远程删除

    自定义Git

    忽略指定文件

    • .gitignore文件中配置需要忽略的文件名,可以使用正则
    • .gitignore文件提交到版本库
    • 检验.gitignore是否生效的标准是git status命令提示working directory clean

    配置别名

    • 使用git config --global alias.<alias> <order>为命令指定别名

    • 花哨的小技巧

          //修改git log的字体样式
          git config --global alias.log "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
      

    补充

    Git clone

    • 用法

        git clone (-o 主机名) <url> <localdir>
      
    • git clone 支持多种协议

        $ git clone http[s]://example.com/path/to/repo.git/
        $ git clone ssh://example.com/path/to/repo.git/
        $ git clone git://example.com/path/to/repo.git/
        $ git clone /opt/git/project.git
        $ git clone file:///opt/git/project.git
        $ git clone ftp[s]://example.com/path/to/repo.git/
        $ git clone rsync://example.com/path/to/repo.git/
      

    remote补充

        $ git remote show <主机名>
        //查看主机信息
        $ git remote add <主机名> <网址>
        //添加主机
        $ git remote rm <主机名>
        //删除主机
        $ git remote rename <原主机名> <新主机名>
        //远程主机改名
    

    git fetch

    • git fetch 通常用于将远程主机的更新(commit)取回本地

       $ git fetch <远程主机名>
       //将远程主机上所有分支取回本地
       $ git fetch <远程主机名> <分支名>
       //将指定分支取回本地
      
    • git fetch取回的更新要用"远程主机名/分支名"的形式读取

    • git branch -r查看远程分支

    • git branch -a查看所有分支

    • 取回远程分支后

        //可以在远程分支的基础上创建一个新的分支
        $ git checkout -b newbranch
        //也可以在本地分支上合并远程分支
        $ git merge origin/master
        $ git rebase origin/master
      
    • git pull/push

        $ git pull <远程主机名> <远程分支>:<本地分支>
        $ git pull <远程主机名> <本地分支>:<远程分支>
        //手动建立本地分支与远程分支的追踪关系
        $ git branch --set-upstream <本地分支> <远程主机/远程分支>
      
    • git push的特殊用法

        //省略远程分支,默认推送到与之有"追踪关系"的远程分支
        $ git push origin master
        //向远程推送空分支相当于删除origin主机上的对应分支
        $ git push origin :master
        #等同于
        $ git push origin --delete master
        # 如果当前分支与多个远程主机关联可以使用`-u`指定默认远程分支
        $ git push -u origin master

    相关文章

      网友评论

          本文标题:Git学习笔记

          本文链接:https://www.haomeiwen.com/subject/fsxucxtx.html