Git学习笔记

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容