美文网首页
git总结篇.md

git总结篇.md

作者: ManjackGo | 来源:发表于2018-01-13 22:06 被阅读248次

    写这个东西一为了总结思路,二为了在公司内部的讲演。

    耳熟能详

    概念

    操作

    • git init
    • git clone
    • git pull
    • git fetch
    • git merge
    • git branch
    • git reset
    • git revert
    • git reflog
    • git log
    • git config

    初次见面

    设置账户

    git config
    git config --global user.name "Manjack" user.email "manjack@aobi.com"
    就算不加上--global参数,也会设置到全局变量里,没办法对某个repo设置name和email。

    config文件有三个层次:

    1. repo层面的,保存在每个repo的.git文件夹里
    [remote "origin"]
        url = https://github.com/wangshub/wechat_jump_game.git
        fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
        remote = origin
        merge = refs/heads/master
    
    1. 用户层面的,保存在C:/user/<user-name>/.gitconfig
    [user]
        email = exkulo@qq.com
        name = ManjackGo
    
    1. 系统层面,做一些全局设定,比如<别名><默认行为(比如fetch使用merge还是rebase)>C:/ProgramData/git/config

    生成sshkey

    和服务器采用非对称加密进行校验,需要把公钥上传至服务器自己的账号里。使用代码:

    ssh-keygen -t rsa -C "manjack@aobi.com"
    

    三次回车使用默认值。公钥会保存在:

    • windows C:\Users\<user-name>\.ssh/id_rsa.pub
    • UNIX/MAC ~ /.gitconfig

    把文件里的内容全选(必须包括最后一行的空行)粘贴到自己gitlab账户的ssh密钥里面,完成配置。

    建立一个repository

    一、自己建立一个空repo

    随便在某个文件夹使用git init。可以看到生成了一个.git文件夹。git自动帮我们建立了一条叫做master的分支。

    二、从网上clone一个repo

    1. 从网上的repo拿到一个远端网址
    2. 执行git clone <url> 可以得到一个新的repo,并帮我们把url设置为一个名字为remote的远端。
      相当于执行了以下操作:
    git remote add remote <url>
    git pull
    

    .git文件夹

    hooks # 钩子函数存放点,可使用自己喜欢的脚本写
        |
        pre-commit
        pre-push
    info
        |
        exclude # 一个本地版本的.ignore
    objectsm #存放着历史文件,包括版本本身,以及版本对应的文件
        |
        21
        c4
        b5
        ...
    refs
        |
        heads
            |
            master
            nb
        remotes
            |
            remote
        tags
            |
            release1.0.0
    config
    description
    HEAD #代表当前的版本指向
    

    版本的实质

    当我们完成一次commit操作,实质上发生了:

    1. 把当前版本变动的文件压缩,产生hash作为名称
    2. 把这些文件的hash集合起来,hash一次
    3. 把当前状态的head进行一次哈希,作为本次提交的tree
    4. 给当前的提交一个hash值,作为log的版本号

    以上所有的文件均储存在object文件里,文件夹的两个字母作为一串hash码的头两个字母,文件夹里的文件名是hash另外一部分的字符串。

    可以使用git cat-file -p <file-name>来解压查看文件。

    (演示ING...)

    提交代码

    working, stage, head

    解释...

    add

    • git add . 把当前目录的变动提交到stage区
    • git add <file-name>

    commit

    • git commit

    vim基础操作
    安装的时候默认使用vim作为编辑器,在这里基本只要知道以下几个点就可以用了:

    • i进入编辑模式
    • esc退出编辑模式
    • wq保存并退出
    • git commit -m "<message>"
    • git commit --amend <message> 添加本次提交到上一次的提交,并修改上一次提交的log(若没有得提交则只改log)

    所谓版本,tag,branch

    只是一个代表着某个版本的字符串。保存在refs里面,打开可以看到所对应的字符串。所谓的撤回操作,就是返回到某个版本。而HEAD代表着当前工作目录所对应的分支或者版本。
    (展示HEAD,展示refs)

    撤回操作

    svn中的revert

    • 对工作区
      也就把工作区的变动回复到head的状态,采用以下代码:
      git reset --hard HEAD~0
      (解释--hard --soft的区别),把目标目录变成某个版本的样子, ~0表示版本
    • 对某个文件
      git reset --hard HEAD

    git reset
    把当前head以及HEAD指向某个版本,把后面的版本摒弃。(摒弃不意味着消失,git的一切提交都不会消失,只是变成了难以再获取到的孤魂野鬼)。HEAD~1代表上一个版本。
    注意:
    当HEAD是合并而来的版本的时候,HEAD~1代表当前分支的父节点,HEAD^1代表另一分支的父节点

    黄金法则 GOLDEN RULE
    不要在公共的分支上(已经在服务器上存在的分支)进行reset操作。

    svn中的update to revision

    svn中我们使用这种方法来检出过去的代码,在git中使用:
    git checkout <commit>就可以把工作区checkout到这个状态。
    注意:此时处于一个dettached head状态。
    非大陆版本翻译为“断头状态”。HEAD一般是指向refs/heads中的某个文件(这些文件又会指向某个版本),成为attched head状态,而当checkout为某个版本的时候,HEAD会显示为某个版本号。成为断头。

    当你需要在checkout出来的版本工作
    断头状态下所有的提交均不属于任何分支,属于无效提交。当需要在这个状态下工作时,最好建立一个新的分支来工作,最后再合并到目标分支。

    git revert

    同样用于撤销操作,需要和svn中作出区分。这是一个安全的操作,可以用于已经共享的分支。具体操作相当于找到某个版本的changeset,逆之,然后作为一次新的commit提交。相当于帮我们手工做了一次改错。
    使用方法git revert <commit>

    必学时光回溯大法

    任何想好好实用git的人都必须学会这一节。
    当我们执行reset之后,hard模式下三个tree都会退回到你的目标版本,此时执行git log,是看不到被reset掉后面的版本的,就好像什么都没发生过一样。这样子当自己手贱不小心reset掉自己需要的代码了,岂不是要捶胸顿足?
    不用怕,之前就讲过,git是一个永远都不会丢失提交的vcs,只要是提交过的,都能找回。这个时候需要一个神器了,那就是reflog。让我们输入reflog,可以看到如下的东西:

    $git reflog
    c75dc97 (HEAD -> nb) HEAD@{0}: reset: moving to HEAD~1
    c1998f3 (master) HEAD@{1}: checkout: moving from master to nb
    c1998f3 (master) HEAD@{2}: commit: add the first line
    c75dc97 (HEAD -> nb) HEAD@{3}: commit (initial): commit first
    

    可以看到最上面reset了一个版本。现在我们突然想要前面的某个版本了,直接执行
    git checkout HEAD@{n}就可回到任意版本,复制出你要的文件然后回到最新版本复制回去,或者新开分支工作都可以, whatever you like。

    令人激动的分支操作

    基于版本的分支。

    查看

    查看分支,带星号的为当前所处分支git branch
    查看远端分支git branch -r

    切换分支

    git checkout <branch> 实质上是改变了HEAD的指向。

    新建分支

    git branch <branch>
    git checkout -r <branch> 新建分支并切换过去

    删除分支

    git branch -d <branch> 安全删除分支,必须在被合并之后才允许删除
    git branch -D <branch> 强行删除分支

    merge

    把一堆操作集合起来作为一个merge commit,会自动处理好历史。
    操作步骤:

    1. 切换到当前分支git checkout <master-branch>
    2. 合并 git merge <feature-branch>

    rebase

    换基。同样需要尊崇黄金法则,不能更改公共分支。
    直接把整条分支的起点挪到源分支的head处。在公共分支使用容易引起冗余changeset。(选择性讲解,看时间)

    rebase和merge的区别

    ...

    远端操作

    存放在refs/remotes文件夹下

    新建立远端

    git remote add <remote-name> <remote-url>一般起名字为origin,跟着git的标准写。

    删除远端

    git remote remove <remote-name>

    rename

    就叫rename git remote rename <old> <new>

    pull

    相当于fetch + merge/rebase
    git pull <remote-name> 当加上--rebase标志时表示使用rebase,一般由于是公共分支,不要这么搞比较好。

    push

    把所有的commit提交到服务器
    git push <remote-name> [--force]

    别名

    允许我们自定义别名,比如使用decompress来代表解压操作,那么
    git config --global alias.decompress "cat-file -p" 既可。

    hook

    相关文章

      网友评论

          本文标题:git总结篇.md

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