看完,再也不怕Git了【高质量】

1. Git由来

  • 1991年,Linus创建了开源的Linux。
  • 2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码。
  • 2002年-2005年,使用商业的版本控制系统BitKeeper。
  • 2005年,Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!

2. Git实现原理

2.1 集中式版本控制系统 VS 分布式版本控制系统

2.1.1 集中式版本控制系统
  • CVS、SVN

    集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,时间成本太高。

2.1.2 分布式版本控制系统
  • Git、Mercurial、Bazaar

    分布式版本控制系统没有"中央服务器",每个人的电脑上都是一个完整的版本库,这样工作的时候就不需要联网了,因为版本库就在你自己的电脑上。

2.1.3 同步问题
  • 集中式,因为所有版本是由中央服务器控制的,所以只要同步中央服务器就行。
  • 分布式,你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当"中央服务器"的电脑,但这个服务器的作用仅仅是用来方便"交换"大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
2.1.4 安全性比较
  • 集中式,中央服务器要是出了问题,所有人都没法干活了
  • 分布式,每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。

2.2 Git 工作流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y7Wa5K1k-1569745860193)(./4.png)]

2.3 工作区、暂存区、版本库

2.3.1 概念
  • **工作区:**就是你在电脑里能看到的目录。
  • **暂存区:**英文叫stage, 或index。一般存放在 “.git目录下” 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • **版本库:**工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
2.3.2 关系展示
  • Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OWOQpivG-1569745860194)(./5.png)]

2.4 版本库相关

2.4.1 概念

可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

注意:所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了什么,版本控制系统不知道,也没法知道。(Microsoft的Word格式是二进制格式,版本控制系统无法跟踪)

2.4.2 版本库创建
  • 创建版本库命令

    mkdir git_demo
    cd git_demo
    git init
    
  • 操作示例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W3PbkPQ9-1569745860197)(./1.png)]

2.5 基础操作

2.5.1 添加文件
  • 添加文件命令

    vim demo.txt  # 写入'I am a text'
    git add demo.txt
    git status  # 可以看见有一个新的文件demo.txt
    git commit -m 'demo'
    

    为什么Git添加文件需要addcommit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件。如果我们想取消已经add的文件可以使用git rm --cached 命令。

  • 操作示例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P32ElET3-1569745860197)(./2.png)]

2.5.2 修改文件
  • 修改文件命令

    vim demo.txt  # 添加'demo'
    git status  # 可以看见有一个被修改的文件demo.txt
    git diff demo.txt  # 可以看见具体修改了什么内容
    
  • 操作示例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2vPYN1rb-1569745860200)(./3.png)]

2.5.3 撤销修改
  • 撤销命令

    vim demo.txt  # 换行添加'checkout'
    git checkout -- demo.txt
    

    撤销不仅对文件内的内容有效,也对文件有效。例:如果文件被删除然后撤销,那么文件就会被恢复。

  • 操作示例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DcO1oj29-1569745860200)(./6.png)]

2.5.4 删除文件
  • 删除命令

    touch delete_test.txt  # 创建一个文件
    git add delete_test.txt  # 添加到暂存区
    git commit -m 'test delete'  # 提交到版本库
    rm delete_test.txt  # 删除文件
    git rm delete_test.txt
    git commit -m 'success delete file'
    
  • 操作示例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G62tG7Kd-1569745860201)(./7.png)]

2.5.5 版本回滚
  • 回滚命令

    git log  # 查看想要回滚的版本commit id
    git reset --hard <commit id>
    

    git reset参数说明:

    git reset –-soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可;
    git reset -–hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,撤销的commit中所包含的更改被冲掉;

  • 操作示例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-634xpokL-1569745860201)(./8.png)]

2.5.6 日志信息

如果你是照着之前的步骤来操作的,你的git log和我这的git log信息是有区别的,本节的图是为了好展示所以加入了一些其他操作。你也可以先跳过这一节,最后再来看这一节的内容。

  • git log

    commit 的版本日志 包含提交的版本 操作者 日期 (方便查看commit的版本,但是版本回退后,使用git log 看不到回退版本号之后的版本记录)
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-msboEU0G-1569745860202)(./25.png)]

  • git log --graph

    图形化显示git log信息,具体符号意义说明:

    * 表示一个commit
    | 表示分支前进
    / 表示分叉
    \ 表示合入
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pbNBXDFq-1569745860202)(./27.png)]

  • git reflog

    使用git 命令进行操作的日志 包括当前步骤所在哪个版本(一个commit 产生一个版本, 指定版本回退只能回退到该commit) 以及操作的具体内容

    版本回退后,仍然可以看到所有的版本记录 方便查看每个操作步骤所在的版本,可以根据版本号自由前进后退
    在这里插入图片描述

