赞
踩
作为一个以学习贯穿一生的程序员,每学习一门技术或者知识,应该静下心,学习好每个知识点,而不是只学习个皮毛而洋洋自得,所以今天从新学习下Git,以便工作中使用,面试前复习。
Git是一个免费的、开源的分布式版本控制系统,可以快速高效地进行代码管理。具有廉价本地库(硬盘存储),方便的暂存区和多个工作流分支等特性。Git官网
版本控制是能够记录文件各个版本以及查看每个版本修改历史的系统。最重要的就是记录文件的修改记录,可以查看历史版本的同时还能切换至各个版本。
团队开发中,多人同时修改,无法保证代码正确同步和修改。
集中式:SVN(典型)
原理:所有人代码保存在一个地方,所有人修改的都是这个地方的代码
好处:管理员和开发者都可以显著看到所有代码的修改
坏处:单点故障导致其他所有人都无法正常工作
分布式:Git
原理:每个人本地都是一个代码库,都可以做版本迭代。同时还有一个远程库。每个人都可以从这个远程库下载或者上传代码。
好处:断网时还可以做版本记录,每个人也都有完整的代码
坏处:比SVN这种集中式系统更复杂,上手难度偏高。
工作区:本地文件,类似你的windows系统上的文件夹
暂存区:记录你本地的代码修改
本地库:本地定版的各个版本存档的版本库
本地库的代码可以提交到远程库(远程代码仓库)后,有远程库访问权限的人,都可以看到这个远程库代码里的修改历史和版本了。而代码托管中心则是基于网络服务器的远程库,你可以通过局域网或互联网访问到这个远程库。
基于局域网的代码托管中心:
GitLab
基于互联网的代码托管中心:
GitHub、Gitee
系统配置
默认编辑器配置
创建分支时的命名,master或者自定义
是否修改环境变量 第一个不修改,第二个选中后可以在命令行或者其他第三方工具中使用git bash,选一个就行
选择客户端安全协议,第一个
配置换行符,第一个(帮你选择,windows默认CRLF,Linux默认LF)
git bash里使用什么类型终端,第一个
代码冲突的默认合并方式,第一个
选择凭据管理器,第一个
其他配置,都选中
实验室功能,不选
安装好验证
提交代码前需要登记用户名和邮箱(与GitHub等代码托管中心的账号没有关系),首次安装必须设置
设置用户名
git config --global user.name 用户名
设置邮箱
git config --global user.email 邮箱
查看用户名和邮箱
cat git根目录/.gitconfig
在你想进行版本控制的文件夹下执行:
git init
执行后在该文件夹下生成 .git 文件夹,默认隐藏
查看 git 状态
git status
将文件或文件夹存放到暂存区
git add file
删除暂存区中的文件或文件夹
git rm --cached file
提交到本地库
git commit -m "日志信息" file (file可累加,空格间隔)
查看引用日志
git reflog
查看详细日志
git log
指针指向历史版本号,可以穿梭回过去,还可以穿梭回来
git reset --hard 版本号
在版本控制过程中,同时推进多个任务,为每个任务创建单独的分支。使用分支可以将自己的工作独立于主分支,在这个分支上操作不会影响主分支。在工作完成后,还可以将分支上的修改合并到主分支上。
分支的好处:可以同时开展多项任务,互不影响,提高效率
查看当前分支
git branch -v
在当前分支上创建分支(不修改当前所在的分支)
git branch 分支名
切换到目标分支
git checkout 目标分支名
把指定的分支合并到当前分支上(先切换到当前分支上)
git merge 分支名
如果合并过程发生冲突,需要手动合并(删除<<< === >>>部分,保留最终想要的代码样子),重新 add 到暂存区,再 commit 到本地库(此时不需要添加 file )
查看当前所有远程分支别名
git remote -v
创建远程库的别名
git remote add 别名 https://github.com/*****
推送代码
git push 别名 本地分支名
git push https://github.com/***** 本地分支名
拉取代码
git pull 别名 本地分支名
克隆代码
git clone https://github.com/*****
有些文件与项目实际无关,不参与服务器上部署运行,忽略它们能屏蔽IDE工具之间的差异。
# 忽略所有 jar 文件
*.jar
#......
[core]
excludesfile = C:C:/Users/git.ignore
以上是 Git 基础的常用命令,如果是在一两个分支或者只有少量开发人员的情况,使用和SVN几乎没有区别,但是在多个部门合作、较多人员同时开发且版本迭代较快的情况下,会同时有很多分支,这时合并分支时会有一些问题,这也是我写这个帖子的主要原因,用来梳理一些思路,以免工作中思路不清晰导致一些难以挽回的结果。
命令:
# 从远程仓库拉取feature-branch分支的内容,并在本地创建一个新的分支my-feature
git fetch origin feature-branch:my-feature
# 从远程仓库拉取feature-branch分支的内容,并在本地创建一个新的分支my-feature并切换
git fetch origin feature-branch:my-feature && git checkout my-feature
可以看出,从远程拉取分支需要指定远程分支和本地分支,从此看出,通常本地分支和远程分支有一对一的关系,一个本地分支对应一个远程跟踪分支。本地分支可以与远程分支关联,成为远程分支的本地表现,这使得你可以在本地进行修改,然后通过push将这些修改上传到远程仓库。当然,一个本地仓库也可能添加多个远程仓库,但一般不会这样操作。
Git中的合并(merge)操作是将两个不同分支的修改集成到一起。合并原理设计三方面内容:基地(base)、源分支(source branch)、目标分支(targe branch)。
合并操作的基础是有源分支和目标分支有一个共同的祖先,这个祖先即为基底。基底是两个要合并的分支的最近的共同祖先。
Git通过找到这个共同的祖先来确定两个分支的修改点。这样合并操作就知道了基底之后分别有哪些修改。
Git 使用第三方合并算法来执行合并操作。这个算法会比较基底、源分支和目标分支的差异,然后尝试自动合并这些差异。
如果在基底之后,源分支和目标分支都没有修改同一行代码,Git 会自动完成合并,产生一个新的提交,表示两个修改分支已经成功合并
如果在同一行代码发生不同修改,Git 会标记这个地方发生了冲突,需要人工合并。
合并冲突表示在同一位置有两个不同的修改,Git 无法自动决定应该选择哪一个。
在合并冲突状态下,你需要手动解决冲突。你可以编辑文件,选择要保留的修改,然后提交解决冲突的结果。
① 最直接方式就是尝试执行合并操作
git merge 源分支 目标分支
② git log 命令查看源分支和目标分支的提交历史,确保它们有一个共同的祖先
git log --oneline --graph --all
merge 合并:
rebase 变基:
总的来说: merge通常用于整合共享的分支(如主分支),而rebase则用户整理个人分支的提交历史。
在Git中,当有未提交的更改,而这些更改与你要切换到的分支上某些更改存在冲突,Git不会自动合并这些修改。在这种情况,你可以选择的解决办法。
暂存其实还是丢弃更改,只不过将更改从工作区丢弃,暂时放在别的地方而已
4. 强行切换分支(会导致未提交部分更改丢失)
git checkout -f targe_branch
5. 让git 尝试自动合并未提交的修改(可能导致冲突)
git checkout --merge target_branch
理解解决办法前,必须要理解工作区、暂存区、分支的本质。当前分支未提交的代码是在工作区(比如在文件末尾加了1),如果切换分支,git 会将你在工作区的代码和目标分支对比(比如目标分支文件末尾加了2),这时工作区和分支上都修改了同一个地方,git不确定使用哪个。理解这个后,就能理解为什么要使用上面的解决方法。
# --oneline 选项将每个提交显示为一行。
# --graph 选项以图形形式显示分支和合并历史。
# --all 选项显示所有分支的历史。
git log --oneline --graph --all
# 显示分支之间的关系
git show-branch
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。