Git学习笔记
Git学习笔记
一篇混乱的学习笔记
Git是一个强大的分布式版本管理系统,本文主要作为学习笔记。
首先是安装,在这里下载,安装过后,打开git bash 执行下面的命令设置用户名和邮箱:
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
需要注意的是,git只能跟踪文本文件的变动,无法跟踪媒体文件的变动。
在一个空目录下git init
可以创建空仓库,目录下会多出一个.git
文件夹,里面的文件时git的工作文件(idea、vscode这类编辑器也都会创建一个文件夹)
在我写下的这篇md时,vscode居然检测出来git了
使用命令git add 文件名
把文件添加到仓库;使用git commit
提交到仓库,后面跟上-m "改变的内容"
可以添加修改说明,如果不加参数git会自动打开一个日志文件。
add可以一次添加多个文件,文件名以空格隔开,如果文件名中有空格可以用双引号引着。
加参数.
可以把当前文件夹的所有文件添加到暂存区。
git status
可以查看当前git状态,git diff 文件名
可以查看文件被被修改了什么。
如果文件仅仅是修改,git status
会有“Changes not staged for commit:”,如果修改之后add了,查看状态会有:“Changes to be committed:”
commit如同一个快照,提交之后可以恢复。使用git log
可以查看提交记录,按q
退出。觉得输出太多的话可以添加参数:git log --pretty=oneline
,日志中的黄色一大串是版本号。
可以使用git reset
命令来进行回退,HEAD
表示当前版本,HEAD^
表示上一个版本,HEAD^^
表示上上个,前第一百个版本的话写作HEAD~100
。
使用git reset --hard HEAD^
回退上个版本。回退之后还可以通过版本号来还原:git reset --hard a0e3c70
,版本号不必写全,git会自动找(这种方式需要知道版本号)。
如果窗口关闭后版本号无法查看,可以使用git reflog
来查看每次的命令,然后进行回退。
工作区:即本地目录。
版本库:工作区的.git
文件夹不算工作区,而是Git的版本库,版本库中存有暂存区,以及Git自动创建的第一个分支master
,以及指向master
的指针HEAD
。
git add
命令将文件修改提交到暂存区,可以添加参数--all
来保存所有文件并更新至缓存区。git commit
是将暂存区的所有变动提交到当前分支。而未添加的文件状态为“Untracked”。commit只会提交暂存区的修改,而不是当前文件的修改。
可以使用gir diff HEAD -- 文件名
来查看工作区和版本库里最新版的区别。
使用git checkout -- 文件名
可以将文件回退到最后一次add的状态。
使用git reset head 文件名
把暂存区的修改移动到工作区(也就是撤销距上次commit的所有add)
删除文件:可以直接删除 -> add -> commit
,也可以git rm 文件名 -> commit
,git rm之后只能从版本库回退,直接删除之后可以从暂存区回退。
远程仓库
在git bash里输入ssh-keygen -t rsa -C "邮箱"
来创建ssh key(下面有ssh-keygen的参数详情),一路回车可以看到在用户文件夹下创建了.ssh
的文件夹,其中id_rsa为私钥,id_rsa.pub为公钥,然后将公钥添加到GitHub中(设置页面)。使用ssh -T git@github.com
检测与GitHub的连接,然后可以关联远程仓库:git remote add origin git@github.com:michaelliao/learngit.git
(这是廖雪峰的仓库23333),如果地址输入错误可以使用git remote rm origin
来移除关联。如果出现连接拒绝可以手动添加私钥:ssh-add ~/.ssh/id_rsa
。然后便可使用git push -u origin master
来推送至远程(origin是远程库名字,一般不修改,-u参数为第一次使用时添加,表示关联本地master和远程master)。
git push origin master
推送分支,git pull origin master
拉取分支。(有时候会第一次拉取失败,可以在pull后添加--allow-unrelated-histories
确定是当前分支)
一般情况先建立远程仓库,然后再创建本地:git clone git@github.com:michaelliao/gitskills.git
,GitHub既支持ssh协议的git://
,也支持HTTP协议的https://
,一般git协议更好。
分支
推荐一个Git中分支介绍的文章:实际项目中如何使用Git做分支管理
言归正传,之前的操作我们都是在master分支上进行,下载我们需要创建一个分支来开发不同的功能。
使用git checkout -b dev
来创建并切换到分支dev。参数-b
代表创建并切换,相当于:git branch dev; git checkout dev
两句。使用git branch
可以查看当前分支。
使用git merge dev
来把dev分支合并到master,出现Fast-forward
代表快进模式,也就是把master的head直接指向dev分支。接着就可以删除dev分支了:git branch -d dev
。
由于git checkout 分支
和git checkout -- 文件名
两个命令容易混淆,git提供了switch
来切换分支:git switch -c dev
其中-c
参数代表创建新分支。
分支冲突时git会以<<<<<<<
、=======
、>>>>>>>
来标记不同的分支,使用下面的命了可以查看分支合并情况:git log --graph --pretty=oneline --abbrev-commit
合并时添加--no-ff
参数可以使用普通模式合并,也就是会留有合并历史,而快速合并的看不出来。
使用git stash
可以隐藏当前工作状态,然后再使用git stash apply
来恢复,接着使用git stash drop
删除刚刚的状态。也可以使用git stash prop
来切换并删除。
使用git stash list
查看已保存的状态,并通过git stash apply stash@{0}
的方式恢复到指定状态。
使用git cherry-pick 版本号
可以重放bug修复过程。
如果一个分支没有没合并过,无法直接删除,此时需要使用-D
参数来强制删除:git branch -D 分支名称
(不过分支还是保留的好,万一策划脑子一热又重启呢?)
推送
git remote
可以查看远程分支名字,添加-v
参数可以查看更详细的信息,如果没有推送权限看不到push分支。
使用push命令进行远程推送:git push 远程名 本地分支名
,一般情况下是:git push origin master
,也可以直接git push
使用clone来抓取分支:git clone git@github.com:michaelliao/learngit.git
,默认情况只能抓取master分支,可以使用git checkout -b dev origin/dev
来抓取dev分支。
多人合作步骤:
- 使用
git push origin 分支名
来试图推送 - 如果推送失败,说明远程分支更新,需要
git pull
拉取来合并 - 如果没有冲突则可以直接推送,有冲突则需要解决冲突
如果拉取时提示:no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to 分支名 origin/远程分支名
分支提交路线优化:
rebase
操作可以把本地未push的分叉提交历史整理成直线,目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
标签
commit的版本号是一大串数字,不容易记,因此可以给某个状态打上标签:git tag v1.0
比如给当前的提交打上v1.0的标签,也可以直接添加commit的参数来给指定的提交打上标签:git tag v1.0 f52c633
,然后使用git tag
可以查看标签,需要注意的是标签不是按照时间顺序排列,而是按照字母顺序。可以使用git show 标签名
来查看详细信息。
如果标签打错了可以添加-d
来删除,创建的便签都存在本地,不会推送到远程。可以使用git push origin 标签名
来推送单个标签,或者git push origin --tags
推送所有标签。
从远程删除标签有点麻烦,需要先从本地删除,然后使用以下格式:git push origin :refs/tags/标签名
多远程仓库
使用git remote -v
查看已关联远程仓库,用git remote rm 远程仓库名
来取消关联,然后添加的时候取不同的名字:git remote add 名字 远程地址
,接着就可以推送了。如果不能推送则需要先pull下来再推送,如果pull的时候提示refusing to merge unrelated histories
,那么可以在pull的后面添加参数--allow-unrelated-histories
。接着就可以一个本地仓库关联多个远程了。
自定义Git
可以使用git config --global color.ui true
来让git命令带颜色,这样更加醒目(其实安装的时候是可以选择这一项的)
忽略文件
在工作目录下创建.gitignore
名字的文件,里面添加需要忽略的文件的名字,可以在这里根据不同语言来添加不同忽略文件:GitHub上总结的忽略文件
一般需要忽略的有:
- 系统自动生成的文件,比如缩略图等
- 编译产生的中间文件、可执行文件等,比如
.class
这种 - 敏感信息文件,比如存放口令的配置文件
如果一个文件被忽略,它就无法被add进暂存区。可以添加-f
参数强制添加。
如果你感觉一个文件不应该被忽略,可以使用git check-ignore -v 文件名
来查看到底是哪个忽略策略在生效。
同时.gitignore
文件也可以推送至远程。
配置命令别名
有些命令太长,不好记,此时就可以使用命令别名。比如把status
命令简写成st
:git config --global alias.st status
,然后就可以使用git st
命令来代替git status
。许多人会用co
表示checkout
,ci
表示commit
,br
表示branch
。
命令中--global
表示全局,也就是此电脑的所有仓库都可以使用,不加的话只对当前仓库生效。当前仓库的别名配置在.git/config
的[alias]里,全局的别名配置在用户目录下的.gitconfig
里,配错了只需要修改配置文件即可。
如果想要代替的命令有空格可以使用双引号引住,比如把git reset HEAD 文件名
撤销暂存区,可以这么简写:git config --global alias.unstage "reset HEAD"
,然后撤销暂存区就可以使用:git unstage 文件名
了。
还有个丧病的配置:git config --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 lg
来很方便的查看分支记录了🤣
附:ssh-keygen 参数详情:
- -b:指定密钥长度(选择为2048更难破解,1024可以被破解)
- -e:读取openssh的私钥或者公钥文件;
- -C:添加注释;(一般把邮箱作为注释)
- -f:指定用来保存密钥的文件名(可以用来创建多个密钥)
- -i:读取未加密的ssh-v2兼容的私钥/公钥文件,然后在标准输出设备上显示openssh兼容的私钥/公钥;
- -l:显示公钥文件的指纹数据;
- -N:提供一个新密语;
- -P:提供(旧)密语;
- -q:静默模式;
- -t:指定要创建的密钥类型。(一般选rsa)
创建一般一路回车默认即可,最后会有一个方块图案,叫做指纹,用来肉眼识别。
参考好吧我承认是摘抄廖雪峰的Git教程
顺便贴个阮一峰的常用 Git 命令清单