zoukankan      html  css  js  c++  java
  • Git

     版本控制 Git

              为什么使用Git:

                      world,脚本,PPT,程序代码 反复修改时需要回退和统计,需要用版本控制软件。

              使用ftp的缺点:
                     上传相同文件名时,原文件会被覆盖

                      版本库是版本控制的核心,这个库可以被任意数量的用户同时访问,适合整个团队协同完成现一个项目

             Git的流程图:

           

             客户端的 工作区:/root/project/ 

                      工作区只保留最新版本,在客户端上clone之后这个目录会自动生成。

              客户端的 本地仓库:/root/project/.git 

                        保存历史版本,在客户端上clone之后这个目录会自动生成。

              客户端的 暂存区/root/project/.git/HEAD

                        保存被修改文件的索引 。git服务无法直接识别用户具体修改了哪个文件,用户通过add指令把已修改

                       文件的文件名提交到暂存区,再执行commint指令告诉git服务暂存区记录的文件名是修改过的文件。

    Git功能介绍:

    1)  部署Git服务器

    YUM安装Git软件。
    [root@web1 ~]# yum -y install git           #默认已安装
    [root@web1 ~]# git --version
    git version 1.8.3.1
    
    [root@web1 ~]# mkdir /var/git               #建目录,为仓库做准备,目录可以任意
    [root@web1 ~]# git init /var/git/project --bare 
                                                #建一个空仓库,bare是祼的意思
    [root@web1 ~]# ls /var/git
    project                                     #服务器端的源仓库,相当于共享文件夹
    [root@web1 ~]#                              #git服务是不需要启动的,它后台用的是ssh服务,默认ssh已开启
    [root@web1 project]# ls
    branches  config  description  HEAD  hooks  info  objects  refs

    2) clone克隆服务器仓库到本地

    [root@web2 ~]# rpm -q git                   #确认clinet上也安装git
    
    [root@web2 ~]# git clone root@192.168.2.100:/var/git/project 
    正克隆到 'project'...                        #客户端以root从192.168.2.100克隆/var/git/project这个仓库
    Warning: Permanently added '192.168.2.100' (ECDSA) to the list of known hosts.
    root@192.168.2.100's password:             #git服务器端的密码
    warning: 您似乎克隆了一个空版本库。             #克隆成功后,客户端会产生工作区/root/project
    
    [root@web2 ~]# ls
    Desktop   project                          #web2的家目录下会产生project   
    [root@web2 project]# pwd
    /root/project                              #客户端上的工作区,只存放最新版本
    [root@web2 project]# ls -a
    .  ..  .git                                #工作区中执行commit,会把前版本备份到本地仓库./.git
    [root@web2 ~]# cd /root/project/.git/                    
    [root@web2 .git]# pwd
    /root/project/.git                         #客户端上的本地仓库,保存了所有历史版本
    [root@web2 .git]# ls                       #这个目录下的内容是和git服务器上源仓库中的文件一样的
    branches  description  hooks  info  objects      refs
    config    HEAD         index  logs  packed-refs
    [root@web2 .git]# 
    [root@web2 .git]# cat /root/project/.git/HEAD 
                                               #客户端上的暂存区

    3) 修改git客户端配置

                                               #暂存区通过commit提交到本地仓库时,会让提交数据的用户
                                               #出示身份。这里需要提前做身份验证
    [root@web2 project]# git config --global user.email "you@example.com"
    [root@web2 project]# git config --global user.name "Your Name"
    [root@web2 project]# cat  ~/.gitconfig     #存放身份的文件
    [user]
        email = you@example.com
        name = Your Name
    
    3) 本地工作区对数据进行增删改查
                                               #执行操作之前一定要进入本地仓库/root/project/ 
    [root@web2 project]# echo "init date" > init.txt 
                                               #在工作区新增一文件新增一文件
    [root@web2 project]# mkdir demo   
    [root@web2 project]# cp /etc/hosts demo    #在工作区新增一文件夹并放入数据

    4) 查看本地仓库中数据的状态

    [root@web2 project]# git status
    # 位于分支 master
    #
    # 初始提交
    #
    # 未跟踪的文件:                             #因为没有索引,所以这里会显示未跟踪的文件demo,init.txt
    #   (使用 "git add <file>..." 以包含要提交的内容)
                                              #这个方式一次只能提交一个文件,如果要提交
                                              #全部文件用 git add .  “.”代表当前目录
    #    
    #    demo/                                 #罗列出来的未跟踪文件
    #    init.txt
    提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)

    5) 提交到暂存区

    [root@web2 project]# git add .            #将工作区的所有文件全部提交到暂存区,暂存区并
                                              #不实际存储文件,仅是对修改过的文件做个标识

    6) 将暂存区修改提交到本地仓库

    [root@web2 project]# du -sh .git/         #提交前先查看下本地仓库的文件夹大小
    68K    .git/
    [root@web2 project]#
    [root@web2 project]# git commit -m "first version"
    [master(根提交) 3e8bb1a] first version  #注释,这里通常写为什么要修改代码,为何要提交代码
     2 files changed, 3 insertions(+)         #执行这个commit之前,需要身份验证
     create mode 100644 demo/hosts            #demo/hosts文件提交本地仓库成功
     create mode 100644 init.txt              #./init.txt文件提交本地仓库成功
    [root@web2 project]# du -sh .git/         #文件提交本地仓库后查看文件夹大小
    96K    .git/                                 #注意:commit操作相当于把工作区的文件备份到了本
    [root@web2 project]#                      #地仓库,本仓库是以数据库的形式存放的文件,无法
                                              #通过ls查看,只能通过比较文件大小的方式判断
    [root@web2 project]# git status
    # 位于分支 master
    无文件要提交,干净的工作区
    [root@web2 project]# 

    7)本地仓库提交到远程仓库

    [root@web2 project]# git config --global push.default simple
                                             #在第一次执行git push提交远程仓库之前需要确认
                                             #一下,以什么试提交代码,这里用的是simple模式
          
    [root@web2 project]# git push            #把文件提交到服务器,(web2将数据推送到web1)
    root@192.168.2.100's password:           #输入web1主机的密码123456
    Counting objects: 5, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (5/5), 358 bytes | 0 bytes/s, done.
    Total 5 (delta 0), reused 0 (delta 0)
    To root@192.168.2.100:/var/git/project
     * [new branch]      master -> master
    [root@web2 project]# 

    8) 将服务器上的数据更新到本地

    [root@web3 project]# git pull            #web1的数据更新到web3

    9) 查看已修改过文件的版本日志

    [root@web2 project]# git log
    commit 3e8bb1a36e118f201ddfe6a0f01d02f6f71046c7
                                            #文件版本,当前只有一个版本,每执行一次commit就会多一个版本日志
    Author: Your Name <you@example.com>     #谁提交的这个版本
    Date:   Sat Jan 4 17:38:33 2020 +0800   #提交的日期
    
        first version                       #为什么提交这个版本,提交的原因
    [root@web2 project]# 
    
    
    [root@web2 project]# git log --pretty=oneline
                                            #查看版本日志的简洁模式
    3e8bb1a36e118f201ddfe6a0f01d02f6f71046c7 first version
    
    
    [root@web2 project]# git log --oneline
    3e8bb1a first version                   #查看版本日志的最简洁模式
    [root@web2 project]#
    
    [root@web2 project]# git reflog         #简洁日志信息,当需要恢复版本时一定会需要先查看日志
    3e8bb1a HEAD@{0}: commit (initial): first version
    [root@web2 project]# 

     HEAD指针操作  

            HEAD指针是一个可以在任何分支和版本移动的指针,通过移动指针我们可以将数据还
    原至任何版本。每做一次提交操作都会导致git更新一个版本,HEAD指针也跟着自动移动。

    1)  对工作区中文件多少修改,并提交使之产生多个版本

    新建文件new.txt,然后多次在原文件中追加内容每修改一次就提交一次本地仓库,最后上传服务器

    [root@web2 project]# echo "new file" > new.txt
    [root@web2 project]# git add .
    [root@web2 project]# git commit -m "add new.txt"
    [root@web2 project]#
    [root@web2 project]# echo "first" >> new.txt
    [root@web2 project]# git add .
    [root@web2 project]# git commit -m "new.txt:first line"
    [root@web2 project]#
    [root@web2 project]# echo "second" >> new.txt
    [root@web2 project]# git add .
    [root@web2 project]# git commit -m "new.txt:second"
    [root@web2 project]#
    [root@web2 project]# echo "third" >> new.txt
    [root@web2 project]# git add .
    [root@web2 project]# git commit -m "new.txt:third"
    [root@web2 project]#
    [root@web2 project]# git push
                                         #新建一个文件num.txt,对文件内容进行两个重写覆盖,每重写一次提交一个本地仓库,最后上传
                                         #服务器
    [root@web2 project]#
    [root@web2 project]# echo "123" > num.txt
    [root@web2 project]# git add .
    [root@web2 project]# git commit -m "num.txt:123"
    [root@web2 project]#
    [root@web2 project]# echo "456" > num.txt
    [root@web2 project]# git add .
    [root@web2 project]# git commit -m "num.txt:456"
    [root@web2 project]#
    [root@web2 project]# echo "789" > num.txt
    [root@web2 project]# git add .
    [root@web2 project]# git commit -m "num.txt:789"
    [root@web2 project]#
    [root@web2 project]# git push

    2)查看Git版本信息

    如果要恢复数据需要先查看日志,在日志信息可以看到所有修改过的文件的版本
    [root@web2 project]# git reflog      
    a3b9645 HEAD@{0}: commit: num.txt:789
    75e05d2 HEAD@{1}: commit: num.txt:456
    f925288 HEAD@{2}: commit: num.txt:123
    d28d549 HEAD@{3}: commit: new.txt:third
    32e11fa HEAD@{4}: commit: new.txt:second
    17cfdbb HEAD@{5}: commit: new.txt:first line
    ec5dbdc HEAD@{6}: commit: add new.txt
    3e8bb1a HEAD@{7}: commit (initial): first version
    [root@web2 project]# 
    
    [root@web2 project]# git log --oneline 
    a3b9645 num.txt:789                    #查看版本日志的最简洁模式
    75e05d2 num.txt:456
    f925288 num.txt:123
    d28d549 new.txt:third
    32e11fa new.txt:second
    17cfdbb new.txt:first line
    ec5dbdc add new.txt
    3e8bb1a first version
    [root@web2 project]# 

    3)HEAD指针 

    默认情况下head指针是指向当前正在使用的版本,通过移动指令可以把将数据还原到任意版本
    [root@web2 project]# git reflog
    a3b9645 HEAD@{0}: commit: num.txt:789
                                       #<----当前指针在这里,当前HEAD指针为HEAD@{0}
    75e05d2 HEAD@{1}: commit: num.txt:456
    f925288 HEAD@{2}: commit: num.txt:123
    d28d549 HEAD@{3}: commit: new.txt:third
    32e11fa HEAD@{4}: commit: new.txt:second
    17cfdbb HEAD@{5}: commit: new.txt:first line
    ec5dbdc HEAD@{6}: commit: add new.txt
    3e8bb1a HEAD@{7}: commit (initial): first version
    [root@web2 project]#                                    
    
                                       #如果需要把num.txt文件恢复到内容是123的时候
                                       #那么把指令移动到f925288
    [root@web2 project]# git reset --hard f925288
    HEAD 现在位于 f925288 num.txt:123
    [root@web2 project]# cat num.txt   #查看内容已恢复为123
    123
    [root@web2 project]# git reflog    
    f925288 HEAD@{0}: reset: moving to f925288
                                       #指针 HEAD@{0}:已指向 f925288
    a3b9645 HEAD@{1}: commit: num.txt:789
    75e05d2 HEAD@{2}: commit: num.txt:456
    f925288 HEAD@{3}: commit: num.txt:123
    d28d549 HEAD@{4}: commit: new.txt:third
    32e11fa HEAD@{5}: commit: new.txt:second
    17cfdbb HEAD@{6}: commit: new.txt:first line
    ec5dbdc HEAD@{7}: commit: add new.txt
    3e8bb1a HEAD@{8}: commit (initial): first version
    [root@web2 project]# 
                                       #把文件恢复到first line
    [root@web2 project]# git reset --hard 17cfdbb
    HEAD 现在位于 17cfdbb new.txt:first line
    [root@web2 project]#               #把文件恢复到first version
    [root@web2 project]# git reset --hard 3e8bb1a
    HEAD 现在位于 3e8bb1a first version
    [root@web2 project]#               #把文件恢复到789
    [root@web2 project]# git reset --hard a3b9645
    HEAD 现在位于 a3b9645 num.txt:789
    [root@web2 project]# ls
    demo  init.txt  new.txt  num.txt   #所有文件全部被恢复
    [root@web2 project]# 
    [root@web2 project]# git reflog    #再次查看版本信息,原来的指针移动记录会被保存
    a3b9645 HEAD@{0}: reset: moving to a3b9645
    3e8bb1a HEAD@{1}: reset: moving to 3e8bb1a
    17cfdbb HEAD@{2}: reset: moving to 17cfdbb
    f925288 HEAD@{3}: reset: moving to f925288
    a3b9645 HEAD@{4}: commit: num.txt:789
    75e05d2 HEAD@{5}: commit: num.txt:456
    f925288 HEAD@{6}: commit: num.txt:123
    d28d549 HEAD@{7}: commit: new.txt:third
    32e11fa HEAD@{8}: commit: new.txt:second
    17cfdbb HEAD@{9}: commit: new.txt:first line
    ec5dbdc HEAD@{10}: commit: add new.txt
    3e8bb1a HEAD@{11}: commit (initial): first version
    [root@web2 project]# 

    Git分支     

        Git支持按功能模块、时间、版本等标准创建分支,分支可以让开发分多条主线同时进行,每条主线互不影响

    1)查看当前分支

    [root@web2 project]# git status   #git默认只有一个master分枝
    # 位于分支 master
    无文件要提交,干净的工作区
    [root@web2 project]# 
                                      #查看当前所有分枝,*表示当前所在分枝
    [root@web2 project]# git branch -v 
    * master a3b9645 num.txt:789
    [root@web2 project]#

    2)创建分支

    [root@web2 project]# git branch hotfix
    [root@web2 project]# git branch feature
    [root@web2 project]# git branch -v
                                      #创建hostfix.feature这两个分支之后,此时加上master这三个分支中版本的内容是一样的。
                                      #三个分支可以在相同的基础上进行不同功能的开发
      feature a3b9645 num.txt:789
      hotfix  a3b9645 num.txt:789
    * master  a3b9645 num.txt:789
    [root@web2 project]# 

    3)切换分支

    [root@web2 project]# git checkout hotfix 
    切换到分支到'hotfix'                #把当前分枝切换到hotfix
    [root@web2 project]# git branch -v
      feature bcf6ba8 num.txt:789
    * hotfix  bcf6ba8 num.txt:789     #切换成功
      master  bcf6ba8 num.txt:789
    [root@web2 project]#              #当前的hotfix分枝有mster分枝的所有内容,因为它是 
    [root@web2 project]# ls           #复制过来的                              
    demo  init.txt  new.txt  new.txxt  num.txt 

    4 )在新的分支上可以继续进行数据操作(增、删、改、查)

                                      #在hotfix分支下对文件做修改
    [root@web2 project]# echo "fix a bug" >>new.txt
    [root@web2 project]# git add .    #修改new.txt文件内容并提交本地版本库
    [root@web2 project]# git commit -m "fix a bug"
    [hotfix 3ae2a7e] fix a bug
     1 file changed, 1 insertion(+)
    [root@web2 project]# 
    [root@web2 project]# cat new.txt  #确认hostfix分枝上的文件已修改
    new file                          #此时master分枝上并没有被修改
    first
    second
    third
    fix a bug                     
    [root@web2 project]# 
    
                                      #切回到master分枝,验证new.txt文件内容
    [root@web2 project]# git checkout  master
    切换到分支 'master'
    [root@web2 project]# ls
    demo  init.txt  new.txt  new.txxt  num.txt
    [root@web2 project]# cat new.txt
    new file
    first
    second                            #new.txt文件内容没有fix a bug          
    [root@web2 project]# 

    5)将hotfix修改的数据合并到master分支

                                     #把当前分枝合并到目的分时,要先切把目的分枝
    [root@web2 project]# git merge hotfix 
    更新 a3b9645..33ae0bb
    Fast-forward
     new.txt | 1 +
     1 file changed, 1 insertion(+) 
    [root@web2 project]#
    [root@web2 project]# cat new.txt
    new file
    first
    second
    fix a bug                          #mster分枝的内容已量新
    [root@web2 project]#

    6)将所有本地修改提交远程服务器

    [root@web2 project]# git push
    root@192.168.2.100's password: 
    Counting objects: 5, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 283 bytes | 0 bytes/s, done.
    Total 3 (delta 1), reused 0 (delta 0)
    To root@192.168.2.100:/var/git/project
       a3b9645..33ae0bb  master -> master
    [root@web2 project]# 

    版本分支的冲突

          两个分枝在对同一个文件修改时,对相同文件的同一行修改的内容不一样,在合并分枝时就会发生冲突

       1)  在hotfix和master分支中修改同一文件a.txt

    [root@web2 project]# git checkout hotfix  
    切换到分支 'hotfix'               #在hotfix分枝上创建a.txt内容为AAA
    [root@web2 project]# 
    [root@web2 project]# echo "AAA" > a.txt
    [root@web2 project]# git add .
    [root@web2 project]# git commit -m "AAA"
    [hotfix 1eedfbb] AAA
     1 file changed, 1 insertion(+)
     create mode 100644 a.txt
    [root@web2 project]# 
    
    [root@web2 project]# git checkout master
    切换到分支 'master'                #在master分枝上创建a.txt内容为BBB
    [root@web2 project]# echo "BBB" > a.txt
    [root@web2 project]# git add .
    [root@web2 project]# git commit -m "BBB"
    [master 0420600] BBB
     1 file changed, 1 insertion(+)
     create mode 100644 a.txt
    [root@web2 project]# 
    
    [root@web2 project]# git merge hotfix 
    自动合并 a.txt                    #这时把hotfix合并到master时会提示分支冲突
    冲突(添加/添加):合并冲突于 a.txt
    自动合并失败,修正冲突然后提交修正的结果。
    [root@web2 project]#

    2) 手动解决冲突

    [root@web2 project]# cat a.txt 
    <<<<<<< HEAD
    BBB
    =======
    AAA
    >>>>>>> hotfix
    [root@web2 project]# 
    [root@web2 project]# vim a.txt    #打开有冲突的文件,修改为想要留下的数据,保存退出
    BBB
    [root@web2 project]# git add .
    [root@web2 project]# git  commit -m "resolved"
    [master 69bbbd2] resolved
    [root@web2 project]# 
  • 相关阅读:
    Object—C 块在函数中作为参数时的分析
    C语言函数调用的底层机制
    高考是最后一次拼智商的事了。(beacuse 大多数人的努力程度之低根本轮不到拼天赋!)
    KMP
    由clone引出的 protected 问题
    Abstract Factory
    Oracle,第四周
    由clone引出的abstract class 和 interface 的问题
    Factory Method
    Simple Factory
  • 原文地址:https://www.cnblogs.com/sven-pro/p/13245930.html
Copyright © 2011-2022 走看看