2.5.7 标签管理
  • 创建标签

    $ git tag v1.0
    
  • 查看所有标签

    $ git tag
    
    
  • 查看标签说明

    $ git show v1.0
    
    
  • 删除标签

    $ git tag -d v0.1
    
    
  • 推送标签到远程

    $ git push origin v1.0
    
    
  • 推送所有未推送的本地标签到远程

    $ git push origin --tags
    
    
  • 删除远程标签

    • 先删除本地标签

      $ git tag -d v1.0
      
      
    • 再删除远程标签

      $ git push origin :refs/tags/v1.0
      
      

3. 分支管理

3.1 创建与合并分支

3.1.1 分支原理

在[版本回滚](####2.5.5 版本回滚)里,我们可以看见,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向mastermaster才是指向提交的,所以,HEAD指向的就是当前分支。

3.1.2 分支实战
  • 具体步骤演示

    • 新建dev分支并切换到dev分支,做修改并提交,看dev分支和master分支的区别
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SEDGDfsv-1569745860203)(./14.png)]

      由于git checkout命令在切换分支和撤销修改时容易搞混淆。推荐切换分支使用新版git switch命令

    • 合并dev分支到master分支,删除dev分支
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k8iC8Gba-1569745860204)(./15.png)]

      注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。在后面的[Fast forward模式](####3.3.1 Fast forward模式)会详细提到这部分内容。

  • 具体步骤原理讲解

    • 刚开始
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FVC6hIjl-1569745860204)(./9.png)]

    • 新建一个dev分支
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iOffOfU8-1569745860205)(./10.png)]

    • 在dev分支新发起一次提交
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KFDsyagi-1569745860205)(./11.png)]

    • 把dev分支合并到master分支
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NObLuPEP-1569745860206)(./12.png)]

    • 合并完分支后,删除dev分支
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hk824UBn-1569745860206)(./13.png)]

3.2 解决合并时发生的冲突

3.2.1 发生冲突
  • 具体步骤演示
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IJgp5j1A-1569745860207)(./16.png)]

    hfm分支修改成

    Creating a new branch is quick AND simple.
    
    

    master分支修改成

    Creating a new branch is quick & simple.
    
    
  • 原理图示
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tWhI6liA-1569745860207)(./17.png)]

3.2.2 解决冲突
  • 具体步骤演示
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H3CpO82P-1569745860207)(./18.png)]

    将demo文件中冲突的地方改成:

    Creating a new branch is quick and simple.
    
    
  • 原理图示
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UbUFqCdp-1569745860207)(./19.png)]

3.3 分支管理策略

3.3.1 Fast forward模式

合并分支时,默认情况下,Git会用Fast forward模式,这种模式直接把当前分支指向合并分支的当前提交,所以合并速度非常快。但这种模式下,删除分支后,会丢掉分支信息。

3.3.2 禁止Fast forward模式

可以使用git merge --no-ff来强制禁止Fast forward模式,Git就会在merge时生成一个新的commit。

3.3.3 临时修改某个分支(git stash的使用)

并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?

Git提供了一个stash功能,可以把当前工作现场"储藏"起来,等以后恢复现场后继续工作:

$ git stash
Saved working directory and index state WIP on hfm: 8ac106b hfm commit

"储藏"完毕就可以切换到另外一个分支进行工作了,工作完后切回原先的分支,可以看到之前存的信息:

$ git stash list
stash@{0}: WIP on hfm: 8ac106b hfm commit

我们可以将"储藏"的内容再还原出来继续之前的工作:

$ git stash pop
On branch hfm
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   demo.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (b45f246f459c3de307391f6f036a86bf27e89441)

注:我们使用git stash往往是遇到了bug或者紧急的事情,这种改动在我们目前的分支也需要更改,所以我们需要将那个提交复制过来。我们可以使用git cherry-pick <commit>命令来同步在其他分支的修改。使用这个命令会自动给我们做一次提交。

