git学习笔记

146 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第4天

Git的正确使用姿势和最佳实践

1 项目初始化

mkdir demo
cd demo
git init [--initial-branch] [--bare] [--template]
# --initial-branch 初始化分支
# --bare 创建一个裸厂库(纯git目录,没有工作目录),服务器通常使用
# --template 可以通过模板创建预先定义好的git目录
$ tree .git
.git
|-- HEAD  当前指向的分支
|-- config 配置信息(全局配置、系统配置、本地配置,低级别的配置会覆盖高级别的配置)
|-- description
|-- hooks
|   |-- commit-msg.sample
|-- info
|   `-- exclude
|-- objects 文件信息
|   |-- info
|   `-- pack
`-- refs 分支信息
    |-- heads
    `-- tags

2 常见的git配置

用户名配置:

git config --global user.name username
git congig --global user.email useremail
对应配置文件中的信息:
[user]
    email = useremail
    name = username

Instead of 配置:url替换

git config --global url.git@github.com:.insteadOf https://github.com/
对应配置文件中的信息:
[url "git@github.com:"]
    insteadOf = https://github.com/

git别名配置:简化命令

git config --global alias.cin "commit --amend --no-edit"
对应配置文件中的信息:
    cin = commit --amend --no-edit

3 git remote配置

  • 表示的是本地和远端厂库的配置信息,分为http和ssh两种。查看和配置方法如下:

    查看:
    $ git remote -v
    添加:
    $ git remote add origin_ssh git@github.com:git/git.git
    $ git remote add origin_http https://github.com/git/git.git
    查看:
    $ git remote -v
    origin_http     https://github.com/git/git.git (fetch)
    origin_http     https://github.com/git/git.git (push)
    origin_ssh      git@github.com:git/git.git (fetch)
    origin_ssh      git@github.com:git/git.git (push)
    查看配置:
    $ cat .git/config
    [core]
            repositoryformatversion = 0
            filemode = false
            bare = false
            logallrefupdates = true
            symlinks = false
            ignorecase = true
    [remote "origin_ssh"]
            url = git@github.com:git/git.git
            fetch = +refs/heads/*:refs/remotes/origin_ssh/*
    [remote "origin_http"]
            url = https://github.com/git/git.git
            fetch = +refs/heads/*:refs/remotes/origin_http/*
    如果输入过程错误,可以-h查看更改
    
  • 同一个orgin设置不同的push和fatch url

    $ git remote add origin git@github.com:git/git.git
    $ git remote set-url --add --push origin git@github.com:my_repo/git.git
    $ git remote -v
    origin  git@github.com:git/git.git (fetch) 设置的fetch
    origin  git@github.com:my_repo/git.git (push) 设置的push
    

3.1 HTTP Remote 不推荐,不安全

配置免密的方式:
内存:git config --global credential.helper 'cache --timeout=3600'
硬盘:git config --global credential.helper "store --file /path/to/credential-file"
不指定目录的情况默认是 ~/.git-credentials
​
将密钥信息存在指定文件中
具体格式:${scheme}://${user}:${password}@github.com

3.2 SSH Remote

免密配置,SSH可以通过公私钥的机制,将生成公钥存在服务端,从而实现免密访问

目前的Key的类型四种,分别是dsa、rsa、ecdsa、ed25519,默认使用的是rsa,由于一些安全问题,现在已经不推荐使用dsa和rsa了(新版本的windows使用的时候已经拒绝),优先推荐使用ed25519。

生成ssh的key:
$ ssh-keygen -t ed25519 -C "15674623628@163.com"
查看ssh的key
$ cat /c/Users/Administrator/.ssh/id_ed25519.pub
并将生成的key复制到github-》setting-》SSH and GPG keys-》新建key

4 git add

执行git add后会在object下创建一个文件的id,把文件加入到暂存区,通过(git cat-file -p 文件id) 可以查看文件。

$ git cat-file -p 3b18e512dba79e4c8300dd08aeb37f8e728b8dad  这个命令可以获取文件的内容
hello world

5 git commit

通过git commit会在object下面生成两个文件,并且会生成log文件和ref变化。其中一个文件记录了commit文件的对象id和文件名,另一个记录了文件的id已经创建者和提交的人的信息

git commit -m "discriable message"

6 Objects

commit / tree / blob在git里面都统一称为object,除此之外还有个tag的object。

  • commit:存储提交信息,一个commit可以对应唯一一个版本的代码
  • blob:存储文件的内容
  • tree:存储文件的目录信息

三个信息的串连方式:通过commit寻找到tree的信息,每个commit都会存储对应的tree id,通过tree id去获取对应的目录树信息blob,通过blob id获取对应的文件内容。

7 Refs

refs的内容就是对应的commit id,因此把ref当作指针,指向对应的commit来表示当前ref对应的版本。

ref也有不用的种类,refs/heads前缀表示的是分支,除此之外还有refs/tags钱缀表示的标签。

  • Breach:git checkout -b 可以创建一个新分支,分支一般用于开发阶段,是可以不断添加commit进行迭代的

  • Tag:标签一般表示一个稳定版本,指向的commit一般不会变更,发布版本的时候会用该标签生成一个稳定的版本

    $ git tag v0.0.1 生成tag的命令
    
  • annotation tag:一种特殊的tag,可以给tag提供一些额外的信息

    $ git tag -a v0.0.2 -m "add feature 1"
    

8 版本追述

通过git log查看commit信息,通过commit的tree用cat-file命令查看blob,再通过blob查看内容。

9 修改历史版本

当使用git commit --amend命令后,由于commit id改变,但是tree没有变化,会出现悬空的commit id,通过 git fsck --lost-found来查看是否有悬空的commit。

10 git gc

  • GC:通过git gc命令,可以删除一些不需要的object,以及会对object进行一些打包压缩来减少厂库的体积。

  • Reflog:用于记录操作日志,防止误操作后数据丢失,通过reflog来找到丢失的数剧,手动将日志设置为过期。

  • 指定时间:git gc prune=new指定的是修剪多久之前的对象,默认是两周前。

    $ git reflog expire --expire=now --all  设置过期时间
    $ git gc --prune=now  清理
    

11 git clone & pull fetch

12 git push 将本地代码同步到远端的方式

13 常见问题

  • 为什么我明明配置了git配置,但是依然没有办法拉取代码

    • 免密认证没有配置
    • instead of配置没有配置,配的ssh免密配置,但是使用的还是http协议访问
  • fecth不会合并本地的代码