Git 官网:
https://git-scm.com
GitHub:
https://github.com
GitLab:
https://about.gitlab.com
https://git-scm.com/book/zh/v2
# 本节知识点
## 添加配置
git config [--local | --global | --system] user.name 'Your name'
git config [--local | --global | --system] user.email 'Your email'
## 查看配置
git config --list [--local | --global | --system]
## 区别
local:区域为本仓库
global: 当前用户的所有仓库
system: 本系统的所有用户
1)第一种理解
本地有个项目代码写了一段时间了,但还没有用 git 管理起来,现在想用git在本地帮着记录变更的版本。
2)第二种理解
很早之前本地生成了一个 git 的仓库,开发了一段时间,想把这个git仓库提交到公司git服务器新建的project中。
对于第一种理解:
cd existing_folder (本地进入到项目文件夹内)
git init (执行 init 命令,会创建出 .git 目录)
git add . (把项目文件加入到 git 的暂存区)
git commit -m “Initial commit” (创建第一个 git 的commit )
对于第二种理解:
cd existing_repo
git remote add origin git@your_git_server:your_group/your_project.git
git push -u origin --all
git push -u origin --tags
git add .与git add -A的区别
一.版本导致的差别:
1.x版本:
(1).git add all可以提交未跟踪、修改和删除文件。
(2).git add .可以提交未跟踪和修改文件,但是不处理删除文件。
2.x版本:
两者功能在提交类型方面是相同的。
二.所在目录不同导致的差异:
(1).git add all 提交的是整个仓库
(2).git add .只能够提交当前目录或者它子目录下相应文件。
git mv filesA FilesB
本节的一些演示命令总结
• git log --all 查看所有分支的历史
• git log --all --graph 查看图形化的 log 地址
• git log --oneline 查看单行的简洁历史。
• git log --oneline -n4 查看最近的四条简洁历史。
• git log --oneline --all -n4 --graph 查看所有分支最近 4 条单行的图形化历史。
• git help --web log 跳转到git log 的帮助文档网页
gitk
cat HEAD 查看HEAD文件的内容
git cat-file 命令 显示版本库对象的内容、类型及大小信息。
git cat-file -t b44dd71d62a5a8ed3 显示版本库对象的类型
git cat-file -s b44dd71d62a5a8ed3 显示版本库对象的大小
git cat-file -p b44dd71d62a5a8ed3 显示版本库对象的内容
HEAD:指向当前的工作路径
config:存放本地仓库(local)相关的配置信息。
refs/heads:存放分支
refs/tags:存放tag,又叫里程牌 (当这次commit是具有里程碑意义的 比如项目1.0的时候 就可以打tag)
objects:存放对象 .git/objects/ 文件夹中的子文件夹都是以哈希值的前两位字符命名 每个object由40位字符组成,前两位字符用来当文件夹,后38位做文件。
git有3种对象:commit、tree、blob。每次的提交,都是一个commit,一个commit又是包含了一棵tree,每个tree里面又是包含了多棵tree和blob,而文件的的最终形式是blob。对于blob,git会认为文件内容相同,就使用同一个blob,这样就极大的避免了频繁的提交时,git的存储空间的急剧上升。
每一次commit都对应一个tree,那这个tree是包裹在最外层的一个tree,使用git cat-file -p 命令的时候查看tree内部的内容,这里的每一个文件夹都可以看成一个tree,而在这些文件夹中的具体文件内容两两不相等文件都是一个blob,内容相同的文件统一为一个blob。
略
那分离头指针在企业或日常使用中, 到底有哪些具体的适用地点呢?
如果临时想基于某个commit做变更,试试新方案是否可行,就可以采用分离头指针的方式。测试后发现新方案不成熟,直接reset回其他分支即可。省却了建、删分支的麻烦了。
git checkout commitId:会出现分离头指针的情况,这种情况下比较危险,因为这个时候你提交的代码没有和分支对应起来,当切换到其他分支的时候(比如master分支),容易丢失代码;但是分离头指针也有它的应用场景,就是在自己做尝试或者测试的时候可以分离头指针,当尝试完毕没有用的时候可以随时丢弃,但是如果觉得尝试有用,那么可以新建一个分支,使用 git branch <新分支的名称> commitId
"^"这个操作符代表父commit。
当一个commit有多个父commit时,可以通过在符号“^”后面跟上一个数字来表示第几个父commit。
比如,“A^” 等于 “A^1”(表示A这个commit的第1个父commit)。
连续的“^”符号依次沿着父commit进行定位,直到某个祖先commit。
~ 相当于连续n个符合“^”。
所以,HEAD^^ 等同于 HEAD~2 是对的。
git branch -d branch_name:使用-d 在删除前Git会判断在该分支上开发的功能是否被merge的其它分支。如果没有,不能删除。如果merge到其它分支,但之后又在其上做了开发,使用-d还是不能删除。-D会强制删除。
git commit --amend 对最新一次提交做 commit 修改
修改历史的 Commit message,通常用在还没有提交到集成分支之前:
git rebase -i father_commit_id
交互界面里的命令选 reword
把连续的多个 Commit 合并为 1 个:
git rebase -i father_commit_id
交互界面里的命令选 squash,并输入新的 commit message
修改最新的:git commit --amend
修改老旧的:git rebase --xxxxxxx pick 改为r reword
合并连续的:git rebase --xxxxxxx(父commit id) 保留较老的pick,其他要合并的使用s squash
合并不连续的:git rebase --xxxxxxx(父commit id)保留较老的pick,其他要合并的移动到第二行,使用s。如果没有父commit id。用git rebase -i --root,或者手动加上。
vi index.html 修改index.html的内容
git add index.html 将修改的文件添加到暂存区
git status 显示在哪个暂存区 有没有文件改变将要提交
git diff --cached 查看文件改变情况 看变更的文件有没有问题
git commit -m’Add the frist command with config’ 做提交操作
假定:HEAD、缓存区、工作区中的readme.md文件内容均不相同。
git diff HEAD – readme.md # 工作区 <=== > HEAD
git diff – readme.md # 工作区 < => 缓存区
git diff --cached – readme.md # 缓存区 <=> HEAD
git reset 有三个参数
–soft 这个只是把 HEAD 指向的 commit 恢复到你指定的 commit,暂存区 工作区不变
–hard 这个是 把 HEAD, 暂存区, 工作区 都修改为 你指定的 commit 的时候的文件状态
–mixed 这个是不加时候的默认参数,把 HEAD,暂存区 修改为 你指定的 commit 的时候的文件状态,工作区保持不变
舍弃html文件的修改
git checkout – index.html(有个空格)
或新版本
git restore index.html
git reset HEAD ,是让暂存区恢复为HEAD所指向的节点,使用了该命令后,工作区修改的内容会被保留(保险),如果本地的修改需要丢弃掉,那么可使用–hard
修改了工作区,恢复:git checkout
add后,想撤销: git reset HEAD
commit后,想撤销: git reset–hard hash值
git diff commit-id1 commit-id2 path-to-filename
对不同的分支进行差异化的比较使用 git diff commit_id commit_id – index.html
本课使用【rm < filename>】先删除工作区的文件后,再使用命令【git add < filename>】提交到暂存区中,效果和使用【rm < filename>】再使用【git rm < filename>】一样。只是【git rm < filename>】可以省略本地工作区【rm < filename>】这个命令的操作步骤。
总结:直接在工作区和暂存区中删除某个将来不需要提交到commit的文件时,使用命令【git rm < filename>】即可。
git stash 将手头正在修改的东西先存起来放到一边去处理紧急任务
git stash apply
第一个作用将之前git stash存放的内容弹出来 把他的东西放到工作区去
第二个使用git stash list查看链表里的内容还在可以进行反复使用
git stash pop 和stash的区别 pop中list不保留 apply保留
.gitinore对其中的内容进行配置,可以设置git不用管理的文件或者文件夹
doc是不管理这个文件夹和文件
doc/不管文件夹管文件
1)找个目录执行 clone 。或
2)用init建个git仓库,然后从备份数据库添加remote,再push到新建仓库;
3)或者用init建个git仓库,然后在新仓库添加remote,再把备份数据库fetch/pull到新仓库。
# 本地模拟推送,git备份
## 远程库
git clone --bare file:///XXXX/.git remoteRepoName.git
bare不包含工作区,作为远端,以后备份方便一点
这样的话,已经备份了
## 本地仓库
跟远程库建立关联
git remote add remoteRepoName file:///XXXX/remoteRepoName.git
本地发送一些改动,比如新增分支develop
推送分支变动到远程
git push --set-upstream remoteRepoName develop
再到远程库下面查看就会发现远程也有develop分支了
略
首次生成密钥时还需要执行一下命令
ssh-add ~/.ssh/id_rsa
github网站更新后,配置SSH keys的入口在:右上角头像 --> Settings --> 左侧导航栏的SSH and GPG keys
略
本地分支往远端分支做push,如果远端分支不是本地分支的祖先,那它俩就不是 fast forward 了。反之,它俩就是fast forward的关系。
个人笔记总结
git remote -v 查看远程版本库信息
git remote add github < url> 添加github远程版本库
git fetch github 拉取远程版本库
git merge -h 查看合并帮助信息
git merge --allow-unrelated-histories github/master 合并github上的master分支(两分支不是父子关系,所以合并需要添加 --allow-unrelated-histories)
git push github 推送同步到github仓库
每次push本地代码之前pull一下远端代码,然后在push,就没有问题了。
老师你好,我有个问题哈,clone命令 git clone git@github.com:git2019/git_learning.git既然已经把远程仓库所有内容都克隆到本地了,为什么还需要git checkout -b feature/add_git_commands origin/feature/add_git_command 命令基于远程分支在本地建立分支,不是从远程clone下来了嘛,为什么还要新建,难道clone命令不能克隆分支嘛
作者回复: 我们在本地无法直接在clone下来的远程分支上做变更的,只能基于远程分支建本地分支后,才能创建commit
git pull 相对于两步git fetch+merge在什么场景下有问题?谢谢。
作者回复: 比如,团队有3个人共同维护一个特性分支,你们在本地直接在该分支上做开发。你的本地功能还没有开发完,还不想和远端的特性分支做集成,只是想看看和远端分支的差异,此时,就可以先执行 fetch,而不用 pull 。
git使用原则
1:push前一定先pull
2:合并代码必须两人结对
3:合并冲突,非自己的变动保持原样,和自己冲突的代码找相应的代码提交人确认如何解决冲突
4:合并完成后,保证本地能编译能运行再push
5:合并到主干的代码必须通过测试,必须通过代码review
6:不同的功能从主干上拉新分支进行开发工作
7:分支的命名需要加上,拉取人+拉取说明
8:上完线的分支要及时清理
前面章节讲git的文件存储时,说git存放blob文件时是以文件内容来区分的,并不以文件名来区分;此处的变更文件名操作和变更文件内容的操作能够自动被git处理,原因就在于blob文件并没有发生修改的冲突吧?如果其中一个人既变更了文件名又修改了文件,同时另一个人也修改了该文件的同一位置的内容,就会被git识别为冲突,而不能自动进行处理了。
老师,你好。想问一下比较简单的多人协助开发代码怎么管理代码分支合并? 现在我作为一个小组长,每天要合并各个成员的代码,打包到测试、预上线等等环境。又涉及到出错回滚等等。每天都花挺多时间在这里。老师能否给个流程或者建议。谢谢了。
作者回复: 你们看起来配置了专门的集成人员,你就充当了类似的角色。我补充说一下,如果你是懂业务并懂开发的,那么你来做这个涉及集成的一系列的工作,倒也挺好。否则就让开发自己来做集成。
为了早点发现集成是否有冲突,或者集成是否能通过一些列的测试,你们团队可以考虑用工具帮你们尽快发现集成的问题。找一些持续集成的资料看看吧,可以借助 Jenkins 或 其他CI工具试试吧。
老师,如果发现之前提交的commit不想要了,想恢复成之前的样子,是不是就不得不用git push -f命令了呢?
作者回复: 自己独自使用的分支,可以采用push -f 的方式。
团队集成分支,通常做法不是去掉不想要的commit,而是把不想要的commit的内容采用revert的方式生成新的commit,以此去掉不想要的变更。然后push到远端。
1:在主干分支上禁止使用git push -f
因为可能会抹掉其他的提交节点,假如有些东西提交了想回滚,那就修改后再提交
2:在主干分支上禁止使用变更提交历史的命令
因为会抹掉一些历史提交信息,我们貌似一直使用rebase,主要是不喜欢混乱的提交线,不过也没出现什么问题,合代码出问题主要集中在合并冲突时,有些代码调整的存在问题。
自己的分支随意,自己可以完全掌控,自己完全负责。公共分支是公地,不要做出影响他人的行为。
略
略
之前在github上搜索项目,直接用项目名搜索,学习这一讲内容后,以后可以添加其他限制条件,如stars:>1000,in:readme等,可以快速有效搜索自己刚兴趣的项目。
略
略
老师,我有个问题,就是如果某用户加入了某个组织,这个组织可以管理n个仓库,那么我是这个组织的一员,是不是就可以对这些仓库进行操作?还是我加入了组织,还得加入到某个team,才能对应进行操作?
作者回复: 这个权限继承的方式,建议大家到GitHub平台上测试一下。平台的做法可能也会随时间而改变的。
略
github
gitlab
github
github:pull request
略
略
Travis-CI工具
wiki
略
gitlab
gitlab:merge request
CICD的例子