3.3.4 Feature分支

添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。

3.3.5 分支策略

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yNZOqNZn-1569745860208)(./20.png)]

3.3.6 merge 和 rebase

现有如下状态的分支情况,我们来看看使用git merge和git rebase合并master到Feature分支上会有什么区别。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KLpFeX73-1569745860208)(./21.png)]

  • merge

    • 如果使用git merge,那么会自动创建一个新的commit

      优点:记录了真实的commit情况,包括每个分支的详情
      缺点:因为每次merge会自动产生一个merge commit,所以在使用一些git 的GUI tools,特别是commit比较频繁时,看到分支很杂乱。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Z0T74zT-1569745860208)(./23.png)]

  • rebase

    • 如果用git rebase,那么会先找公共祖先

    • 然后将Feature分支从公共祖先到目前的commit都暂存起来

    • 再将要合并的分支先提交到公共祖先之后

    • 最后将暂存的部分提交到master之后

      优点:得到更简洁的项目历史,去掉了merge commit
      缺点:如果合并出现代码问题不容易定位,因为re-write了history

      注:由于会修改历史记录,所以不要在公共分支上使用此命令

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BIBx9WBM-1569745860209)(./22.png)]

4. 远程仓库

注:不同的平台新建仓库的步骤有点不一样,但是大同小异,根据自己的需求去官网查找对应的帮助文档都会有具体步骤,故此不在本文档赘叙新建仓库相关的内容了。

要参与任何一个 Git 项目的协作,必须要了解该如何管理远程仓库。远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写。同他人协作开发某个项目时,需要管理这些远程仓库,以便推送或拉取数据,分享各自的工作进展。 管理远程仓库的工作,包括添加远程库,移除废弃的远程库,管理各式远程库分支,定义是否跟踪这些分支,等等。

4.1 查看当前的远程库

4.1.1 克隆及查看
  • 要查看当前配置有哪些远程仓库,可以用 git remote 命令,它会列出每个远程库的简短名字。在克隆完某个项目后,至少可以看到一个名为 origin 的远程库,Git 默认使用这个名字来标识你所克隆的原始仓库

    git clone git@gitlab.liquidnetwork.com:backend/flash_shopping.git
    Cloning into 'flash_shopping'...
    remote: Counting objects: 6934, done.
    remote: Compressing objects: 100% (1651/1651), done.
    remote: Total 6934 (delta 5291), reused 6910 (delta 5275)
    Receiving objects: 100% (6934/6934), 1.01 MiB | 8.40 MiB/s, done.
    Resolving deltas: 100% (5291/5291), done.
    
    
  • 加上 -v 选项(译注:此为 --verbose 的简写,取首字母),显示对应的克隆地址

    git remote -v
    origin	git@gitlab.liquidnetwork.com:backend/flash_shopping.git (fetch)
    origin	git@gitlab.liquidnetwork.com:backend/flash_shopping.git (push)
    
    

4.2 添加远程仓库

4.2.1 添加
  • 要添加一个新的远程仓库,可以指定一个简单的名字,以便将来引用,运行 git remote add [shortname] [url]

    $ git remote add test git@gitlab.liquidnetwork.com:backend/flash_shopping.git
    $ git remote -v
    origin	git@gitlab.liquidnetwork.com:backend/flash_shopping.git (fetch)
    origin	git@gitlab.liquidnetwork.com:backend/flash_shopping.git (push)
    test	git@gitlab.liquidnetwork.com:backend/flash_shopping.git (fetch)
    test	git@gitlab.liquidnetwork.com:backend/flash_shopping.git (push)
    
    
  • 现在可以用字符串 test 指代对应的仓库地址了。

    $ git fetch test
    From gitlab.liquidnetwork.com:backend/flash_shopping
     * [new branch]      broadcast_card              -> test/broadcast_card
     * [new branch]      check_flash                 -> test/check_flash
     * [new branch]      comment                     -> test/comment
     * [new branch]      deploy                      -> test/deploy
    
    

4.3 从远程仓库抓取数据

