git总结篇.md

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

耳熟能详

概念

操作

  • 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 "[email protected]"
就算不加上--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//.gitconfig
[user]
    email = [email protected]
    name = ManjackGo
  1. 系统层面,做一些全局设定,比如<别名><默认行为(比如fetch使用merge还是rebase)>C:/ProgramData/git/config

生成sshkey

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

ssh-keygen -t rsa -C "[email protected]"

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

  • windows C:\Users\\.ssh/id_rsa.pub
  • UNIX/MAC ~ /.gitconfig

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

建立一个repository

一、自己建立一个空repo

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

二、从网上clone一个repo

  1. 从网上的repo拿到一个远端网址
  2. 执行git clone 可以得到一个新的repo,并帮我们把url设置为一个名字为remote的远端。
    相当于执行了以下操作:
git remote add remote 
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 来解压查看文件。

(演示ING...)

提交代码

working, stage, head

解释...

add

  • git add . 把当前目录的变动提交到stage区
  • git add

commit

  • git commit

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

  • i进入编辑模式
  • esc退出编辑模式
  • wq保存并退出
  • git commit -m ""
  • git commit --amend 添加本次提交到上一次的提交,并修改上一次提交的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 就可以把工作区checkout到这个状态。
注意:此时处于一个dettached head状态。
非大陆版本翻译为“断头状态”。HEAD一般是指向refs/heads中的某个文件(这些文件又会指向某个版本),成为attched head状态,而当checkout为某个版本的时候,HEAD会显示为某个版本号。成为断头。

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

git revert

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

必学时光回溯大法

任何想好好实用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 实质上是改变了HEAD的指向。

新建分支

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

删除分支

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

merge

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

  1. 切换到当前分支git checkout
  2. 合并 git merge

rebase

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

rebase和merge的区别

...

远端操作

存放在refs/remotes文件夹下

新建立远端

git remote add 一般起名字为origin,跟着git的标准写。

删除远端

git remote remove

rename

就叫rename git remote rename

pull

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

push

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

别名

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

hook

你可能感兴趣的:(git总结篇.md)