Git 学习笔记
Git个人
安装git
使用git之前需要做的最小化配置
常用配置
git config [--local | --global | --system] user.name 'Your name'
git config [--local | --global | --system] user.email 'Your email'
一般选择global即可
config 的三个作用域?
git config --local -> local只对某个仓库有效
git config --global -> global对当前用户所有仓库所有用户有效
git config --system -> system对系统登录的所有用户有效(不常用)
如何查看config的配置?
git config --list [--local | --global | --system]
git仓库的创建和配置
建git仓库的两种情景:
-
将已有的项目代码纳入git管理
cd 代码所在文件夹 git init
-
新建的项目直接用git管理
cd 上层文件夹
git init your_project_name //会在当前路径下创建跟项目同名的文件夹作为仓库
cd your_project_name
git仓库配置local用户信息
git config --local user.name "your_user_name"
git config --local user.email "your_email"
git config --list --local // 查看配置是否生效
local与global的优先级
git add readme.txt //添加文件
git commit -m "add readme.txt" //提交文件
git log // 查看git日志 查看其中的Author和email,global的还是local生效
初识工作区与暂存取
4 次提交,⼀个有模有样的静态⻚⾯⽣成了
-
加⼊ index.html 和 git-logo
-
加⼊ style.css
-
加⼊ script.js
-
修改 index.html 和 style.css
工作目录 -> 暂存区 -> 版本历史
git add files git commit
常用工作流程:
工作目录修改 -> git add将修改文件添加到暂存区
工作目录修改 -> git add将修改文件添加到暂存区 -> git commit 统一提交
工作目录修改 -> git add将修改文件添加到暂存区
git add -u //将已纳入git管理的修改文件全不添加到暂存区
文件重命名的简便方法
方式1:
mv readme.txt readme.md //在工作目录重命名
git status // 发现readme.txt需要被删除 readme.md未纳入git管理
git add readme.md //将新文件纳入git管理
git rm readme.txt //删除readme.txt
git status //发现git智能检测到重命名
// git commit -m "重命名" // 提交更改即可完成更名
git reset --hard //还原暂存区和工作区的更改
git log //发现日志未发生改变
方式2(直接使用git命令完成重命名):
git mv readme.txt //直接使用git命令完成重命名 避免删除和重新add
git commit -m "move readme.txt to readme.md" //提交更改
查看版本历史
命令行查看
git log --oneline // 查看commit摘要信息(版本号 描述)
git log -n3 //查看最近三条commit记录
git log -n3 --oneline // 最近三条commit记录的摘要信息 组合使用
git log // 默认查看当前分支的commit 记录
git log --all // 查看所有分支commit记录
git log --all --graph //所有分支commit记录 图形化显示
git log --oneline --all -n4 -- graph// 查看所有分支commit摘要 最近4条 图像化显示
扩展:
git branch -v //查看当前本地分支
git commit -am "branch:tmp update test" //直接将工作区的文件commit到仓库 一般不适用
git help --web log //浏览器查看帮助文档 log命令
git checkout master // 切换到master分支
图形界面查看
gitk //图像化界面查看日志
patch -> 变更集 对比old-> new 文件 查看diff
tree -> 当前commit下的目录结构
Author -> 作者 Committer -> 提交人
当作者在develp分支上提交,Committer 将其合并到master分支上时 Author与Committer不相同
Parent -> 上一次commit 版本号
Child -> 下次Commit版本号
branch : 哪几个分支包含此commit
view -> 定制页面内容
refs -> 分支选择
鼠标右键 -> 更多功能使用(create tag,create new branch...)
.git目录详解
HEAD -> ref: refs/heads/tmp 引用: 指向随着当前分支改变
config -> core user 仓库配置
refs -> heads 分支 (开发的独立空间)
-> tags 里程碑(项目开发到一定程度 我们可以对其所对应的commit打上一个标签1.0,标识这个里程碑)
heads -> master(指向master的commit的引用) 4e13ccc2b71167a2a858aea4aaf73e5b23ec0b52
-> tmp(指向tmp的commit的引用) 30e8c1f638088868963caf1e3172628277b72d53
git branch -vl //查看当前分支信息 我们可以观察到master与tmp所存储的就是分支对应commit引用
git cat-file -t 4e13ccc //查看引用类型
git cat-file -p bfce9b7 //查看引用内容
objects tree
blob
commit
tag
object类型commit-tree-blob之间的关系
tree生成blob时,内容相同的文件只生成一个blob,节约存储空间
同一个文件在修改后会生成一个新的blob,git会对松散的blob做整理,将内容相近的文件做增量存储
数一数tree的个数
新建的Git仓库,有且仅有1个commit,仅仅包含 /doc/readme ,请问内含多少个tree,多少个blob?
image解答:
mkdir doc //新建空目录时git不处理
echo "hello,world" > doc/readme.txt //工作目录新建文件时 objects下无内容
git add doc // objects 下生成一个文件blob 内容为我们新建的文件内容
git commit -m 'add readme.txt'//objects 中新建一个commit 一个commit快照tree 一个doc文件夹tree
分离头指针(detached head)
出现原因
git checkout 4e13ccc //切换到指定commit版本 当前不指向任何指针
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
即我们现在工作在一个没有分支的状态下,你产生了变更,并提交了commit,然后直接切换到指定分支完成工作时,我们在分离头指针条件下做出的变更很有可能会消失。在我们想做一些尝试性的变更时可以在分离头指针的状态下进行,若对变更的结果不满意,我们直接切换分支即可,并不会对其他任何分支产生影响,若我们需要保存变更,只要私用 git branch <new-branch-name> a4ec3fd 创建一个新的分支与这次变更连接上即可。
HEAD与branch再理解
//基于某个分支或某此commit创建新的分支 并切换到新分支
git checkout -b <branch-new-name> [branch-name-exist|commit-hash]
HEAD 可以指向分支的最后一次commit,也可以不与分支挂钩(detached HEAD) ,指向某一次commit, 当我们使用git checkout <branch-name> 切换分支时,HEAD的值也会随之改变
HEAD -> branch-name -> branch最后一次commit
HEAD -> 某一次commit
总之,HEAD最后都指向某个commit
HEAD特性利用
git diff commit1_hash commit2_hash
//比较HEAD和HEAD的第一个parent的差异(HEAD可能有多个parent -> 多分支合并)
git diff HEAD HEAD^ <=> git diff HEAD HEAD>1
git diff HEAD HEAD~ <=> git diff HEAD HEAD~1
//比较HEAD和HEAD第n个祖先提交
git diff HEAD HEAD~2 <==> git diff HEAD HEAD^1^1 <==> git diff HEAD HEAD^^
分支删除
git branch -av // 查看分支列表
git branch -d <branch-name> // 删除分支,若待删除分支有内容未full merge,删除失败并提示
git branch -D <branch-name> //删除分支而不管待删除分支是否有内容未merge
错误提示示例:
$ git branch -d branch-save-test
error: The branch 'branch-save-test' is not fully merged.
If you are sure you want to delete it, run 'git branch -D branch-save-test'.
一般使用 -d 命令删除分支,确认无需merge时使用-D 删除,当然若确认不用merge时也可直接使用-D
最近commit修改
git commit -amend //对最近commit 做commit修改而不生成新的commit
一般用于push之前修改commit信息
思考:若commit已经push到远端又该如何解决?
老旧commit修改
//选择需要改变提交info的commit的parent执行变基操作(交互式)
git rebase -i <parent-commit-hashcode>
查询需要修改的commit的parent
image选择仅修改commit 信息
image修改 commit infomation
image修改成功 commit-information发生改变 ,Head对应hash-code也发生改变
image注: 以上修改基于本地commit做变更,若已经push到remote,需慎重考虑,以免为团队成员带来不便
commit整理
连续commit整理
当前commit-logs:
imagegit rebase -i 508b3a //选择base进行交互式变基操作
操作commit向前一个commit合并:
合并操作示意合并完成后 保留原有commit-information 并添加新的commit-info
imagecommit合并结果:
image非连续commit整理
查看当前commit日志 整合readme相关提交
imagegit rebase -i 508b73a4f92dabdc6d//选择跟节点进行变基操作 合并涉及根commit 无parent
image
添加commit-info后即完成合并
暂存区与HEAD差异比较
git diff --cached //比较暂存区与HEAD的差异
操作流程:
vim index.html //修改index.html 工作目录 添加git add 命令
git diff --cached //无差异
git add index.html //工作区修改添加到暂存区
git diff --cached //检测到添加git add 发现不是自己想要的命令
vim index.html //修改index.html 将git add 替换为 git config
git add index.html //将修改再次添加到暂存区
git diff --cached //发现添加command 替换为git config
git commit -m 'add first command' //将暂存区中的修改生成commit
工作区与HEAD差异比较
git diff //默认比较工作区与暂存区的差异(所有文件)
git diff -- <file-name> //比较工作区与暂存区指定文件的差异
git diff -- <file-name1> <file-name2> //查看工作区与暂存区多个指定文件的差异
暂存区还原为HEAD
git reset HEAD //将暂存区还原为HEAD(因某些原因不想要之前add添加到暂存区的文件时可以使用)
git rest HEAD <file-name>
工作区还原为暂存区
git reset //将暂存区内容还原为HEAD
git checkout <file-name> //discard changes in working directory
暂存区部分文件还原为HEAD
git reset HEAD -- <file1> <file2> //将暂存区部分文件还原为HEAD
最近commit还原
//将工作目录和还原到某次commit 之前的commit都会消失(慎用)
git reset --hard <commit-hash-code>
不同分支指定文件差异比较
git diff <branch1> <branch2> -- <file1> <file2> //比较不同分支指定文件
git diff <commit1-hash-code> <commit2-hash-code> -- <file1> <file2> //不同commit文件比较
文件删除
git rm <file-name> //删除暂存区和工作区中的指定文件
git commit -m 'delete file-name' //提交文件删除
加塞紧急任务
git stash //利用stash暂存工作区修改
git stash list // 查看暂存修改列表
git stash apply //将工作区恢复成stash list top状态 stash list保持不变
git stash pop //利用stash list中弹出的stash还原工作区,stash list中弹出了一个stash
git不需要管理的文件
添加 .gitignore 文件,并在文件中配置,注意加'/'与不加的区别
git仓库本地备份
备份协议
image多点备份
image//使用哑协议备份
git clone --bare /c/Users/lenovo/Desktop/git/tmp/.git ya.git
//智能协议备份
git clone --bare file:///c/Users/lenovo/Desktop/git/tmp/.git zhineng.git
//添加远端分支
git rmote add zhineng file:///c/Users/lenovo/Desktop/git/my-backup/zhineng.git
//查看当前分支
git branch -av
//基于HEAD添加备份分支用于测试同步到远端
git checkout -b testBackUp HEAD
//推送到叫zhineng的远端的testBackUp分支 进行同步
git push --set-upstream zhineng testBackUp
//进入远端查看分支信息
git branch -av //发现新增了testBackUp分支
GitHub初识
公私钥配置
Adding a new SSH key to your GitHub account
本地仓库同步gitHub
1.gitHub建立仓库 git-learning 选择mit证书
2.建立本地仓库与gitHub仓库建立联系
git remote add git_hub_learn git@github.com:xiangfeifei54/git-learning.git
//本地仓psuh到远端
git push git_hub_learn --all //tmp与testBackUp分支push成功 maser分支报错
master push失败 -> 远端整数commit与本地仓库commit没有共同的parent
解决:
-
先将远端master fetch下来 -> merge本地与远端 -> push
//allow merging unrelated histories git merge --allow-unrelated-histories git_hub_learn/master
-
先将远端master fetch下来 -> rebase 本地与远端记录 调整为顺序树结构 -> push
再次push 成功
git push git_hub_learn master // 本地commit push到gitHub master分支
不同人在相同分支修改不同文件
一个人准备push时发现remote已经有了一个新的提交,无法直接完成push,需要先fetch下remote的commit
方法一:
git merge git_hub_learn/feature/add_git-_commands //merge 本地与remote分支
git push git_hub_learn add_git-_commands //本地commit提交到remote
不同人在相同分支修改相同文件但不同区域
方法同上 merge 时git能自动处理,不需要人工介入
不同人在相同分支相同区域修改相同文件
Your branch and 'origin/feature/add_git-_commands' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
此时merge之后会生成conflict
- 解决:上一个commit的提交者商议后,完成冲突文件的修改,再次重新commit产生conflict的文件,git status发现merge冲突已解决,将commit 提交到remote即可,
- 忽略此次merge: git merge --abort
同一文件被不同人改为不同的文件名
push会失败,之后我们通过git pull 拉取和自动merge,结果发生冲突
$ git pull
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 2 (delta 1), reused 2 (delta 1), pack-reused 0
Unpacking objects: 100% (2/2), done.
From github.com:xiangfeifei54/git-learning
ba38a57..9bcac40 feature/add_git-_commands -> origin/feature/add_git-_commands
CONFLICT (rename/rename): Rename "index.html"->"index1.html" in branch "HEAD" rename "index.html"->"index2.html" in "9bcac40668292ea491e4b56e69a8d605b26cc8eb"
Automatic merge failed; fix conflicts and then commit the result.
查看当前状态
$ git status
On branch feature/add_git-_commands
Your branch and 'origin/feature/add_git-_commands' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add/rm <file>..." as appropriate to mark resolution)
both deleted: index.html
added by us: index1.html
added by them: index2.html
no changes added to commit (use "git add" and/or "git commit -a")
状态提示需要使用 git add/rm <file> 解决conflicts,经过协商,我们决定重命名为index1.html
git rm index.html //删除index.html
git add inex1.html //添加index1.html
git rm index2.html //删除index2.html
查看当前状态
$ git status
On branch feature/add_git-_commands
Your branch and 'origin/feature/add_git-_commands' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
提示conficts已经修复,我们仍然出于merge状态,需要我们再次commit
git commit -m 'Resolved conflicts : decided to mv index to index1'
将commit push到remote 完成重命名
git push //使用默认分支即可
Git集成使用禁忌
git checkout //慎重使用
git reset//慎重使用
git push -f //禁止使用 会破坏git的安全机制
若本地使用了git reset --hard <commit-hash-code> 还原了本地commit,正常push会有报错信息,无法push成功,若何使用-f 参数,则强制push成功,remote的commit都会被一起还原。
禁止变更集成分支历史
本地rebase形成新的commit并push到远端会导致协同开发人基于最新commit做出的开发与现在的remote发生no fast-forward ,别人也需要重新做merge或rebase。
GitHub再了解
使协作 编写软件 git使用 更加容易
image快速查找开源项目
in: readme //readme 中修改
stars:>100 // starts>100
GitHub个人blog搭建
开源项目代码质量
持续集成+code review
组织类型仓库
人员管理 team管理 权限管理
团队项目
选择组织 -> 新建团队项目 -> readme/ignore/license -> marketplace apps(集市授权访问仓库)
权限设置 -> settings -> Collaborators & teams -> admin/write/read
团队工作流
主干开发 -> git flow -> gitHub flow -> gitlab flow(带生产分支) -> gitlab flow(带环境分支)
gitlab flow(带发布分支 多个版本存在) ->
启用issue跟踪需求和任务
issue维护划分