这是我参与「第五届青训营 」伴学笔记创作活动的第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不会合并本地的代码