Git 使用简易指南
- Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
- Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
- Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
Git 与 SVN 区别
- GIT是分布式的,SVN不是:这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。
- GIT把内容按元数据方式存储,而SVN是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。
- GIT分支和SVN的分支不同:分支在SVN中一点不特别,就是版本库中的另外的一个目录。
- GIT没有一个全局的版本号,而SVN有:目前为止这是跟SVN相比GIT缺少的最大的一个特征。
- GIT的内容完整性要优于SVN:GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
Git 命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| # 创建版本库
git clone <url> //克隆远程版本库
git init //初始化本地版本库
# 修改和提交
git status //查看状态
git diff //查看变更内容
git status //跟踪所有改动过的文件
git add <file> //跟踪指定的文件
git mv <old> <new> //文件改名
git rm <file> //删除文件
git rm --cached <file> //停止跟踪文件但不删除
git commit -m "message" //提交所有更新过的文件及描述
git commit --amend //修改最后一次提交
# 查看提交历史
git log //查看提交历史
git log -p <file> //查看指定文件的提交历史
git blame <file> //以列表形式查看指定文件的提交历史
# 撤销
git reset --hard HEAD //撤销工作目录中所有未提交文件的修改内容
git checkout HEAD <file> //撤销指定的未提交文件的修改内容
git revert <commit> //撤销指定的提交
# 分支与标签
git branch //显示所有本地分支
git checkout <branch/tag> //切换到指定分支或标签
git branch <new-branch> //创建新分支
git branch -d <branch> //删除本地分支
git tag //列出所有本地标签
git tag <tagname> //基于最新提交创建标签
git tag -d <tagname> //删除标签
# 合并与衍合
git merge <branch> //合并指定分支到当前分支
git rebase <branch> //衍合指定分支到当前分支
# 远程操作
git remote -v //查看远程版本库信息
git remote show <remote> //查看指定远程版本库信息
git remote add <remote> <url> //添加远程版本库
git fetch <remote> //从远程库获取代码
git pull <remote> <branch> //下载代码及快速合并
git push <remote> <branch> //上传代码及快速合并
git push <remote> :<branch/tag-name> //删除远程分支或标签
git push --tags //上传所有标签
|
Git 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| # git ssh公钥
ssh-keygen -t rsa -C "laijingwei1993@163.com"
# 保存 git 账号密码,避免每次 push 重复输入
git config --global credential.helper store
# 全局配置
git config --global user.email "laijingwei1993@163.com"
git config --global user.name "赖经纬"
# 禁用自动转换换行符 (LF will be replaced by CRLF in)
git config --global core.autocrlf false
# git log 中文乱码
git config --global core.quotepath false
git config --global gui.encoding utf-8
git config --global i18n.commit.encoding utf-8
git config --global i18n.logoutputencoding utf-8
export LESSCHARSET=utf-8
# 变量添加到 Windows 环境变量
|
Git Fork 仓库更新
1
2
3
4
5
| # 将别人的仓库添加到你的上游远程,通常命名为upstream
git remote add upstream http://192.168.1.100:3000/laijw/docsify-sdsf.git && git fetch upstream
# 合并到 master
git checkout master && git merge upstream/master
|
Git 提交三部曲
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| git add .
git commit -m "update"
git push origin master
# 首次提交远程仓库
git push -u origin master
# 当本地与远程分支均为默认分支名称时即本地为master,远程分支为origin
git push
# 删除本地缓存,通常用于修改 .gitignore 后
git rm -r --cached .
# 重写 git 历史,通常用于 git clone --depth 1 <..> 后
git filter-branch -- --all
|
Git 查看代码贡献量
1
2
3
4
5
6
7
8
| # 查看git上个人代码量
git log --author="赖经纬" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -
# 统计每个人的增删行数
git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done
# 查看仓库提交者排名前 5
git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 5
|
Git 本地临时服务器
1
2
3
4
| mkdir test.git && cd test.git
git init --bare
git remote add origin D:\test.git
git push
|
Git 部署
1
2
3
4
5
6
| # CentOS部署
cd /www/wwwroot/laijw.mxnt.net
git pull origin master
# 当本地与远程分支均为默认分支名称时即本地为master,远程分支为origin
git pull
|
git clone 加速
通过淘宝代理
1
2
| https://github.com/spf13/spf13-vim.git
https://github.com.cnpmjs.org/spf13/spf13-vim.git
|
通过本地代理
1
2
| git config --global http.https://github.com.proxy socks5://127.0.0.1:1080
git config --global https.https://github.com.proxy socks5://127.0.0.1:1080
|
git submodules
1
2
3
4
5
6
7
8
9
10
11
12
| # 在 Linux 下执行
git rm --cached addons/Wechat
git submodule add http://git.huizhouyiren.com/mirrors/Wechat.git addons/Wechat
git add .
git commit -m "2020/04/28 星期二 16:31:01 赖经纬"
git push origin master
# 克隆有 git 子模块的仓库
git clone --recurse-submodules http://git.huizhouyiren.com/php/yirenframe.git
# 批量更新子模块仓库
git submodule foreach git submodule update
|
Commitizen
1
2
3
4
5
6
7
8
9
10
11
12
| npm install -g commitizen
cd .git
# npm
commitizen init cz-conventional-changelog --save-dev --save-exact
# yarn
commitizen init cz-conventional-changelog --yarn --dev --exact
git add .
git cz
git push
|
gitignore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # 表示此为注释,将被Git忽略
*.a 表示忽略所有 .a 结尾的文件
!lib.a 表示但lib.a除外
/TODO 表示仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ 表示忽略 build/目录下的所有文件,过滤整个build文件夹;
doc/*.txt 表示会忽略doc/notes.txt但不包括 doc/server/arch.txt
bin/: 表示忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
/bin: 表示忽略根目录下的bin文件
/*.c: 表示忽略cat.c,不忽略 build/cat.c
debug/*.obj: 表示忽略debug/io.obj,不忽略 debug/common/io.obj和tools/debug/io.obj
**/foo: 表示忽略/foo,a/foo,a/b/foo等
a/**/b: 表示忽略a/b, a/x/b,a/x/y/b等
!/bin/run.sh 表示不忽略bin目录下的run.sh文件
*.log: 表示忽略所有 .log 文件
config.php: 表示忽略当前路径的 config.php 文件
/mtk/ 表示过滤整个文件夹
*.zip 表示过滤所有.zip文件
/mtk/do.c 表示过滤某个具体文件
|
被过滤掉的文件就不会出现在git仓库中(gitlab或github)了,当然本地库中还有,只是push的时候不会上传。
需要注意的是,gitignore还可以指定要将哪些文件添加到版本管理中,如下:
!*.zip
!/mtk/one.txt
唯一的区别就是规则开头多了一个感叹号,Git会将满足这类规则的文件添加到版本管理中。为什么要有两种规则呢?
想象一个场景:假如我们只需要管理/mtk/目录中的one.txt文件,这个目录中的其他文件都不需要管理,那么.gitignore规则应写为::
/mtk/*
!/mtk/one.txt
假设我们只有过滤规则,而没有添加规则,那么我们就需要把/mtk/目录下除了one.txt以外的所有文件都写出来!
注意上面的/mtk/*不能写为/mtk/,否则父目录被前面的规则排除掉了,one.txt文件虽然加了!过滤规则,也不会生效!
还有一些规则如下:
fd1/*
说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;
/fd1/*
说明:忽略根目录下的 /fd1/ 目录的全部内容;
/*
!.gitignore
!/fw/
/fw/*
!/fw/bin/
!/fw/sf/
说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录;注意要先对bin/的父目录使用!规则,使其不被排除。