4.3.1 几种不同的抓取
  • 可以用下面的命令从远程仓库抓取数据到本地:

    $ git fetch [remote-name]
    
    

    此命令会到远程仓库中拉取所有你本地仓库中还没有的数据。但是需要注意fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。

  • 如果设置了某个分支用于跟踪某个远端仓库的分支,可以使用以下命令自动抓取数据下来

    $ git pull
    
    

    此命令实际上是执行了git fetch和git merge(可以给git pull加参数–rebase改成git rebase)

  • 默认情况下 git clone 命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支

    $ git clone
    
    

4.4 推送数据到远程仓库

4.4.1 推送
  • 将本地仓库中的数据推送到远程仓库。实现这个任务的命令很简单: git push [remote-name] [branch-name]

    $ git push origin master
    
    

    只有在所克隆的服务器上有写权限,或者同一时刻没有其他人在推数据,这条命令才会如期完成任务。如果在你推数据前,已经有其他人推送了若干更新,那你的推送操作就会被驳回。你必须先把他们的更新抓取到本地,合并到自己的项目中,然后才可以再次推送。

4.5 跟踪远程分支

4.5.1 基本概念
  • 从远程分支 checkout 出来的本地分支,称为 跟踪分支(tracking branch)。跟踪分支是一种和某个远程分支有直接联系的本地分支。在跟踪分支里输入 git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。同样,在这些分支里运行 git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。
4.5.2 如何跟踪
  • 使用命令git checkout -b [分支名] [远程名]/[分支名]即可将本地分支跟踪到远程分支

    $ git checkout -b se origin/service
    
    

5. 其他

gitlab的用户管理方面属于运维控制的内容,本文档不再详细说明,感兴趣的可以移至参考链接

5.1 SSH公钥

5.1.1 生成SSH公钥

大多数 Git 服务器都会选择使用 SSH 公钥来进行授权。系统中的每个用户都必须提供一个公钥用于授权,没有的话就要生成一个。生成公钥的过程在所有操作系统上都差不多。 首先先确认一下是否已经有一个公钥了。SSH 公钥默认储存在账户的主目录下的 ~/.ssh 目录。进去看看:

$ cd ~/.ssh
$ ls
authorized_keys2  id_dsa       known_hosts
config            id_dsa.pub

关键是看有没有用 somethingsomething.pub 来命名的一对文件,这个 something 通常就是 id_dsaid_rsa。有 .pub 后缀的文件就是公钥,另一个文件则是密钥。假如没有这些文件,或者干脆连 .ssh 目录都没有,可以用 ssh-keygen 来创建。该程序在 Linux/Mac 系统上由 SSH 包提供,而在 Windows 上则包含在 MSysGit 包里:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/schacon/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/schacon/.ssh/id_rsa.
Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub.
The key fingerprint is:
43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local

它先要求你确认保存公钥的位置(.ssh/id_rsa),然后它会让你重复一个密码两次,如果不想在使用公钥的时候输入密码,可以留空。

现在,所有做过这一步的用户都得把它们的公钥给 Git 服务器的管理员(假设 SSH 服务被设定为使用公钥机制)。他们只需要复制 .pub 文件的内容然后发邮件给管理员。公钥的样子大致如下:

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== schacon@agadorlaptop.local

5.1.2 添加到Gitlab

在gitlab中找到Profile Settings -> SSH keys,将刚生成的SSH公钥添加进来即可

5.2 初次运行 Git 前的配置

5.2.1 查看现有的Git配置
  • 命令

    $ git config --list
    
    
  • 示例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RW2ecCz8-1569745860209)(./24.png)]

5.2.2 配置用户名称及邮件地址
  • 每次 Git 提交时都会引用你的用户名称和电子邮件地址,说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录,所以这两条配置信息很重要。

  • 命令

    $ git config --global user.name "huangfengmiao"
    $ git config --global user.email "huangfengmiao@liquidnetwork.com"
    
    

5.3 Git忽略提交规则

