bingoogolapple.github.io
bingoogolapple.github.io copied to clipboard
Git 学习笔记
配置 git config
影响范围说明,优先级从上往下依次递增
- --system 该计算机范围内,基本上不会用到这个
- --global 该计算机当前登陆用户范围内(配置自己常用的用户名和邮箱,如 GitHub 的)
- --local 当前仓库范围内(多用于在公司项目的目录里,配置公司的项目范围里的用户名和邮箱)
配置常用别名
git config --global alias.cfg "config"
git cfg --global alias.ci "commit -a -v"
git cfg --global alias.throw "reset --hard HEAD"
git cfg --global alias.throwh "reset --hard HEAD^"
git cfg --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
配置该计算机当前登陆用户的名字和邮箱
git cfg --global user.name "bingoogolapple"
git cfg --global user.email "[email protected]"
跳转到公司项目目录下,配置公司的项目项目范围里的用户名和邮箱
git cfg --local user.name "wanghao"
git cfg --local user.email "[email protected]"
设置 Git 大小写敏感,安装完 Git 后一定要配置这个,安装完 Git 后一定要配置这个,安装完 Git 后一定要配置这个
git cfg --global core.ignorecase false
解决 git status 中文乱码
git cfg --global core.quotepath false
防止仓库较大,curl 的 postBuffer 默认值较小时 clone 失败「Unable to rewind rpc post data - try increasing http.postBuffer」
git cfg --global http.postBuffer 20480000
设定默认的编辑器
git cfg --global core.editor vim
查看当前项目的 Git 配置信息
git cfg --local -l
查看影响整个计算机的 Git 配置信息,如果当前在一个 Git 仓库的目录中,输出的配置信息的末尾就是「git cfg --local -l」输出的信息
git cfg -l
删除某项配置,例如删除用户名
git cfg --global --unset user.name
直接编辑配置信息,默认在 vim 中编辑。每个仓库的 Git 配置文件都放在「.git/config」文件中。而当前用户的 Git 配置文件放在用户主目录下的一个隐藏文件「.gitconfig」中。你也可以找到该文件用自己喜欢的编辑器来编辑
git cfg -e
HEAD索引
这只是简单的一个文件,包含了你当前指向的那个提交的SHA-1索引值。
所有的分支指针都保存在.git/refs/heads里,HEAD在.git/HEAD里,而标签保存在.git/refs/tags里
iqegganiddeiMac:.git iqeggandroid$ cat HEAD
ref: refs/heads/master
iqegganiddeiMac:.git iqeggandroid$ cat refs/heads/master
30f83e55adfc88f8e42b42b0ab50790d39c7f483
git工作流
初始化
git init
添加文件到版本控制中
git add 文件1 文件2
git不会自动跟踪新建或删除文件,每次添加或删除某个文件后用git add xxx或git rm xxx很麻烦,通常在添加或者删除任意多个文件之后执行下面的命令,git会自动重新扫描当前目录下改动的文件git add和rm都被这一步代替了
git add .
提交。git commit 只负责把暂存区的修改提交到当前分支
git commit -m ""
加上-a(要先-a,再写-m),让git自动跟踪修改过的文件(前提是文件已经加入了版本控制)
git commit -a -m ""
做新的版本之前查看新的版本会保存哪些修改(和执行add .之前执行diff看到的内容差不多)
git commit -av
修改最新 commit 的 message
git commit --amend
修改老旧 commit 的 message,改为 r,然后编辑 message
git rebase -i 要修改的commit的父亲commit的hash值
合并多个 commit 的 message,改为 s 或 f,然后编辑 message。「骚操作:还能修改 commit 的顺序」
git rebase -i 要修改的commit的父亲commit的hash值
查看日志。最上面是最新的提交
git log
在一行中查看日志,不会显示日期和提交者
git log --pretty=oneline
查看分支合并图
git log --graph --pretty=oneline --abbrev-commit
查看指令使用记录(能够查看所有的版本)
git reflog
扔掉当前工作区的修改(如果之前已经执行了 git add 操作,暂存区里有该文件的修改,就变成和暂存区里的一样,否则就变成和当前分支 HEAD 里的一样)
git checkout -- <file>
恢复到某个版本(--mixed(默认值):这些 commit 的和暂存的所有文件都会被放到工作区,--soft:这些 commit 的所有文件都会被放到暂存区;--hard:这些 commit 的和暂存的所有文件都会被丢掉)
git reset --mixed 版本号
扔掉当前暂存区的修改(默认加了 --mixed,只是清空了暂存区里的修改,变成和 HEAD 一样;工作区里的内容不变)
git reset HEAD [<files>]
扔掉暂存区和工作区里所有的修改(加上 --hard 后工作区和暂存区都会被清空,变成和 HEAD 一样)
git reset --hard HEAD [<files>]
回到上(多少个^^)个版本
git reset --hard HEAD^^^
回到上(n)个版本
git reset --hard HEAD~n
忽略某个已被跟踪的文件,但不会删除该文件
git rm --cached 文件
删除某个已被跟踪的文件,如果是删除整个目录需加上-rf参数
git rm 文件
查看当前状态
git status
查看已经被跟踪的文件
git ls-files
查看工作目录和 INDEX(暂存区)之间的差异(修改后,提交前 和 上一次commit或者add .后的差异)
git diff
git diff -- 文件名1 文件名2
查看 INDEX(暂存区)和 HEAD 之间的差异(add .后 和 上一次commit的差异)
git diff --staged
git diff --cached
把刚才的修改藏起来(应用场景:开发一个大的功能时,发现之前的版本有个bug,把刚才的修改隐藏起来,然后去修复bug,修复完记得提交,然后再把刚才隐藏的修改取出来)
1、文件已经被 git 跟踪,只是修改了代码(而不是新条件文件),我们
可以使用 git stash 或 git stash save "注释" 来暂存修改。
2、如果有新添加的文件,那么就需要添加 -a 参数(如,git stash -a 或 git stash save -a "注释"),
或先 git add . 然后再使用 git stash 或 git stash save "注释" 来暂存修改。
把刚才藏起来的修改取出
git stash apply stash@{0} // 如果是取出最近的一个stash,可以省略stash@{0}
删除stash
git stash drop stash@{0} // 如果是删除最近的一个stash,可以省略stash@{0}
清空所有stash
git stash clear
取出并删除stash
git stash pop stash@{0} // 如果是取出并删除最近的一个stash,可以省略stash@{0}
查看所有stash
git stash list
删除未监视的文件untracked files
# 删除 untracked files
git clean -f
# 连 untracked 的目录也一起删掉
git clean -fd
# 连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的 .o之类的文件用的)
git clean -xfd
# 在用上述 git clean 前,墙裂建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删
git clean -nxfd
git clean -nf
git clean -nfd
分支操作
查看本地分支列表
git branch
列出全部分支和 commit 版本
git branch -v
查看本地分支和远程分支的跟踪关联关系
git branch -vv
查看远程分支列表
git branch -a
git branch -av
添加一个新的remote远程仓库
git remote add [remote-name] [url]
显示每个远端服务器的URL
git remote -v
origin [email protected]:bingoogolapple/learngit.git (fetch)
origin [email protected]:bingoogolapple/learngit.git (push)
// 上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。
删除一个remote
git remote rm [name]
重命名remote
git remote rename [old-name] [new-name]
修改远程仓库地址
git remote set-url origin 仓库地址
从当前分支创建分支
git branch branchname
从当前分支创建分支+切换分支
git checkout -b branchname
从当前分支的某个版本号状态新建一个分支
git checkout 43237 -b branchname
切换到branchname分支
git checkout branchname
如果远程分支有个 develop ,而本地没有,想把远程的 develop 分支迁到本地
git checkout -b develop origin/develop
删除分支,-D表示强制删除
git branch -D branchname
删除远程分支
git push origin :branchname
提交本地test分支作为远程的master分支
git push origin test:master
提交本地test分支作为远程的test分支
git push origin test:test
git push命令用于将本地分支的更新,推送到远程主机。它的格式与git pull命令相仿
git push <远程主机名> <本地分支名>:<远程分支名>
注意,分支推送顺序的写法是<来源地>:<目的地>,所以git pull是<远程分支>:<本地分支>,而git push是<本地分支>:<远程分支>
如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。
将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。
git push origin master
如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
git push origin :master
等同于
git push origin --delete master
如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。将当前分支推送到origin主机的对应分支
git push origin
如果当前分支只有一个追踪分支,那么主机名都可以省略。不带任何参数的git push,默认只推送当前分支
git push
如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git push。
将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。
git push -u origin master
还有一种情况,就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要使用–all选项。
git push --all origin
如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用–force选项。
git push --force origin
紧急修复分支。「git merge --no-ff -m "注释" branchname」 命令用于合并指定分支到当前分支
合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
$ git checkout -b hotfix-1.2.1 master
$ ./bump-version.sh 1.2.1
$ git commit -a -m "Bumped version number to 1.2.1"
$ git checkout master
$ git merge --no-ff -m "注释" hotfix-1.2.1
$ git tag -a 1.2.1
$ git checkout develop
$ git merge --no-ff -m "注释" hotfix-1.2.1
$ git branch -d hotfix-1.2.1
git的合并在默认情况下会采用fast-farward merge模式,将master直接指向dev分支上,添加上 --no-ff选项之后,会执行正常合并,在Master分支上生成一个新节点,这样可以明确合并的操作
合并 test2 时「git merge test2」,合并 test3 时「git merge --no-ff test3」

