廖雪峰老师Git教程学习笔记
什么是Git
分布式版本控制系统。
分布式版本控制系统没有“中央服务器”,每个人的电脑上都是一个完整的版本库。和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多。
分布式版本控制系统通常也有一台充当“中央服务器”的电脑,这个服务器的作用是用来方便“交换”大家的修改。
安装
官网下载安装
// 每台机器需要标识自己
// --global 表示这台机器上所有仓库都使用这个配置
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
创建版本库
mkdir testcd testgit init初始化,将test目录变成git可以管理的仓库ls -ah查看.git隐藏目录,该目录是用来跟踪管理版本库的-a显示所有文件及目录 (. 开头的隐藏文件也会列出)-h–human-readable ???
touch main.js新建main.js
工作区、暂存区、版本库
时光机穿梭
提交文件
git add main.js提交到暂存区git commit -m 'add main.js'从暂存区提交到版本库
修改文件
- 修改main.js
git status查看文件状态 Changes not staged for commitgit diff查看修改内容git addgit statusChanges to be committedgit commit -m 'modify main.js'git statusnothing to commit, working tree clean
删除文件
git rm <file>git commit -m 'delete <file>'
查看记录
git log查看提交记录git log --pretty=oneline查看提交记录git log --graph --pretty=oneline --abbrev-commitq退出git loggit reflog查看所有操作记录,包括回退版本等
版本
- HEAD 当前版本
- HEAD^ 上一个版本
- HEAD^^ 上上一个版本
- HEAD~100 往上100个版本
- 版本号(commit id) 例:
4e66e5f1b054df5db72aa64dc56b01b1bc1a6b75用SHA1计算出来的数字,十六进制表示
版本回退
git reset --hard HEAD^回退到上个版本--hardResets the index and working tree. Any changes to tracked files in the working tree since<commit>are discarded. Any untracked files or directories in the way of writing any tracked files are simply deleted.--softDoes not touch the index file or the working tree at all (but resets the head to<commit>, just like all modes do). This leaves all your changed files "Changes to be committed", asgit statuswould put it.--mixedResets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action. If-Nis specified, removed paths are marked as intent-to-add (see git-add[1]).
git reset --hard 版本号回退到指定版本
版本回退后并推送
- 本地修改提交后,如果push到了远程分支。此时先在本地执行
git reset ...操作后,直接push到远程可能会报错,需要强制push,git push 仓库名 分支名 --force
管理修改
git 管理的是修改而不是文件
git checkout -- <file>撤销工作区的修改git reset HEAD <file>撤销暂存区的修改
远程仓库
生成秘钥对
- 将GitHub作为远程仓库
- 本地仓库与远程仓库之间通过SSH加密传输,因此需要进行设置
ssh-keygen -t rsa -C "youremail@example.com"生成秘钥对- PuTTYgen加载私钥id_rsa,导出ppk私钥文件,后续拉取代码时加载该私钥文件
- id_rsa.pub公钥上传到GitHub
本地关联远程仓库
git remote add 远程库名称 远程库地址关联仓库git push -u 远程库名称 远程库分支将本地内容推送到远程并关联分支git push 远程库名称 远程库分支推送内容git remote rm 远程库名称解除关联已有的远程库
克隆远程库
- 先创建远程库,再克隆到本地
git clone 远程库地址
创建远程分支到本地
git checkout -b dev origin/dev创建本地dev分支,关联的是远程origin库的dev分支
远程库地址
- 默认使用ssh
git://xxx/xxx - 也可以使用https
https://github.com/michaelliao/gitskills.git git remote查看远程库地址git remote -v查看远程库详细信息
fork
- 通过fork操作可以复制一份其他官方仓库代码到自己的仓库
- fork后自己的仓库有读写权限
- 可以pull request推送给官方仓库
分支管理
创建并切换分支
git checkout -b dev相当于两条命令git branch dev创建dev分支git checkout dev切换到dev分支
git branch查看当前有哪些分支
switch 命令切换分支
git switch -c dev创建并切换到新的dev分支git switch master切换到已有的master分支
合并分支
git merge 分支名合并指定分支到当前分支- 在master分支上
git merge dev,即把dev分支上的内容合并到master分支
删除分支
git branch -d <branchname>删除本地分支(合并过的分支)git branch -D <branchname>强行删除本地没有合并过的分支git push <remote> --delete <branchname>删除远程分支
给分支添加描述
git config branch.<branchname>.description '描述内容'添加描述git config branch.<branchname>.description查看描述
比较两个分支差异
git diff branch1 branch2 --stat列出所有有差异的文件列表;+表示branch2相对于branch1多出的内容,-表示branch2相对于branch1少了的内容git diff branch1 branch2 文件名(带路径)显示指定文件的详细差异git diff branch1 branch2显示所有有差异文件的详细差异
解决冲突
通过命令行解决冲突
git merge feature将feature分支合并到当前时冲突- 手动解决冲突,然后再执行
git add和git commit提交 git log --graph --pretty=oneline --abbrev-commit查看分支合并情况- 然后删除feature分支,默认使用的
Fast forward模式,会丢失掉feature分支的信息
合并时禁用Fast forward模式
- 使用
--no-ff参数 强制禁用Fast forward模式,会在merge时生成一个新的commit,可以在分支历史上看出历史信息 git merge --no-ff -m "merge with no-ff" dev
使用TortoiseGit工具解决冲突
- 使用
git pull <remote> <branchname>从远程仓库拉取时与其他人提交的代码发生冲突 - 使用TortoiseGit工具的EditConflicts工具可以直观看到冲突的位置
- 并且还会生成
filename.ext.BASE.ext,filename.ext.LOCAL.extandfilename.ext.REMOTE.ext3个文件 - MERGE_HEAD表示远程文件内容,HEAD表示当前我的分支的内容,Merged表示解决冲突后的内容。在冲突处右键可以选择使用远程的,我的,或者合并两者。
- 将文件标记为resolved然后提交,提交时会提示这是一次解决冲突的提交,里面可能会包含本地修改的一些其他代码
- 手动解决冲突后,执行的TortoiseGit的resolve命令,实际是
git add操作- 官方文档:Please note that the Resolve command does not really resolve the conflict. It uses "git add" to mark file status as resolved to allow you to commit your changes and it removes the
filename.ext.BASE.ext,filename.ext.LOCAL.extandfilename.ext.REMOTE.extfiles.
- 官方文档:Please note that the Resolve command does not really resolve the conflict. It uses "git add" to mark file status as resolved to allow you to commit your changes and it removes the
- 最后再commit进行提交
stash 临时存储
- 保存
git stash会自动使用一串字符作为标识git stash save “修改的信息”保存并记录修改内容(推荐)
- 展示所有保存的版本
git stash list
- 查看保存版本的内容
git stash show -p stash@{0}查看序号为0的stash的内容
- 恢复版本
git stash pop取最后一个版本,并删除该版本git stash apply stash@{0}恢复需要的某个版本 版本号通过展示版本命令获取
- 删除版本
git stash drop stash@{0}删除某个版本git stash clear清除所有版本
cherry-pick 复制特定提交到当前分支
- 在dev分支做了一次修改提交,记录下版本号
- 在master分支上同样需要修改,执行
git cherry-pick 版本号,将该次修改合并到master分支
推送分支
git push 远程库名称 远程分支名称将本地当前分支推送到远程库特定分支
分支是否要推送
- 主分支与开发分支需要与远程同步;
- bug分支只用于在本地修复bug,就没必要推到远程了
- feature分支是否推到远程,取决于是否需要合作开发。
抓取分支
git pull从远程抓取分支,有冲突要先解决冲突- 如果拉取时没有指定从哪个分支拉取,希望默认关联分支拉取
- 执行
git branch --set-upstream-to=<remote>/<branch> <branch>建立远程分支和本地分支的关联
- 执行
rebase
git rebase将本地未push的分叉提交历史整理成直线,看上去更直观。缺点是本地的分叉提交已经被修改过了。- 总的原则是,只对尚未推送或分享给别人的本地修改执行变基操作清理历史,从不对已推送至别处的提交执行变基操作。
rebase参考资料
标签管理
新建标签
git tag <tagname>当前状态打标签git tag <tagname> <commit id>某个版本打标签git tag -a <tagname> <commit id> -m "标签信息"指定标签信息git tag查看所有标签git show <tagname>查看指定标签的详细信息
操作标签
git tag -d <tagname>删除本地标签git push <remote> <tagname>推送标签git push <remote> --tags一次性推送所有未推送的标签- 如果标签已经推送,需要删除的话,首先需要从本地删除,然后从远程删除
git push <remote> :refs/tags/<tagname>
自定义Git
让Git显示颜色
git config --global color.ui true
忽略特殊文件
- 在
.gitignore文件中,将要忽略的文件名填进去,并将该文件提交到仓库中
忽略文件原则
- 忽略操作系统自动生成的文件,比如缩略图等
- 忽略编译生成的中间文件、可执行文件等
- 忽略带有敏感信息的配置文件
强制添加文件
git add -f <file>强制添加被忽略的文件git check-ignore -v <file>检查忽略规则,哪条规则导致该文件被忽略(在强制添加之前检查)
不忽略某些文件(增加特例)
!<file>不忽略指定文件
# 忽略所有.开头的隐藏文件:
.*
# 忽略所有.class文件:
*.class
# 不忽略.gitignore和App.class:
!.gitignore
!App.class
配置别名
git config --global alias.st status将st配置为status的别名git config --global alias.unstage 'reset HEAD'将unstage配置为'reset HEAD'的别名git config --global alias.last 'log -1'显示最后一次提交信息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"- 不加--global的配置只对当前仓库生效
- 每个仓库的配置文件都放在.git/config文件中
- 当前用户的配置文件放在用户主目录下的一个隐藏文件.gitconfig中
- 可以通过修改配置文件内容直接修改别名配置
git pull 和 git fetch的区别
- pull 根据不同的配置,可等于 fetch + merge 或 fetch + rebase