5.3.1 gitignore
  • 使用场景

    在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交。简单来说一个场景:在你使用git add .的时候,遇到了把你不想提交的文件也添加到了缓存中去的情况,比如项目的本地配置信息,如果你上传到Git中去其他人pull下来的时候就会和他本地的配置有冲突,所以这样的个性化配置文件我们一般不把它推送到git服务器中,但是又为了偷懒每次添加缓存的时候都想用git add .而不是手动一个一个文件添加,该怎么办呢?很简单,git为我们提供了一个.gitignore文件只要在这个文件中申明那些文件你不希望添加到git中去,这样当你使用git add .的时候这些文件就会被自动忽略掉。

  • 使用方法

    • 在Git项目中定义.gitignore文件

      在.gitingore 文件中,遵循相应的语法,在每一行指定一个忽略规则。如:

      *.log
      *.temp
      /vendor
      
      
    • 在Git项目的设置中指定排除文件

      这种方式只是临时指定该项目的行为,需要编辑当前项目下的 .git/info/exclude文件,然后将需要忽略提交的文件写入其中。需要注意的是,这种方式指定的忽略文件的根目录是项目根目录。

    • 定义Git全局的 .gitignore 文件

      除了可以在项目中定义 .gitignore 文件外,还可以设置全局的git .gitignore文件来管理所有Git项目的行为。这种方式在不同的项目开发者之间是不共享的,是属于项目之上Git应用级别的行为。这种方式也需要创建相应的 .gitignore 文件,可以放在任意位置。然后在使用以下命令配置Git:

      $ git config --global core.excludesfile ~/.gitignore
      
      
  • gitignore匹配语法说明

    • 空格不匹配任意文件,可作为分隔符,可用反斜杠转义
    • 以“”开头的行都会被 Git 忽略。即#开头的文件标识注释,可以使用反斜杠进行转义。
    • 可以使用标准的glob模式匹配。所谓的glob模式是指shell所使用的简化了的正则表达式。
    • 以斜杠"/“开头表示目录;”/“结束的模式只匹配文件夹以及在该文件夹路径下的内容,但是不匹配该文件;”/"开始的模式匹配项目跟目录;如果一个模式不包含斜杠,则它匹配相对于当前 .gitignore 文件路径的内容,如果该模式不在 .gitignore 文件中,则相对于项目根目录。
    • 以星号"“通配多个字符,即匹配多个任意字符;使用两个星号”*" 表示匹配任意中间目录,比如a/**/z可以匹配 a/z, a/b/z 或 a/b/c/z等。
    • 以问号"?"通配单个字符,即匹配一个任意字符;
    • 以方括号"[]"包含单个字符的匹配列表,即匹配任何一个列在方括号中的字符。比如[abc]表示要么匹配一个a,要么匹配一个b,要么匹配一个c;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配。比如[0-9]表示匹配所有0到9的数字,[a-z]表示匹配任意的小写字母)。
    • 以叹号"!“表示不忽略(跟踪)匹配到的文件或目录,即要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。需要特别注意的是:如果文件的父目录已经被前面的规则排除掉了,那么对这个文件用"!"规则是不起作用的。也就是说”!“开头的模式表示否定,该文件将会再次被包含,如果排除了该文件的父级目录,则使用”!"也不会再次被包含。可以使用反斜杠进行转义。
5.3.2 忽略文件的规则
  • Git忽略文件的基本原则

    • 忽略操作系统自动生成的文件,比如缩略图等;
    • 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如python自动产生的.pyc文件;
    • 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
  • 忽略规则的优先级

    在 .gitingore 文件中,每一行指定一个忽略规则,Git检查忽略规则的时候有多个来源,它的优先级如下(由高到低):

    • 从命令行中读取可用的忽略规则
    • 当前目录定义的规则
    • 父级目录定义的规则,依次递推
    • $GIT_DIR/info/exclude 文件中定义的规则
    • core.excludesfile中定义的全局规则
  • 忽略规则查看

    如果你发下.gitignore写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore命令检查

    $ git check-ignore -v HelloWorld.pyc
    .gitignore:1:*.pyc    HelloWorld.pyc
    
    
  • Git忽略规则不生效原因和解决

    • .gitignore中已经标明忽略的文件目录下的文件,git push的时候还会出现在push的目录中,或者用git status查看状态,想要忽略的文件还是显示被追踪状态。
      原因是因为在git忽略目录中,新建的文件在git中会有缓存,如果某些文件已经被纳入了版本管理中,就算是在.gitignore中已经声明了忽略路径也是不起作用的,
      这时候我们就应该先把本地缓存删除,然后再进行git的提交,这样就不会出现忽略的文件了。

      $ git rm -r --cached .
      $ git add .
      $ git commit -m 'update .gitignore'
      $ git push
      
      
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值