您好,欢迎来到榕意旅游网。
搜索
您的当前位置:首页Git简单教程

Git简单教程

来源:榕意旅游网


Git简介

集中式和分布式
  • Git是目前世界上最先进的分布式版本控制系统(没有之一)。
  • Git是用C语言开发的。
  • CVS及SVN都是集中式的版本控制系统,版本库是集中存放在服务器的,必须联网才能工作。分布式版本控制系统没有“服务器”,每个人的电脑上都是一个完整的版本库,通常也有一台充当“服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改。
  • 所有的版本控制系统,其实只能跟踪文本文件的改动,图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化。

『千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题。』

创建版本库
  • 初始化一个Git仓库,使用git init命令。
  • 使用命令git add <file>,注意,可反复多次使用,添加多个文件;
  • 使用命令git commit -m <message>,完成。

时光机穿梭

  • 要随时掌握工作区的状态,使用git status命令。
  • 如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
版本回退
  • HEAD指向的版本就是当前版本,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。(上一个版本就是HEAD^,上上一个版本就是HEAD^^,commit id是一个SHA1计算出来的一个非常大的数字,用十六进制表示。)
  • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
  • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
  • cat readme.txt 查看文本内容。
工作区和暂存区

Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。

管理修改

为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件。

  • git diff filename:比较工作区和暂存区。
  • git diff HEAD -- filename:比较工作区和版本库的最新版本。
撤销修改
  • 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
  • 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>,就回到了场景1,第二步按场景1操作。
  • 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
删除文件

确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit;删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本git checkout -- test.txt
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。)

远程仓库

本地Git仓库和GitHub仓库之间的传输是通过SSH加密的。

『Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。』

添加远程库
  • 关联一个远程库:git remote add origin git@server-name:path/repo-name.git
  • 关联后,使用命令git push -u origin master第一次推送master分支的所有内容;
  • 此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改。
从远程库克隆
  • git clone git@server-name:path/repo-name.git
  • Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。

分支管理

创建与合并分支

HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上。

  • 查看分支:git branch
  • 创建分支:git branch <name>;
  • 切换分支:git checkout <name>; 或者git switch ;(新版本)
  • 创建+切换分支:git checkout -b <name>; 或者git switch -c ;
  • 合并某分支到当前分支:git merge <name>;
  • 删除分支:git branch -d <name>;

(Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快)

补充:
对于所有分支而言, 工作区和暂存区是公共的。git 切换分支时会把未add或未commit的内容带过去。

解决冲突
  • 当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
  • 解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
  • 用git log --graph命令可以看到分支合并图。git log --graph --pretty=oneline --abbrev-commit
分支管理策略
  • 合并分支时,如果可能,Git会用Fast forward模式,但删除分支后,会丢掉分支信息。如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。(创建一个新的commit时,要加上-m参数,把commit描述写进去)
  • 合并分支时,加上–no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并。git merge --no-ff -m "msg" dev

『在实际开发中,我们应该按照几个基本原则进行分支管理:首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。』

Bug分支
  • 修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除。
  • 当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。(git stash list查看,用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;用git stash pop,恢复的同时把stash内容也删了;git stash apply stash@{0}
  • 在master分支上修复的bug,想要合并到当前dev分支,可以用git cherry-pick <commit ID>命令,把bug提交的修改“复制”到当前分支,避免重复劳动。
Feature分支

开发一个新功能feature,最好新建一个分支;
如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。

多人协作

多人协作的工作模式通常是这样:

  • 首先,可以试图用git push origin <branch-name>推送自己的修改;
  • 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
  • 如果合并有冲突,则解决冲突,并在本地提交;
  • 没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!
  • 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to=origin/<branch-name> <branch-name>

查看远程库信息,使用git remote -v
在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致。

Rebase(变基)
  • rebase操作可以把本地未push的分叉提交历史整理成直线,看上去更直观。缺点是本地的分叉提交已经被修改过了。git rebase
  • rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

(只对尚未推送或分享给别人的本地修改执行变基操作清理历史;从不对已推送至别处的提交执行变基操作)

标签管理

发布一个版本时,我们通常先在版本库中打一个标签(tag)。取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。
Git的标签是版本库的快照,它就是指向某个commit ID的指针。(跟分支很像对不对?但是分支可以移动,标签不能移动)

创建标签
  • 命令git tag <tagname>用于新建一个标签,默认为HEAD,也可以指定一个commit id;
  • 命令git tag -a <tagname> -m "msg" commit id可以指定标签信息;
  • 命令git tag可以查看所有标签;git show <tagname>查看标签信息。

(标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。)

操作标签
  • 命令git push origin <tagname>可以推送一个本地标签;
  • 命令git push origin --tags可以推送全部未推送过的本地标签;
  • 命令git tag -d <tagname>可以删除一个本地标签;
  • 命令git push origin :refs/tags/<tagname>可以删除一个远程标签。

使用GitHub

  • 在GitHub上,可以任意Fork开源仓库;
  • 自己拥有Fork后的仓库的读写权限;
  • 可以推送pull request给官方仓库来贡献代码。

使用码云

git给远程库起的默认名称是origin,如果有多个远程库,我们需要用不同的名称来标识不同的远程库。
先删除已关联的名为origin的远程库:git remote rm origin
git remote add github git@github.com:path/repo-name.git
git remote add gitee git@gitee.com:path/repo-name.git

自定义Git

忽略特殊文件

忽略某些文件时,需要编写.gitignore
.gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理!

配置别名

git config --global alias.<new> old
–global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。
比如:

  • st就表示status:git config --global alias.st status
  • co表示checkout,ci表示commit,br表示branch;alias.unstage ‘reset HEAD’;
  • 显示最后一次提交信息:alias.last ‘log -1’
  • alias.lg ‘git log --graph --pretty=oneline --abbrev-commit’

笔记整理自廖雪峰老师的Git教程。
同时发现一个Git的图文互动的学习网站,特别形象生动,在github上也有相应的开源项目:

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- nryq.cn 版权所有 赣ICP备2024042798号-6

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务