
Git

git以及github的一些基本操作
Git 常用操作
一、本地仓库
1. init
初始化本地仓库(主要用于客户端)
1
git init
创建裸库
用于作为大家一起工作的共享库,每一个人都可以往里面push自己的本地修改
1
2
3mkdir <example.git>
cd <example.git>
git init --bare .在工作目录只有一个.git目录,没有类似本地库那样的文件结构可供你直接进行浏览和修改
但你可以使用git show来进行浏览,参数为某次commit的SHA1值
1
git show <id>
本地仓库与裸库连接
1
git remote add <remote> <path>/<example.git>
2. config
配置
1
2
3
4
5
6
7
8
9
10
11
12git config --global user.name "username"
git config --global user.email "email" # 初始化用户和邮箱
git config --list # 检查当前配置
git config --local --list # (当前目录)
git config --global --list # (全局)
git config <key> # 检查git的某一项配置
git config --global core.editor vim # 设置默认文本编辑器
git config --global merge.tool vimdiff # 差异分析工具
git config --global alias.br <branch> # 设置命令别名
git config --global --unset <entry-name> # 删除全局设置
git config core.fileMode false # 忽略文件的权限变化
git config credential.helper store # 保存凭证(避免每次pull或push的时候询问帐号密码)git配置http和scoks代理
1
2
3git config --global https.proxy 'http://127.0.0.1:8001' # 适用于privoxy将socks协议转为http协议的http端口
git config --global http.proxy 'http://127.0.0.1:8001'
git config --global socks.proxy "127.0.0.1:1080"git配置ssh代理
1
2
3
4
5
6cat ~/.ssh/config
Host gitlab.com
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p # 直接使用 shadowsocks 提供的
socks5 代理端口
Host github.com
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
3. clone
克隆仓库
1
2
3
4git clone https://github.com/Marszhewei/Cmake.git
git clone https://github.com/Marszhewei/Cmake.git cmake # 指定本地仓库名
git clone -b <branch-name> --single-branch https://github.com/user/repo.git # clone下来指定的单一分支
git clone --depth=1 https://github.com/user/repo.git # clone最新一次提交
4. add
添加
1
2
3git add <file>
git add *.md # 正则匹配
git add <dir>/1
2
3git add .
git add -A # 添加全部文件
git add * # 不包含隐藏文件交互式暂存
1
git add -i
5. commit
1 | git update-ref -d HEAD # 清空commit重新提交第一个commit |
提交更新到本地库
1
2
3
4git commit
git commit -v # 查看当前stage区与上一个版本的差异(填写comments后直接提交到本地库了)
git commit [[--message | -m] <"comments">] # 添加简短提交信息
git commit -a -m <"comments"> # 跳过暂存区,直接提交到本地库(untracked文件不能用)将暂存区的文件重新提交,将目前的修改追加到上一次提交中
1
git commit --amend # 修改最后一次提交
类似于变基,如果最后一次提交已经push了就不要使用了
优雅的提交commit信息
- 组成部分
- 标题行: 必填, 描述主要修改类型和内容
- 主题内容: 描述为什么修改, 做了什么样的修改, 以及开发的思路等等
- 页脚注释: 放 Breaking Changes 或 Closed Issues
- 常用修改项
- type: commit 的类型
- feat: 新特性
- fix: 修改问题
- refactor: 代码重构
- docs: 文档修改
- style: 代码格式修改, 注意不是 css 修改
- test: 测试用例修改
- chore: 其他修改, 比如构建流程, 依赖管理.
- scope: commit 影响的范围, 比如: route, component, utils, build…
- subject: commit 的概述
- body: commit 具体修改内容, 可以分为多行
- footer: 一些备注, 通常是 BREAKING CHANGE 或修复的 bug 的链接.
- 组成部分
6. status
检查当前文件状态
1
2git status
git status --ignored # 展示忽略的文件获得简短的状态输出
1
git status [-s | --short]
7. reset
reset中三棵树
1
2
3
4
5
6git reset --soft
仅移动HEAD指针,只回退了commit
git reset --mixed
重置HEAD,重置暂存区,工作区不会被修改,这时git add 和 git commit 即可回到之前状态
git reset --hard
彻底回退到指定commit-id的状态revert & reset
1
2
3git revert <id> # 以新增一个commit的方式还原某一个commit的修改
reset 命令会抹去某个 commit id 之后的所有 commit
git revert -m 1 HEAD # 撤销一步(工作区暂存区本地仓库均撤销)
Level | HEAD | Index | Workdir | safe |
---|---|---|---|---|
Commit Level | ||||
reset –soft [commit-id] | 移动了HEAD指向的分支引用 | NO | NO | YES |
reset –mixed [commit-id] | 移动了HEAD指向的分支引用 | YES | NO | YES |
reset –hard [commit-id] | 移动了HEAD指向的分支引用 | YES | YES | NO |
checkout [commit-id] | 只移动了HEAD | YES | YES | YES |
File Level | ||||
reset (commit-id) [file] | NO | YES | NO | YES |
checkout (commit-id) [file] | NO | YES | YES | NO |
8. stash
查看存储栈
1
git stash list
保存到存储栈
1
2
3git stash [save <"comments">] # 将现在工作区和暂存区的更改保存到存储栈(已跟踪)
git stash [save <"comments">] -u # 存储未跟踪的文件
git stash --keep-index # 存储工作区的更改而忽视暂存区的修改从存储栈恢复
1
2
3
4git stash pop # 从栈顶恢复并出栈
git stash pop stash@{2} # 从栈的任意位置恢复内容并出栈
git stash apply # 从栈顶恢复但不删除
git stash apply stash@{2} # 从栈的任意位置恢复但不删除从存储栈删除
1
2
3git stash drop # 从栈顶移除记录
git stash drop stash@{2} # 从任意位置移除记录
git stash clear # 清空存储栈drop后可跟stash_id,不加参数就是删除最近一条
9. clean
1 | git clean -d -n # 做一次演习然后告诉你将要移除什么 |
强制删除untracked的文件&目录
1
2git clean <file-name> -f
git clean <directory-name> -df
10. show
1 | git show <branch-name>:<file-name> # 展示任意分支的某一文件的内容 |
1 | git show <tagname> # 查看标签信息与对应的提交信息 |
11. branch
创建分支
1
2
3git branch test # 创建分支
git branch <branch> <id> # 从任意提交创建分支
git branch <branch> <old-branch> # 从现有分支创建分支查看分支
1
2
3
4
5
6
7git branch # 列出全部分支
git branch -v # 列出全部分支并查看每个分支的最后一次提交
git branch -vv # 将所有的本地分支列出来并且包含更多的信息
git branch --merge # 查看哪些分支已经合并到当前分支
git branch --no-merged # 查看所有包含未合并工作的分支
git branch -a # 查看全部本地分支和远程分支
git branch -r # 查看全部的远程分支切换跟踪的远程分支
1
git branch -u origin/serverfix # 设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支
删除分支
1
2git branch -d test # 删除分支
git branch -D test # 强制删除分支在该分支代码未合并到master分支时,直接删除会不成功
重命名本地分支
1
git branch -m <branch>
12. checkout
1 | git checkout <branch> # 切换分支 |
撤销对文件的修改
1
2git checkout <file>
git checkout . # 放弃工作区所有修改撤销还没有进暂存区的文件
跟踪远程分支,并在本地创建同名分支(迁移本地)
1
2git checkout --track origin/dev
git checkout -b serverfix origin/serverfix # 相同,但是后一种本地分支和远程分支可以使用不同名
13. merge
合并分支
1
2git merge <branch>
git merge <branch> -no-ff -m <commit message> # 合并指定分支到当前分支(-no-ff 参数表示禁用Fast forward)merge比较暴力,直接腾出区域把另一个分支全放进去,好处是可以知道哪些代码是来
自哪一个分支的rebase会按照一定顺序进行重新排序,然后再放入,但是不知道哪些代
码来自哪个分支修改文件出现冲突时需要操作者手动修改再进行合并
操作项
1
2git merge --abort # 在遇到冲突时终止合并
git merge --continue # 冲突解决后继续merge关于空白问题导致的冲突
1
2git merge -Xignore-space-change whitespace # 忽略所有空白修改
git merge -Xignore-all-space whitespace # 忽略任意数量已有空白修改
13. tag
列出标签
1
2git tag # 列出现有标签
git tag -l <tagname> # 查找标签(特定模式)贴上标签
1
2
3
4git tag <tagname> # 创建轻量标签
git tag <tagname> <id> # 给某次提交创建一个轻量标签
git tag -a <tagname> -m <"tag comments"> # 创建附注标签
git tag -a <tagname> <id> -m <"tag comments"> # 给某次提交创建一个附注标签删除标签
1
git tag -d v1.4
15. diff
详细展示一行中的修改
1
git diff --word-diff
工作目录中当前文件和暂存区域快照之间的差异
1
git diff <file>
比较暂存区和版本库的差异
1
git diff --staged/--cached
指定范围内比较
对比两次提交
1
2
3git diff <id1> <id2>
git diff <id>^ # 和上一次提交进行比较
git diff <id1> <id2> <path>/<file> # 限制比较的范围对比两个分支
1
git diff <branch-a> <branch-b>
16. log
1 | git reflog # 引用日志 |
显示最近的两条提交记录
1
2git log -n # -n用来显示最近的n次提交
git log -p # -p用来显示每次提交的内容差异使用其它格式显示历史提交信息
查看提交历史
1
2
3
4
5git log
git log --pretty=oneline # 一行输出一条提交记录
git log --pretty=short # 简短显示log
git log --pretty=full # 完整显示log
git log --pretty=fuller # 更加完整的显示log更改显示的格式
1
git log --pretty=format:"%h - %an, %ar : %s"
1
2
3
4H 提交的完整哈希值 %h 提交的简写哈希值 %T 树的完整哈希值 %t 树的简写哈希值
P 父提交的完整哈希值 %p 父提交的简写哈希值 %an 作者名字 %ae 作者的电子邮件地址
ad 作者修订日期(可以用 --date=选项 来定制格式) %ar 作者修订日期,按多久以前的方式显示
cn 提交者的名字 %ce 提交者的电子邮件地址 %cd 提交日期 %cr 提交日期(距今多长时间) %s 提交说明
图形化显示合并提交分支历史
1
2
3git log --stat # 查看简要提交变更
git log --shortstat # 只显示 --stat 中最后的行数修改添加移除统计
git log --graph # 图形化展示提交历史日志搜索
1
2
3
4git log --after/--since=2.week # 两周之内的提交
git log --after/--since="2022-8-8" # 此日期之后的提交
git log --before/until="2022-8-3" # 此日期之前的提交
git log --before/--until=2.week # 两周之前的提交1
2
3git log --author <author> # 仅显示包含作者的提交
git log --committer <commiter> # 仅显示指定提交者相关的提交
git log -- <path>/<file> # 仅显示文件相关的提交1
2
3
4git log master dev # 查看dev和master分支的所有commit
git log master..dev
git log ^master dev
git log dev --not master # dev分支还未合并到master分支上的提交1
2git log <branch-a> <branch-b> ^<branch-c>
git log <branch-a> <branch-b> --not <branch-c> # branch-a,branch-b包含,branch-c不包含的提交1
git log master...dev # 查看两次提交的非共有提交
1
2
3git log -S <string> # 只显示添加或删除该字符串的那些提交
git log -G <string> # 使用正则表达式进行搜索
git log -L :<function>:<file> # 将文件中的函数改动全部列出来1
git log --grep <keywords> # 仅显示包含关键字的搜索
others
1
2
3
4git log --name-only # 显示提交修改了什么文件
git log --abbrev-commit # 仅显示SHA-1前几个字符
git log --show-signature # 显示GPG签名
git log --name-status # 显示新增、修改、删除的文件清单
17. rebase
1 | git rebase --autostash # 执行rebase之前自动stash |
谨慎使用: 不要将已经推送到中央服务器中的提交包含在内,这样做会出现相同变更的不同版本,造成混乱
对分支变基消除钻石链
1
2
3
4git checkout <topic-branch>
git rebase <base-branch>
git checkout <base-branch>
git merge <topic-branch>1
2
3git rebase <base-branch> <topic-branch>
git checkout <base-branch>
git merge <topic-branch>当使用rebase导致混乱
1
2
3
4git pull --rebase
or
git fetch
git rebase <remote>/<branch>改变历史
1
git rebase -i HEAD~3
pick
reword
edit
squash
fixup
exec
18. grep
从提交历史或者工作目录中查找
1
2
3
4git grep -n <string> # -n参数输出匹配行行号
git grep --count <string> # --count输出哪些文件包含了该string及次数
git grep -p <string> <file> # 查看该string属于哪个函数
git grep --break --heading # 易于阅读
19. filter-branch
从每一个提交中移除一个文件
1
git filter-branch --tree-filter "rm -f <file>" HEAD
将一个子目录作为新的根目录
1
git filter-branch --subdirectory-filter <dir> HEAD
全局修改邮箱地址
1
2
3
4
5
6
7
8
9git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = <"old-email"> ];
then
GIT_AUTHOR_NAME=<"author">;
GIT_AUTHOR_EMAIL=<"new-email">;
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
19. rm mv
移除文件
1
2
3rm <file>
git rm <file> # 该文件在工作区
git rm -f <file> # 该文件在暂存区1
git rm --cached <file> # 把文件从git仓库中删除,但是本地保留
移动文件
1
2
3
4git mv <file-from> <file-to> # 相当于运行下面三条命令
mv <file-from> <file-to>
git rm <file-from>
git add <file-to>
20. 其它
ls-file
1
2
3git ls-files -t # 显示所有tracked的文件
git ls-files --others # 显示所有untracked的文件
git ls-files --others -i --exclude-standard # 显示所有忽略的文件忽略文件的改动
1
2
3git update-index --assume-unchanged path/to/file
关闭 track 指定文件的改动,也就是 Git 将不会在记录这个文件的改动
git update-index --no-assume-unchanged path/to/file # 恢复 track 指定文件的改动以最后提交的顺序列出所有git分支
1
git for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads/
二、远端仓库
1. remote
列出远端仓库
1
2
3git remote
git remote -v # 显示读写远程仓库使用的Git保存的简写与其对应的URL
git remote show <remote> # 查看远程仓库和本地仓库的对应关系添加更改远程仓库
1
git remote add <remote> <url>/<local.git> # 添加远程仓库
1
2git remote rename <old-remote> <new-remote> # 重命名远程仓库
git remote set-url <remote> <url> # 修改远程仓库的url移除远程仓库
1
2git remote rm origin # 移除远程仓库
git remote prune origin # 远程删除了分支本地也删除
2. push
推送到远端仓库
1
2git push <remote> <branch> # 同名
git push <remote> <local_branch>:<remote_branch> # 不同名推送标签到远端仓库
1
2git push <remote> <tag> # 推送一个标签
git push <remote> --tags # 推送多个标签移除/删除远端分支
1
2git push <remote> :<branch>
git push <remote> --delete <branch>
3. pull
拉取分支最新内容
pull = fetch + merge
1
git pull <remote> <branch>
变基
1
git pull --rebase
4. fetch
从远端仓库拉取并不会自动合并
1
2git fetch <remote> <branch>
git fetch <remote> pull/<id>/head:<branch> # 从远程仓库根据id拉下某一状态到本地分支抛弃本地所有修改回到远程仓库的状态
1
git fetch --all && git reset --hard <remote>/<branch>
三、服务器上的Git
1. 四种协议
本地协议
1
2git clone <path>/<local.git> # 硬链接或直接复制
git clone file://<path>/<local.git> # 没有外部参考的干净版本库副本1
git remote add <remote> <path>/<example.git>
HTTP协议
SSH协议
Git协议
2. 在服务器上搭建Git
创建裸库
1
2
3git init --bare
or
git clone --bare <repo> <repo.git>将裸库上传服务器
1
2
3
4
5
6scp -r <repo.git> user@git.example.com:/opt/git
git clone user@git.example.com:/opt/git/<repo.git> # 注意权限(要有可读权限)
ssh user@git.example.com
cd /opt/git/<repo.git>
git init --bare --shared # Git会自动更改权限为可写(--shared)
3. 签署工作
GPG
1
2
3gpg --list-keys # 配置 GPG 并安装个人密钥
gpg --gen-key # 还未安装密钥,生成一个
git config --global user.signingkey <key> # 签署签署标签
1
2git tag -s <tag> -m <"tag comments"> # -s替换-a
git show <tag> # 你会看到GPG签名1
git tag -v <tag> # 验证标签(签署者的公钥需要在你的钥匙链中)
签署提交
1
git commit -a -s -m <"comments">
1
git log --show-signature # 查看签名
四、Git在生产中的应用
1. master分支
线上分支,主分支,中小规模项目作为线上运行的应用对应的分支。
2. develop分支
是从master创建的分支,一般作为开发部门的主要开发分支,如果没有其他并行开发不同期上线要求,都可以在此版本进行开发,阶段开发完成后,需要合并到master主分支上,准备上线。
3. feature/xxxx分支
从develop创建的分支,是开发新功能的分支,一般是同期并行发布,但不同期上线时创建的分支,分支上的研发任务完成后merge到develop分支。
4. hotfix/xxxx分支
从master派生的分支,一般作为线上(master)bug修复使用,修复完成后要合并到master,test,develop分支。
5. release
准备要发布版本的分支,用来修复bug,基于develop,完成后merge回develop和master
6. 其他
test分支(用于代码测试),pre分支(用于预上线)
Github
一、SSH TOKEN
1. SSH
1 | ssh-keygen -t rsa # 生成SSH公钥 |
验证是否配置成功
1
2ssh -T git@gitee.com
ssh -T git@github.com配置git服务器
1
2
3
4
5sudo adduser git
su git
cd
mkdir .ssh && chmod 700 .ssh
touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys我们将使用 authorized_keys 方法来对用户进行认证。同时我们假设你使用的操作系统是标准的 Linux 发行版
首先,创建一个操作系统用户 git,并为其建立一个 .ssh 目录
1
2
3cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys
cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys将这些公钥加入系统用户 git 的 .ssh 目录下 authorized_keys 文件的末尾
1
2
3
4
5cd /opt/git
mkdir project.git
cd project.git
git init --bare
Initialized empty Git repository in /opt/git/project.git/现在我们来为开发者新建一个空仓库
2. token
1 | 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 |
二、github常用功能
1. Watch Star Fork
Watch: 观察(关注)
Star: 点赞(对项目的支持)
Fork: 获得别人项目的一份拷贝(在获得仓库管理者的merge后你的项目
2. Code
你项目的代码文件(建议加一个readme,方便别人使用)
3. Issues
该项目的一些问题或者bug
分为解决的问题(close)和待解决(open)
4. Pull requests
一般先将别人的项目fork到你自己的仓库(相当于是原项目的分支)
然后你把项目再clone到本地
修改完成后push到远端仓库
通过pull requests提交PR
等待原作者review你的代码,如果接受,你就是项目的贡献者之一了
5. Projects
分类Issues, pull requests等
6. Wiki
说明文档
7. Pulse
汇总概况
8. Graphs
以图的形式展开项目整体情况
三、Git Flow
1. gitflow工具
git flow feature start A 创建以feature开头的分支
git flow feature finish A 合并到develop分支
如果是hotfix或者release分支甚至会自动帮你合并到develop、master