zoukankan      html  css  js  c++  java
  • Git详解

    起步 - Git 简史

    同生活中的许多伟大事物一样,Git 诞生于一个极富纷争大举创新的年代。

    Linux 内核开源项目有着为数众多的参与者。 绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。 到 2002 年,整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码。

    到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统。 他们对新的系统制订了若干目标:

    • 速度

    • 简单的设计

    • 对非线性开发模式的强力支持(允许成千上万个并行开发的分支)

    • 完全分布式

    • 有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)

    自诞生于 2005 年以来,Git 日臻成熟完善,在高度易用的同时,仍然保留着初期设定的目标。 它的速度飞快,极其适合管理大项目,有着令人难以置信的非线性分支管理系统。

    三种状态

    好,请注意。 如果你希望后面的学习更顺利,记住下面这些关于 Git 的概念。 Git 有三种状态,你的文件可能处于其中之一:已提交(committed)、已修改(modified)和已暂存(staged)。 已提交表示数据已经安全的保存在本地数据库中。 已修改表示修改了文件,但还没保存到数据库中。 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。

    由此引入 Git 项目的三个工作区域的概念:Git 仓库工作目录以及暂存区域

    关于版本控制

    什么是“版本控制”?我为什么要关心它呢? 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 在本书所展示的例子中,我们对保存着软件源代码的文件作版本控制,但实际上,你可以对任何类型的文件进行版本控制。

    如果你是位图形或网页设计师,可能会需要保存某一幅图片或页面布局文件的所有修订版本(这或许是你非常渴望拥有的功能),采用版本控制系统(VCS)是个明智的选择。 有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。 使用版本控制系统通常还意味着,就算你乱来一气把整个项目中的文件改的改删的删,你也照样可以轻松恢复到原先的样子。 但额外增加的工作量却微乎其微。

      1、本地版本控制系统

      许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。 这么做唯一的好处就是简单,但是特别容易犯错。 有时候会混淆所在的工作目录,一不小心会写错文件或者覆盖意想外的文件。

    为了解决这个问题,人们很久以前就开发了许多种本地版本控制系统,大多都是采用某种简单的数据库来记录文件的历次更新差异。

      2、集中化的版本控制系统

      如何让在不同系统上的开发者协同工作?于是,集中化的版本控制系统(Centralized Version  Control Systems,简称 CVCS)应运而生。这类系统,诸如 CVS、Subversion 以及Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。

     

      3、分布式版本控制系统

      在这类系统中,像Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

    Git 官方中文手册 https://git-scm.com/book/zh/v2
    

    安装git

    环境说明:

    [root@gitlab ~]# rpm -qa centos-release
    centos-release-7-4.1708.el7.centos.x86_64
    [root@gitlab ~]# uname -a
    Linux gitlab 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
    [root@gitlab ~]# getenforce 
    Disabled
    [root@gitlab ~]# systemctl status firewalld.service 
    ● firewalld.service - firewalld - dynamic firewall daemon
       Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
       Active: inactive (dead)
         Docs: man:firewalld(1)

      1、Yum安装Git

    # centos 自带git
    [root@gitlab ~]# rpm -qa git
    git-1.8.3.1-11.el7.x86_64
    
    # 安装方法
    yum install git -y

      2、编译安装

    编译安装可以安装较新版本的git
    Git下载地址: https://github.com/git/git/releases
    
    # 安装依赖关系
    yum install curl-devel expat-devel gettext-devel  openssl-devel zlib-devel
    # 编译安装 tar
    -zxf git-2.0.0.tar.gz cd git-2.0.0 make configure ./configure --prefix=/usr make make install

    初次运行 Git 前的配置

      1、配置git

    git config --global user.name "clsn"  #配置git使用用户
    git config --global user.email "admin@znix.top"  #配置git使用邮箱
    git config --global color.ui true  #语法高亮
    git config --list # 查看全局配置

      2、配置过程

    [root@gitlab ~]# git config --global user.name "clsn"  #配置git使用用户
    [root@gitlab ~]# git config --global user.email "admin@znix.top"  #配置git使用邮箱
    [root@gitlab ~]# git config --global color.ui true  #语法高亮
    [root@gitlab ~]# git config --list # 查看全局配置
    user.name=clsn
    user.email=admin@znix.top
    color.ui=true

      3、生成的配置文件

    [root@gitlab ~]# cat .gitconfig 
    [user]
        name = clsn
        email = admin@znix.top
    [color]
        ui = true

      4、获取帮助

    使用Git时需要获取帮助,有三种方法可以找到Git命令的使用手册:
    
    git help <verb>
    git <verb> --help
    man git-<verb>
    例如,要想获得配置命令的手册,执行
    
    git help config

    获取 Git 仓库(初始化仓库)

    # 创建目录
    mkdir git_data
    # 进入目录
    cd git_data/
    # 初始化
    git init
    # 查看工作区状态
    git status

      操作过程

    [root@gitlab ~]# mkdir git_data
    [root@gitlab ~]# cd git_data/
    [root@gitlab git_data]# git init
    初始化空的 Git 版本库于 /root/git_data/.git/
    [root@gitlab git_data]# git status
    # 位于分支 master
    #
    # 初始提交
    #
    无文件要提交(创建/拷贝文件并使用 "git add" 建立跟踪)

    Git命令常规操作

     

      1、常用操作示意图

      2、文件的状态变化周期

      

      3、git操作练习->创建文件

    1、创建文件

    [root@gitlab git_data]# touch README
    [root@gitlab git_data]# git status
    # 位于分支 master    //有可能是英文的对应着解释
    #
    # 初始提交
    #
    # 未跟踪的文件:
    #   (使用 "git add <file>..." 以包含要提交的内容)
    #
    #    README
    提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)

    2、添加文件跟踪

    [root@gitlab git_data]# git add ./*
    [root@gitlab git_data]# git status
    # 位于分支 master
    #
    # 初始提交
    #
    # 要提交的变更:
    #   (使用 "git rm --cached <file>..." 撤出暂存区)
    #
    #    新文件:    README

     文件会添加到.git的隐藏目录

    [root@gitlab git_data]# tree  .git/
    .git/
    ├── branches
    ├── config
    ├── description
    ├── HEAD
    ├── hooks
    │   ├── applypatch-msg.sample
    │   ├── commit-msg.sample
    │   ├── post-update.sample
    │   ├── pre-applypatch.sample
    │   ├── pre-commit.sample
    │   ├── prepare-commit-msg.sample
    │   ├── pre-push.sample
    │   ├── pre-rebase.sample
    │   └── update.sample
    ├── index
    ├── info
    │   └── exclude
    ├── objects
    │   ├── e6
    │   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
    │   ├── info
    │   └── pack
    └── refs
        ├── heads
        └── tags
    

    3、由工作区提交到本地仓库

    [root@gitlab git_data]# git commit  -m 'first commit'  
    [master(根提交) bb963eb] first commit
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 README

    4、查看git的状态

    [root@gitlab git_data]# git status
    # 位于分支 master
    无文件要提交,干净的工作区

    提交后的git目录状态

    [root@gitlab git_data]# tree  .git/
    .git/
    ├── branches
    ├── COMMIT_EDITMSG
    ├── config
    ├── description
    ├── HEAD
    ├── hooks
    │   ├── applypatch-msg.sample
    │   ├── commit-msg.sample
    │   ├── post-update.sample
    │   ├── pre-applypatch.sample
    │   ├── pre-commit.sample
    │   ├── prepare-commit-msg.sample
    │   ├── pre-push.sample
    │   ├── pre-rebase.sample
    │   └── update.sample
    ├── index
    ├── info
    │   └── exclude
    ├── logs
    │   ├── HEAD
    │   └── refs
    │       └── heads
    │           └── master
    ├── objects
    │   ├── 54
    │   │   └── 3b9bebdc6bd5c4b22136034a95dd097a57d3dd
    │   ├── bb
    │   │   └── 963eb32ad93a72d9ce93e4bb55105087f1227d
    │   ├── e6
    │   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
    │   ├── info
    │   └── pack
    └── refs
        ├── heads
        │   └── master
        └── tags

      4、添加新文件

    git add  * 添加到暂存区域
    git commit  提交git仓库 -m 后面接上注释信息,内容关于本次提交的说明,方便自己或他人查看
    修改或删除原有文件
    
    //常规方法
    git add  *
    git commit
    
    //简便方法
    git commit -a  -m "注释信息"
    
    -a 表示直接提交
    Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are
    not affected.

      5、删除git内的文件

    命令说明:

    • 没有添加到暂存区的数据直接rm删除即可。
    • 已经添加到暂存区数据:
    
    git rm --cached database 
    #→将文件从git暂存区域的追踪列表移除(并不会删除当前工作目录内的数据文件)
    
    git rm -f database
    #→将文件数据从git暂存区和工作目录一起删除

    命令实践:

    # 创建新文件
    [root@gitlab git_data]# touch 123
    [root@gitlab git_data]# git status
    # 位于分支 master
    # 未跟踪的文件:
    #   (使用 "git add <file>..." 以包含要提交的内容)
    #
    #    123
    提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
    # 将文件添加到暂存区域
    
    [root@gitlab git_data]# git add 123
    [root@gitlab git_data]# git status
    # 位于分支 master
    # 要提交的变更:
    #   (使用 "git reset HEAD <file>..." 撤出暂存区)
    #
    #    新文件:    123
    #  删除文件
    
    [root@gitlab git_data]# rm 123 -f
    [root@gitlab git_data]# ls
    [root@gitlab git_data]# git status
    # 位于分支 master
    # 要提交的变更:
    #   (使用 "git reset HEAD <file>..." 撤出暂存区)
    #
    #    新文件:    123
    #
    # 尚未暂存以备提交的变更:
    #   (使用 "git add/rm <file>..." 更新要提交的内容)
    #   (使用 "git checkout -- <file>..." 丢弃工作区的改动)
    #
    #    删除:      123
    # 
    [root@gitlab git_data]# git reset HEAD  ./* 
    [root@gitlab git_data]# git status
    # 位于分支 master
    无文件要提交,干净的工作区  

      6、查看历史记录

    • git log   #→查看提交历史记录
    
    • git log -2   #→查看最近几条记录
    
    • git log -p -1  #→-p显示每次提交的内容差异,例如仅查看最近一次差异
    
    • git log --stat -2 #→--stat简要显示数据增改行数,这样能够看到提交中修改过的内容,对文件添加或移动的行数,并在最后列出所有增减行的概要信息
    
    • git log --pretty=oneline #→--pretty根据不同的格式展示提交的历史信息
    
    • git log --pretty=fuller -2 #→以更详细的模式输出提交的历史记录
    
    • git log --pretty=fomat:"%h %cn"  #→查看当前所有提交记录的简短SHA-1哈希字串与提交着的姓名。

      7、还原历史数据

    Git服务程序中有一个叫做HEAD的版本指针,当用户申请还原数据时,其实就是将HEAD指针指向到某个特定的提交版本,但是因为Git是分布式版本控制系统,为了避免历史记录冲突,故使用了SHA-1计算出十六进制的哈希字串来区分每个提交版本,另外默认的HEAD版本指针会指向到最近的一次提交版本记录,而上一个提交版本会叫HEAD^,上上一个版本则会叫做HEAD^^,当然一般会用HEAD~5来表示往上数第五个提交版本。

    git reset --hard   hash
    
    git reset --hard HEAD^  #→还原历史提交版本上一次
    
    git reset --hard 3de15d4 #→找到历史还原点的SHA-1值后,就可以还原(值不写全,系统会自动匹配)

    测试命令

    [root@gitlab git_data]# git log
    commit a409fc46f792228a8119705e9cc97c2a013534ab
    Author: clsn <13835544305@163.com>
    Date:   Wed Nov 29 11:44:14 2017 +0800
    
        test
    
    commit bb963eb32ad93a72d9ce93e4bb55105087f1227d
    Author: clsn <13835544305@163.com>
    Date:   Wed Nov 29 10:57:02 2017 +0800
    
        first commit

    还原数据

    [root@gitlab git_data]# git reset --hard  bb963
    HEAD 现在位于 bb963eb first commit
    # 查看数据
    [root@gitlab git_data]# ls
    README

      8、标签使用

    前面回滚使用的是一串字符串,又长又难记。
    
    git tag v1.0   #→当前提交内容打一个标签(方便快速回滚),每次提交都可以打个tag。
    
    git tag          #→查看当前所有的标签
    
    git show v1.0   #→查看当前1.0版本的详细信息
    
    git tag v1.2 -m "version 1.2 release is test"  #→创建带有说明的标签,-a指定标签名字,-m指定说明文字
    
    git tag -d v1.0   #→我们为同一个提交版本设置了两次标签,删除之前的v1.0

    测试命令

    [root@gitlab git_data]# git reset --hard 0bdf2e7
    HEAD is now at 0bdf2e7 modified README file
    [root@gitlab git_data]# git reset --hard V1.0
    HEAD is now at a66370a add test dir
    
    [root@gitlab git_data]# git tag  v20171129
    [root@gitlab git_data]# git tag 
    v20171129

      9、对比数据

    git diff可以对比当前文件与仓库已保存文件的区别,知道了对README作了什么修改后,再把它提交到仓库就放⼼多了。
    
    git diff README

    分支结构

    在实际的项目开发中,尽量保证master分支稳定,仅用于发布新版本,平时不要随便直接修改里面的数据文件。

    那在哪干活呢?干活都在dev分支上。每个人从dev分支创建自己个人分支,开发完合并到dev分支,最后dev分支合并到master分支。所以团队的合作分支看起来会像下图那样。

     

      1、分支切换 

    [root@gitlab git_data]# git branch linux
    [root@gitlab git_data]# git branch 
          linux
        * master
        [root@gitlab git_data]# git checkout linux 
    
        切换到分支 'linux'
        [root@gitlab git_data]# git branch 
        * linux
          master
    
    在linux分支进行修改
        [root@gitlab git_data]# cat README 
        [root@gitlab git_data]# echo "2017年11月30日" >> README 
        [root@gitlab git_data]# git add .
        [root@gitlab git_data]# git commit -m "2017年11月30日09点10分"
        [linux 5a6c037] 2017年11月30日09点10分
         1 file changed, 1 insertion(+)
        [root@gitlab git_data]# git status 
        # 位于分支 linux
        无文件要提交,干净的工作区
    
    回到master分支
        [root@gitlab git_data]# git checkout master 
        切换到分支 'master'
        [root@gitlab git_data]# cat README 
        [root@gitlab git_data]# git log  -1
        commit 7015bc7b316cc95e2dfe6c53e06e3900b2edf427
        Author: clsn <admin@znix.top>
        Date:   Wed Nov 29 19:30:57 2017 +0800
    
            123
    
    合并代码
        [root@gitlab git_data]# git merge linux 
        更新 7015bc7..5a6c037
        Fast-forward
         README | 1 +
         1 file changed, 1 insertion(+)
        [root@gitlab git_data]# git status 
        # 位于分支 master
        无文件要提交,干净的工作区
        [root@gitlab git_data]# cat README 
        2017年11月30日

      2、合并失败解决

     模拟冲突,在文件的同一行做不同修改

    //在master 分支进行修改
    [root@gitlab git_data]# cat README 
    2017年11月30日
    [root@gitlab git_data]# echo  "clsn in master">> README 
    [root@gitlab git_data]# git commit -a -m "clsn 2017年11月30日 09点20分 "
    [master 7ab71d4] clsn 2017年11月30日 09点20分
     1 file changed, 1 insertion(+)
    
    //切换到linux分支
    [root@gitlab git_data]# git checkout linux 
    切换到分支 'linux'
    [root@gitlab git_data]# cat README 
    2017年11月30日
    [root@gitlab git_data]# echo "clsn in linux" >> README 
    [root@gitlab git_data]# git commit -a -m "2017年11月30日 03"
    [linux 20f1a13] 2017年11月30日 03
     1 file changed, 1 insertion(+)
    
    //回到master分区,进行合并,出现冲突
    [root@gitlab git_data]# git checkout master 
    切换到分支 'master'
    [root@gitlab git_data]# git merge linux
    自动合并 README
    冲突(内容):合并冲突于 README
    自动合并失败,修正冲突然后提交修正的结果。
    
    //解决冲突
    [root@gitlab git_data]# vim README 
    2017年11月30日
    clsn in master
    clsn in linux
    
    # //手工解决冲突
    [root@gitlab git_data]# git commit -a -m "2017年11月30日 03"
    [master b6a097f] 2017年11月30日 03

      3、删除分支

    因为之前已经合并了linux分支,所以现在看到它在列表中。 在这个列表中分支名字前没有 * 号的分支通常可以使用 git branch -d 删除掉;你已经将它们的工作整合到了另一个分支,所以并不会失去任何东西。

    查看所有包含未合并工作的分支,可以运行 git branch --no-merged

    git branch --no-merged
      testing

    这里显示了其他分支。 因为它包含了还未合并的工作,尝试使用 git branch -d 命令删除它时会失败:

    git branch -d testing
    error: The branch 'testing' is not fully merged.
    If you are sure you want to delete it, run 'git branch -D testing'. 

    如果真的想要删除分支并丢掉那些工作,如同帮助信息里所指出的,可以使用 -D 选项强制删除它。 

    git详细讲解:https://git-scm.com/book/en/v2

  • 相关阅读:
    webmagic使用
    网站文件下载链接
    正则表达式
    JS 页面刷新或重载
    History
    【问题&解决】fonts/fontawesome-webfont.woff2 404 (Not Found)
    ckeditor的使用
    Windows Server 2012 R2 或 2016 无法安装 .Net 3.5.1
    自定义配置文件的读取
    MVC中上传文件大小限制的解决办法
  • 原文地址:https://www.cnblogs.com/tim1blog/p/9895599.html
Copyright © 2011-2022 走看看