终止 merge
git merge --abort
继续 merge
git merge --continue
只克隆指定分支
git clone -b branchname https://github.com/bingoogolapple/GitWorkflow.git
刷新远程分支列表
git fetch -p
指定本地dev分支与远程origin/dev分支的关联关系
git branch --set-upstream-to=origin/dev dev
取消本地dev分支与远程分支的关联关系
git branch --unset-upstream dev
从本地已有仓库建一个远程仓库
# 哑协议,没有进度
git clone --bare ~/git/VSCode/git-note/.git git-note1.git # 只包含 git-note/.git 目录里的内容
git clone ~/git/VSCode/git-note/.git git-note2.git # 包含整个 git-note 目录里的内容
# 智能协议,有进度
git clone --bare file:///Users/wanghao/git/VSCode/git-note/.git git-note3.git # 只包含 git-note/.git 目录里的内容
git clone file:///Users/wanghao/git/VSCode/git-note/.git git-note4.git # 包含整个 git-note 目录里的内容
更新数据
GitHub两步认证
ssh-keygen -t rsa -b 4096 -C "[email protected]"
将生成的公钥添加到github中
如果开启了两步验证,还需在settings/applications/generate new token
git config --global credential.helper store
Username for 'https://github.com': bingoogolapple
Password for 'https://[email protected]':这里的密码就是刚才生成的token
一旦远程主机的版本库有了更新(Git术语叫做commit),需要将这些更新取回本地,这时就要用到git fetch命令。将某个远程主机的更新,全部取回本地。
git fetch <远程主机名>
取回特定分支的更新。所取回的更新,在本地主机上要用”远程主机名/分支名”的形式读取。比如origin主机的master,就要用origin/master读取。
git fetch <远程主机名> <分支名>
取回远程主机的更新以后,可以在它的基础上,使用git checkout命令创建一个新的分支。在origin/master的基础上,创建一个新分支。
git checkout -b newBrach origin/master
也可以使用git merge命令或者git rebase命令,在本地分支上合并远程分支。在当前分支上,合并origin/master。
git merge origin/master
或者
git rebase origin/master
git fetch相当于是从远程获取最新版本到本地,不会自动merge。
git fetch origin master:tmp
git diff tmp
git merge tmp
git pull相当于是从远程获取最新版本并merge到本地
git pull origin master
- 在实际使用中,git fetch更安全一些,因为在merge前,我们可以查看更新情况,然后再决定是否合并
- 如果本地分支和远程分支没有关联过,并且各自提交过commit,是不能进行 merge 的,需要加上 --allow-unrelated-histories 参数
标签操作
列出标签
git tag
打标签
git tag -a tagname -m "注释" 9fbc3d0 // 默认标签是打在最新提交的commit上的,加上commit id可以打在指定commit上
切换到标签,与切换分支命令相同
git checkout tagname
查看标签的版本信息
git show tagname
push单个tag到服务器
git push origin tagname
推送全部尚未推送到远程的本地标签
git push origin --tags
删除本地tag
git tag -d tagname
用push, 删除远程tag
git push origin :refs/tags/tagname
获取远程tag
git fetch origin tag tagname
合并多个commit
git rebase -i <不变动的commit的SHA-1>
需要重点注意的是相对于正常使用的 log 命令,这些提交显示的顺序是相反的
git reflog
e23b08e HEAD@{8}: commit: b2
1694e14 HEAD@{9}: commit: b1
a9104d8 HEAD@{10}: commit (initial): a
git rebase -i a9104d8
git rebase -i HEAD~2
终止 rebase
git rebase --abort
继续 rebase
git add .
git rebase --continue
解决Git的大小不敏感问题
一是设置Git大小写敏感
git config --global core.ignorecase false
二是先删除文件,再添加进去
git rm <filename>; git add <filename> ; git commit -m "rename file"
忽略文件
你想添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore忽略了。如果你确实想添加该文件,可以用-f强制添加到Git
git add -f test.txt
你发现,可能是.gitignore写得有问题,需要找出来到底哪个规则写错了
$ git check-ignore -v App.class
.gitignore:3:*.class App.class
// Git会告诉我们,.gitignore的第3行规则忽略了该文件,于是我们就可以知道应该修订哪个规则。
忽略、恢复已跟踪文件的改动
忽略已跟踪的文件
git update-index --assume-unchanged /path/to/file
恢复已跟踪的文件
git update-index --no-assume-unchanged /path/to/file
多帐号配置
生成 ssh 密钥
- ssh-keygen -t rsa -b 4096 -C "[email protected]"
- bga_rsa
- ssh-keygen -t rsa -b 4096 -C "[email protected]"
- company_rsa
拷贝公钥到剪贴板可以用 pbcopy 命令「pbcopy < ~/.ssh/bga_rsa.pub」
在 .ssh 目录下,增加 config 配置,config 可以配置多个 git 的帐号「vim ~/.ssh/config」
#Host myhost(这里是自定义的 host 简称,以后连接远程服务器就可以用命令 ssh myhost)[注意下面有缩进]
#User 登录用户名(如:git)
#HostName 主机名可用ip也可以是域名(如:github.com 或者 bitbucket.org)
#Port 服务器open-ssh端口(默认:22,默认时一般不写此行)
#IdentityFile 证书文件路径,是指 rsa 密钥,不是公钥 pub 文件(如 ~/.ssh/id_rsa_*)
Host github.com
User bingoogolapple
Hostname github.com
IdentityFile ~/.ssh/bga_rsa
Host bitbucket.org
User bingoogolapple
Hostname bitbucket.org
IdentityFile ~/.ssh/bga_rsa
Host git.company.com
User wanghao
Hostname git.company.com
IdentityFile ~/.ssh/company_rsa
配置用户名和邮箱
// 设置全局范围的
git config --global user.name "bingoogolapple"
git config --global user.email "[email protected]"
// 设置仓库
git config user.name "wanghao"
git config user.email "[email protected]"
- 修改目录大小写
git mv foldername tempname && git mv tempname folderName
- 查看类型(commit、tree、blob)
git cat-file -t hash值
- 查看内容
git cat-file -p hash值