Install
Mac 用户需要先安装 Xcode command line tools,再通过 HomeBrew 安装 GIT,然后检测下 GIT 版本
1 | xcode-select --install |
如果检测的GIT版本不是刚安装的版本,就用 which
命令检测下GIT的安装路径。然后把该路径添加到变量配置文件里,Bash用户编辑 ~/.bash_profile 或 ~/.bashrc,ZSH用户编辑 ~/.zshrc 文件
- which -a git
- /usr/bin/git:Mac_Xcode内置的GIT路径
- /usr/local/bin/git:用户安装的GIT路径
- echo export PATH=”/usr/local/bin/git:$PATH” >> ~/.zshrc
- source ~/.zshrc 重启环境变量配置文件
更新GIT使用 brew upgrade git;卸载GIT使用 sh /usr/local/git/uninstall.sh
开始前
help
学习工具或者语言时,首先要做的是应该知道如何查找或者如何获得工具的使用帮助,GIT也不例外
1 | git help -a #列出全部命令 |
config
初次使用需要设置用户名及其邮箱,git init 初始化项目时会用到,这些信息会在你commit时包含到附注里
1 | git config --global user.name ["Your Name"] |
–global 是全局(也称用户级,注意global前面有两个中划线-)设置的意思,除了用户级还有系统级 –system 和项目级 –local
git config core.ignorecase false 设置大小写敏感
git config –global -e 编辑全局配置文件
git config –list –show-origin 列出所有配置文件位置
git config –list 列出当前仓库的所有配置信息
git config –list –global 列出全局的配置信息
git config –global alias.st status 设置全局的命令别名
查看、更改、删除 config 内的用户名或者邮箱
1 | # 查看 |
Tab prompt
设置GIT命令提示,终端下按TAB键让它帮我们自动补全GIT命令,可提高我们的使用效率
1 | cd ~ && git clone https://github.com/git/git.git |
配置环境变量,不知道编辑哪个文件的请参考上一步
1 | # 设置自动完成 |
重启环境配置文件 source ~/.zshrc
https://git-scm.com/book/id/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-Bash
初始项目
git init
初始化本地项目(会在项目根目录下生成一个 .git 文件夹,这是GIT工作的核心)
1 | git init |
裸仓库
初始化后的内容,跟你 init 生成的 .git 目录里面的东西几乎一样,该目录不允许直接操作没有工作区,只能接收push提交的版本记录,你在代码托管平台建仓库时就是建的这玩意
1 | git init --bare |
git clone
从远程库克隆到本地(可以使用https协议或原生GIT协议)
1 | git clone https://github.com/vuejs/vue-cli.git |
git remote
跟踪(添加)远程仓库
1 | git remote add origin https://github.com/user/repo.git |
查看项目下的远程仓库
1 | git remote -v |
https://help.github.com/cn/github/using-git/adding-a-remote
https://git-scm.com/docs/git-remote
配置项目
.gitignore
项目 clone 或 init 后,你做的第一件事应该是,在项目的根目录下创建个 .gitignore 文件。它是用来帮助你忽略某些文件的,语法支持正则表达式。如果你不知道该忽略那些文件的话,可直接拷贝 Github 上给出的模版 https://github.com/github/gitignore https://www.gitignore.io/
主要应用场景:
- 忽略操作系统自动生成的文件,例如:.DS_Store、Desktop.ini
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如 Java 编译产生的 .class 文件
- 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件
https://www.liaoxuefeng.com/wiki/896043488029600/900004590234208
如果你不想创建 .gitignore 文件或者不愿意跟别人共享的话,可把规则写在 .git/info/exclude
内,这样就不会影响到其他人了,也不会 push 到 remote repo。你还可以使用 git config --global core.excludesfile ~/.gitignore_global
指定全局的 .gitignore 文件
1 | .DS_Store # 忽略指定的文件 |
- / 反斜杠转义特殊字符,例如:#、! 等在 .gitignore 有意义的字符
- * 通配符
- / 结尾表示忽略整个文件夹
- ! 不忽略某个文件
- ?代表任意的一个字符
- {!ab} 必须不是此类型
- {ab,bb,cx} 代表 ab, bb, cx 中任一类型即可
- [abc] 代表 a, b, c 中任一字符即可
- [^abc] 代表必须不是 a, b, c 中任一字符
项目实际开发中由于你的疏忽大意,把不该提交的文件做成了版本,这时再添加到 .gitignore 是无效的。正确的做法是先 git rm -r –cached filename
删除下缓存,再添加到 .gitignore 内(另外GIT默认不会把空目录纳入到版本管控里,你可以在空目录里创建一个空白的 .gitignore,这样空白目录就会正常的提交了)
GIT 默认会监听文件的权限,可使用以下命令关闭(也可直接配置 .git/config 文件)。如果是脚本、二进制程序等需要权限认证的建议还是开启,只是源码的话可随意
git config core.filemode false 本地设置
git config –global core.filemode false 全局设置
ssh_key
GIT 管理代码版本时用到的传输协议有四种:本地传输、SSH 协议、Git 协议和 HTTPS 协议。而我们平时链接远程仓库需要验证授权时,主要用到的是SSH协议,所以托管代码前还需要在本地配置SSH密钥
单个账户
执行 ssh-keygen 一路回车,命令选项说明请查阅 https://ipcmen.com/ssh-keygen
1 | ssh-keygen -t rsa -b 4096 -C ["email@example.com"] |
多账户
执行 ssh-keygen 后在第一次提示处,输入密钥保存名称及其位置路径(SKM 插件也能管理多账户 key【类似NVM】)
1 | # ssh-keygen -t ...执行后终端内会有三次提示信息 |
密钥创建成功后,需要把 公钥(~/.ssh/id_rsa.pub) 部署到代码托管网站上,以 Github 为例,ssh 命令测试链接是否成功
1 | ssh -T git@github.com |
在创建密钥时设置了密码,可使用下述命令进行设置,避免每次 Push\pull 时都需要手动输入密码
设置记住密码(默认15分钟)
git config –global credential.helper cache
如果想自己设置时间,例如一个小时之后失效
git config credential.helper ‘cache –timeout=3600’
还可以选择长期存储密码
git config –global credential.helper store
或者在增加 remote 时带上密码
http://yourname:password@git.oschina.net/name/project.git
管理项目
git add
跟踪文件并添加到索引区(index\暂存区)
1 | # 除 git rm 删除的文件外,其它的都提交到暂存区(new 和 modified) |
还原(回退)整个工作区
1 | git reset --hard HEAD |
git clean
主要清除未跟踪的文件使用
1 | git clean -n |
git rm
从版本库中删除文件,请使用 git rm
不要直接删除(空目录除外)【没直接用 git rm 删除的,请分别 git rm 和 git add 下】
1 | # 删除工作区和暂存区内的文件 |
只删除索引区(index\暂存区)内的文件
1 | git rm --cached README.md |
恢复误删除的文件,实际是版本库(历史记录)里的版本替换了工作区里的版本而已【未追踪的文件是无法恢复】
1 | git restore README.md |
git mv
移动或者重命名文件
1 | git mv ["file"] ["path"] |
git restore
版本库里的文件同时恢复到索引区(index\暂存区)和工作区【为了区分 checkout 混淆部分,2.23版本新增了 restore 和 switch,restore 只针对文件,switch 则针对分支】
1 | git restore --source=HEAD --staged --worktree ["file"] |
版本库里的文件恢复到索引区
1 | git restore --source ["HEAD\master\SHA-1"] ["file"] |
索引区恢复到工作区或取消此次暂存操作
1 | git rm --cached ["file"] #仓库初次暂存时使用 |
工作区还原文件
1 | git checkout -- ["file"] |
git commit
文件 add 到索引区(index\暂存区)后,要用 commit
把这次暂存的所有文件做成版本,提交到版本库里(历史记录)(commit的内容实际是 .git/index 索引文件内的信息【还有就是commit附注会储存在 .git/COMMIT_EDITMSG 内,主要是给作者提示使用,GIT不会使用,下次commit时的附注也会覆盖此文件】)
如果 commit 时不加参数,GIT会用默认的编辑器打开一个交互式窗口,并提示下面类似的信息
1 | # Please enter the commit message for your changes. Lines starting |
进入交互式模式后,需要把输入法切换成英文状态,按 i 键输入本次做成版本时的描述信息。完成后按 esc 退出插入模式,进入指令模式再按 :wq 保存退出
git config –global core.editor “vim” 可修改git默认的编辑器
git config –global commit.template ~/.xxx.txt 可设置commit提交时的模版信息
加 -m 参数,可将附注与命令放在同一行
1 | git commit -m ["单行写commit"] |
修改上次附注(已push到远程仓库的误用!)
1 | git commit --amend |
再次 commit 时使用上次的附注(已push到远程仓库的误用!)
1 | git commit --amend --no-edit |
删除版本库里所有版本(附注/历史记录)【慎用】
1 | git update-ref -d HEAD |
查看项目
git status
1 | git status #查看工作区内文件的状态 |
git show
1 | git show #查看当前版本的修改 |
git log
查看 commit 历史记录,不指定参数会列出所有记录,最近的排在最上方,显示内容包含提交对象的哈希值,作者、日期和说明(输入法英文状态下。按 `F` 键向下翻屏、按 `G` 键直接回到历史记录顶部、按上下方向键可一行一行查看、按 `Q` 退出)
1 | git log |
更多案例请查阅 GIT-SCM官网
git blame
帮助你查看某行代码是由谁写的、什么时间写的、为什么这么写…
1 | git blame README.md |
指定显示的区间段
1 | git blame -L 8,12 README.md |
https://weinan.io/2019/10/22/git.html
https://wxnacy.com/2019/05/21/git-blame/
git diff
查看索引区(index\暂存区)里的文件跟工作区的有什么不同
1 | git diff README.md |
索引区(index\暂存区)跟版本 (版本的 SHA-1 校验和或者HEAD)
1 | git diff --cached README.md |
版本跟版本
1 | git diff SHA-1 SHA-1 |
本地分支跟远程分支
1 | git diff master origin/master |
查看冲突文件列表,解决冲突时比较有用
1 | git diff --name-only --diff-filter=U |
git difftool --tool-help 可查询当前支持的GUI工具
git difftool --tool=<tool> 指定要使用的GUI工具
分支管理
git branch
1 | git branch ["branch"] #添加分支 |
git switch
1 | git switch ["branch"] #切换分支 |
git stash
切换分支时,需要先把工作区内所有文件,做成版本才可切换,否则会报错(强制切换内容会丢失)!切换分支又不想 commit,这时就可以使用 stash
1 | git stash list #查看stash列表 |
git merge
1 | git merge ["branch"] #把指定分支合并到当前分支上 |
git rebase
使用 rebase 变基操作可编辑、修改、删除、压缩提交等管理仓库内的历史记录。注意 rebase 打开的 commit 顺序跟 git log 是相反的,旧的在前新的在后。使用过程要经常 status 下,如果变基过程中出现错误或者不想修改了,请使用 git rebase --abort
退出变基操作,恢复到修改前的状态!(慎用)
合并分支
rebase 跟 merge 的区别在于,rebase 合并的分支 ASCII 图像显示的是直线
1 | git rebase ["branch"] #把指定分支合并到当前分支上 |
git rebase -i [START_SHA-1] [END_SHA-1] 修改 N 次的 commit 信息(慎用)
变基时有用的命令
- pick(p):保留该提交信息,重新排序可更改提交的顺序
- reword(r):只更改提交信息
- edit(e):可修改提交信息也可修改代码
- squash(s):将提交合并到上一个提交中
- fixup(f): 将提交合并到上一个提交中,而且不保留该提交信息
- drop(d): 删除提交信息
- exec(x): 提交时要执行的shell命令
https://help.github.com/cn/github/using-git/about-git-rebase
1 | # 从倒数第二个 commit 开始修改 |
标签管理
git tag
想永久保存提交快照或者记录项目版本时,就使用GIT标签
1 | git tag #查看标签 |
版本回退
git reset
reset 的作用是修改 HEAD 的位置,即将 HEAD 指向的位置改变为之前存在的某个版本。如果想恢复到之前的某个提交版本,且那个版本之后提交我们都不要了,就可以用这种方法(慎用)
回退到上个 commit 版本(当前版本的前一个)
1 | git reset --hard HEAD^ |
–hard 还原工作区及其暂存区(硬重置)
–mixed 还原暂存区,且把 HEAD 和分支名的引用指向该 commit(默认选项)
–soft 工作区及其暂存区保持原样,只是把 HEAD 指向该 commit(软重置)
该方法通常结合 git reflog 使用(只要 HEAD 发生变化 reflog 都会记录【.git/logs/HEAD】)
git revert
revert 用于“反做”某一个版本,以达到撤销该版本的修改的目的。例如:我们 commit 了三个版本,想撤销版本二,但又不想影响到版本三的内容,就可以使用此方法“反做”下版本二,创建个版本四
1 | git revert HEAD^ |
git revert SHA-1 === git revert -e SHA-1 默认值 -e
git revert -n [START_SHA-1] [END_SHA-1] 撤销多个版本
git revert –abort 取消
提交项目
git push
1 | git push #推送已同步的所有分支 |
更新项目
git fetch
1 | git fetch |
git pull
1 | git pull |
多人合作时拉取项目时,pull 操作会自动创建一条 commit,人多的话会有很多该信息不利于查看,可使用下述命令解决
1 | git pull --rebase origin master |
FQA
中文乱码
最近升级到了GIT2.25.0版本,并且终端提示信息改成了中文,有点扯的就是 git status
时文件名称乱码了!乱码形式如下:
位于分支 master
您的分支领先 ‘origin/master’ 共 2 个提交。
(使用 “git push” 来发布您的本地提交)
尚未暂存以备提交的变更:
(使用 “git add <文件>…” 更新要提交的内容)
(使用 “git restore <文件>…” 丢弃工作区的改动)
修改: package.json
未跟踪的文件:
(使用 “git add <文件>…” 以包含要提交的内容)
“source/_posts/github-\346\201\242\345\244\215\345\267\262\345\210\240\351\231\244\347\232\204\344\273\223\345\272\223.md”
修改尚未加入提交(使用 “git add” 和/或 “git commit -a”)
解决方案是:
https://www.worldhello.net/gotgit/08-git-misc/020-git-charset.html
1 | git config --global core.quotepath false |
或者设置环境配置文件切换到英文状态
1 | export LC_ALL=en_US.UTF-8; |
其它跟UTF-8字符集有关的问题
1 | git config --global i18n.commitEncoding utf-8 #提交 commit 时乱码 |