完整地过了一遍廖雪峰的教程。我学Git的初衷是想熟练用上GitHub, 现在发现Git才是那个深奥的核心😂
简介
- Git是用C语言开发的
- 集中式&分布式版本控制系统
- 集中式:版本库集中存放在中央服务器;最大的毛病就是必须联网才能工作
- 分布式:没有“中央服务器”,每个人的电脑上都是一个完整的版本库,不需要联网;安全性要高很多;通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改;极其强大的分支管理
创建版本库
- 版本库:又名仓库,英文名repository,可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”
- 创建版本库
- step1:创建一个空目录
- step2:初始化,
git init
- 把一个文件放到Git仓库
git add
git commit
时光机穿梭
git status
查看工作区状态git diff
查看修改内容
版本回退
git reset --hard commit_id
版本回退git reset --hard HEAD^
- 在Git中,用
HEAD
表示当前版本,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,往上100个写成HEAD~100
- 在Git中,用
git reset --hard 1094a
- 版本号(commit id)没必要写全,前几位就可以了,Git会自动去找
git log
查看提交历史- 显示从最近到最远的提交日志(如果嫌输出信息太多,加上
--pretty=oneline
参数)
- 显示从最近到最远的提交日志(如果嫌输出信息太多,加上
git reflog
查看命令历史- 可以找到版本号
工作区和暂存区
- 工作区(Working Directory):在电脑里能看到的目录
- 版本库(Repository):工作区有一个隐藏目录
.git
,这个不算工作区,而是Git的版本库 - 版本库里重要的东西有:
- 暂存区:stage(或者叫index)
- 分支:Git为我们自动创建的第一个分支
master
- 指针:指向
master
的一个指针叫HEAD
- 需要提交的文件修改通通放到暂存区,然后一次性提交暂存区的所有修改
管理修改
- Git跟踪并管理的是修改,而非文件
- 每次修改,如果不用
git add
到暂存区,那就不会加入到commit
中 - add只添加进了暂存区,commit才是进版本库,暂存区的相同文件都是覆盖的
撤销修改
git restore -- file
丢弃修改,让这个文件回到最近一次git commit
或git add
时的状态--
很重要,没有--
,就变成了“切换到另一个分支”的命令
git restore --staged
把暂存区的修改撤销掉(unstage),重新放回工作区- 注:
- 原来的git checkout 可以使用 git restore 代替
- 原来的git reset HEAD 可以使用 git restore –staged 代替
- 最新版的git提示都已经更换成了restore
- 总结:
- 情况1:在工作区做了修改,并未添加到暂存区,想撤销工作区的修改,用 git restore file
- 情况2:在工作区做了修改,并用git add 添加到了暂存区,未提交;想撤销,分两步,1.先撤销暂存区的修改,用 git restore –staged file, 2.然后参考情况1撤销工作区的修改
- 情况3:在工作区做了修改,且git add git commit添加并提交了内容,想撤销本次提交,直接用 git reset –hard HEAD^回退版本,即可保证工作区,暂存区,版本库都是上次的内容
删除文件
git rm
- 如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容
- 当你直接在文件管理器中把没用的文件删了,或者用
rm
命令删了,接下来有两种选择:- 确实要从版本库中删除该文件,那就用命令
git rm
删掉,并且git commit
- 删错了,用
git checkout
把误删的文件从版本库里恢复到最新版本
- 确实要从版本库中删除该文件,那就用命令
远程仓库
- 本地Git仓库和GitHub仓库之间的传输通过SSH加密
添加远程库
git remote add origin git@server-name:path/repo-name.git
- 关联一个远程库时必须给远程库指定一个名字,
origin
是默认习惯命名
- 关联一个远程库时必须给远程库指定一个名字,
- 关联后,使用命令
git push -u origin master
第一次推送master分支的所有内容 - 此后,每次本地提交后,只要有必要,就可以使用命令
git push origin master
推送最新修改
删除远程库
git remote rm <name>
- 使用前,建议先用
git remote -v
查看远程库信息 - 只是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到GitHub,在后台页面找到删除按钮再删除
- 使用前,建议先用
从远程库克隆
- ssh:
git clone git@github.com:your name/repo name.git
- 更快
- https:
git clone http://github.com/yourname/reponame.git
分支管理
创建与合并分支
git checkout -b
或git switch -c
创建并切换- 相当于
git branch
(创建) +git checkout
或git switch
(切换)
- 相当于
git branch
查看当前分支- 会列出所有分支,当前分支前面会标一个
*
- 会列出所有分支,当前分支前面会标一个
git merge
合并指定分支到当前分支git branch -d
删除分支- 创建、合并和删除分支非常快,所以最好使用分支完成某个任务,合并后再删掉分支,这和直接在
master
分支上工作效果是一样的,但过程更安全
解决冲突
- 把Git合并失败的文件手动编辑为我们希望的内容,再提交
分支管理策略
- 分支策略
master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活dev
分支是不稳定的,干活都在dev
分支上;到某个时候,比如1.0版本发布时,再把dev
分支合并到master
上,在master
分支发布1.0版本- 团队成员都在
dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了
- 合并分支时的普通模式:加上
--no-ff
参数- 这样合并后的历史有分支,能看出来曾经做过合并,而
fast forward
合并就看不出来曾经做过合并
- 这样合并后的历史有分支,能看出来曾经做过合并,而
Bug分支
- 修复bug时,通过创建新的bug分支进行修复,然后合并,最后删除
git stash
保存工作现场,然后去修复bug,修复后,有两种方式回到工作现场:git stash apply
,stash内容并不删除,需要用git stash drop
来删除git stash pop
,恢复的同时把stash内容也删了
git stash list
查看stash里的内容,然后用git stash apply stash@{0}
恢复到指定的stash(这里是stash@{0})- 在master分支上修复的bug,想要合并到当前dev分支,可以用
git cherry-pick <commit>
,把bug提交的修改“复制”到当前分支,避免重复劳动
Feature分支
- 开发一个新feature,最好新建一个分支
- 如果要丢弃一个没有被合并过的分支,可以通过
git branch -D <name>
强行删除
多人协作
git push origin <branch-name>
推送自己的修改- 如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并- 如果
git pull
提示no tracking information
,则需要用git branch --set-upstream-to <branch-name> origin/<branch-name>
建立起本地分支和远程分支的链接关系
- 如果
- 如果合并有冲突,则解决冲突,并在本地提交
- 没有冲突或者解决掉冲突后,再用
git push origin <branch-name>
推送
Rebase
- 把本地未push的分叉提交历史整理成直线
- 目的:使我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比
标签管理
- tag是一个让人容易记住的有意义的名字,它跟某个commit绑在一起
- 如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签
创建标签
git tag <tagname>
新建一个标签- 默认为
HEAD
,也可以指定一个commit id - 创建的标签都只存储在本地,不会自动推送到远程
- 默认为
git tag -a <tagname> -m "blablabla..."
创建带有说明的标签git tag
查看所有标签- 不是按时间顺序列出,而是按字母排序
git show <tagname>
查看标签信息
操作标签
- 推送
git push origin <tagname>
推送某个本地标签到远程git push origin --tags
一次性推送全部未推送过的本地标签到远程
- 删除
git tag -d <tagname>
删除某个本地标签- 删除一个远程标签:先从本地删除(用上面的命令),然后从远程删除,命令是
git push origin :refs/tags/<tagname>
使用GitHub
- 可以任意Fork开源仓库
- Fork后的仓库,你拥有读写权限
- 推送pull request给官方仓库来贡献代码
使用Gitee
- 国内的Git托管服务
- 使用方法和GitHub类似
自定义Git
git config --global color.ui **true**
让Git显示颜色,看起来更醒目
忽略特殊文件
- Github官方.gitignore文件合集
- 忽略文件的原则:
- 忽略操作系统自动生成的文件
- 忽略编译生成的中间文件、可执行文件等
- 忽略带有个人敏感信息的配置文件
git add -f filename
虽然被忽略但强制添加!filename
例外文件- .gitignore online generator
配置别名
git config --global **alias**.st status
设定用st
表示status
--global
是全局参数,针对当前用户,即让命令在这台电脑的所有Git仓库下都有用;如果不加,那就只针对当前仓库有用- 每个仓库的Git配置文件都放在
.git/config
文件中 - 当前用户的Git配置文件放在用户主目录下的一个隐藏文件
.gitconfig
中 - 要删除别名,直接把
[alias]
后面的对应别名的行删掉即可
搭建Git服务器
- 需要一台运行Linux的机器(推荐Ubuntu或Debian)。暂时用不到就没看,详见这里
使用Sourcetree
- 免费Git图形界面工具
附录
教程
链接
评论