git学习笔记

git

知识导读git
  • 了解Git使用场景、基本概念、发展史
  • 掌握Git常用命令
  • 了解Git相关工具
  • 了解Git服务器搭建
  • Git应用总结
参考资料
  • 廖雪峰官方网站 https://www.liaoxuefeng.com/wiki/896043488029600
  • 易百教程 https://www.yiibai.com/git
  • 菜鸟教程 https://www.runoob.com/git/git-tutorial.html
  • 书籍 《Pro Git第二版(中文版)》
  • 网络各大机构教程
当前学习进度(完成后删除)

https://www.liaoxuefeng.com/wiki/896043488029600/900004590234208

使用场景、基本概念、发展史

主要应用于文件管理,主要为文本文件,如代码管理。是目前世界上最先进的分布式版本控制系统(没有之一)。参考入门资料https://www.liaoxuefeng.com/wiki/896043488029600/896067008724000,深入了解参考以上资料。

Git常用命令
#设置Git全局用户名和邮箱
git config --global user.name "your name"
git config --global user.email "you email"

#初始化仓库(在某目录下执行)
git init
#加入文件当前状态到暂存区(可能是添加了一个新的文件及内容,可能是新的内容修改,仅局限本次内容): git add 
git add readme.txt
#提交暂存区的文件到仓库中: git commit -m 
git commit -m '加入了两行文本'

#查看工作区、暂存区及仓库的状态
git status
#比较某文件工作区与暂存区的差异(若暂存区没有该文件,会从仓库获取该文件): git diff 
git diff readme.txt

#查看当前分支的提交日志(按照当前文件的提交记录逆序展示) 每次提交的commit id、msg、时间及提交人都会展示出来
git log
#查看git的提交日志(展示所有被提交了的commit id,即使某commit id被reset了)(该日志不会和远程仓库关联,本地日志,意味着push fetch pull等不会推送、加载。该日志不是永久的,会被定期执行的gc清理掉,某时间范围之前的就会丢失)
git reflog
#重做某次执行(仓库、暂存区及工作区都更改) 可以回退或跳跃到某次提交 commit_id可以采用HEAD代替,HEAD表示当前指针,HEAD^上次提交的指针,依次类推
#git reset --hard 
git reset --hard 44c638823cc9fb3fa5633b57d4b9b6a0b9460060
#重做某次执行(仅更改仓库和暂存区,不更改工作区) git reset 
git reset HEAD
#撤销某次commit id的提交 git revert ,这里和reset不一样,这里是撤销某次提交,得到某次提交之前的状态(仓库、暂存区及工作区都改动),reset是重置至预期的状态(reset的id是目标)。一般都是撤销最后一次commit id,因为撤销之前的commit id可能产生冲突。冲突可能需要手动处理,add或者rm置为解决状态,再次提交。
git revert HEAD
#批量依次撤销提交 git revert .. 这里指old指早的提交,new指新的提交。会从new开始一直撤销到old的状态(不包含撤销old),所以一般为了撤销old,也符合撤销的整体思路,一般是old^,加^代表上个提交,这里就会撤销old了。一般尽量的new使用HEAD,这样没有冲突。比如撤销了n次提交,需要手动输入每次撤销的commit id(第一次是revert后边都是continue),并且下次手动执行git revert --continue(最后需要多执行一次,revert1次,continue为n次,最后一次没有意义,仅仅让git标志为结束而已(除了最后一次标志结束不用输入msg之外,之前的每次执行都得输入)),一直撤销完最后一次,这样就把每次都撤销了。
git revert 2e9aa8f447188bde5aec4d0fe74a60d719485305..HEAD
git revert 2e9aa8f447188bde5aec4d0fe74a60d719485305^..HEAD
git revert --continue
#一次撤销多次提交(range描述与上边一致不包含前边,包含右边,为了包含前边采用了^) git revert -n   再次需要执行 git commit -m  这里行为上是撤销了多次提交,往前只有一个commit,执行完了没有提交,仅仅是到达暂存区,需要再次手动执行commit 操作结束,推荐这种处理方式
git revert -n 2e9aa8f447188bde5aec4d0fe74a60d719485305^..HEAD
git commit -m '撤销最后三次提交的代码'
#丢弃修改(恢复工作区至暂存区/仓库状态,若暂存区有该文件某状态,恢复至暂存区,若没有则恢复至仓库) git checkout --  注意一定要加 --,否则就变成了切换分支
git checkout -- readme.txt
#标识暂存区中删除某个文件 git rm  与暂存增加或暂存修改类似git add   要想更新版本库(包含增加、删除及修改),还得git commit -m 
git rm test.txt
#远程仓库账号关联本地机器 基于非对称加密、ssh协议方式
https://www.liaoxuefeng.com/wiki/896043488029600/896954117292416
#关联本地仓库与远程仓库 git remote add [远程主机名称] [远程仓库地址]
git remote add origin [email protected]:gaofeilongdev/gitLearnOne.git
#查看远程仓库本地标识名称
git remote
#查看远程仓库信息(包含fetch和push的地址)
git remote -v
#解除本地仓库与远程仓库的关联关系 git remote rm [远程主机名字]
git remote rm  origin
#查看所有本地分支名称
git branch
#查看本地和远程所有分支名称
git branch -a
#查看本地所有分支,每个分支的commitid,展示msg信息,若与远程存在差异,则描述差异“步数”
git branch -v
#查看所有本地分支,同时展示本地分支关联的远程分支(没有关联远程分支的本地分支,无法展示关联远程分支,仅展示本地分支)(git branch -v有的信息这里也有)
git branch -vv
#推送本地某分支到远程仓库某分支(远程分支没有自动创建) git push [远程主机名称] [本地分支名]:[远程分支名]
git push origin master:master
#推送本地某分支到远程同名分支(远程没有则自动创建),并关联本地该分支与远程该分支 git push -u [远程主机名] [本地分支名]
git push -u origin dev
#删除远程仓库某分支 git push [远程主机名] :[远程分支名] 或 git push [远程主机名] --delete [远程分支名]
git push origin :dev
git push origin --delete dev
#推送本分支与关联的远程分支(默认simple方式,需要当前分支与远程分支关联;需要当前分支与远程分支名称一致)
git push
#强制推送 如果本地分支与远程仓库关联分支存在冲突,远程分支无法采用"Fast Forward"模式自动merge推送的commit 对象,可以采用这种方式处理。远程仓库关联分支会自动切换到本地分支关联的提交树中,最后一个commit id和本地一致。
git push -f
#创建新分支 git branch <新分支>
git branch dev
#切换到已有的某分支 git checkout <分支名> 或 git switch <分支名>
git checkout dev
git switch dev
#创建并切换到某分支 git branch -b <新分支>(等于先git branch <新分支>然后git checkout <新分支>) 或git switch -c <新分支>(等于git branch <新分支>然后git switch <新分支>)
git checkout -b dev
git switch -c dev
#删除某已经被合并的分支(需要该分支已经被merge到当前分支或者push到远程仓库) git branch -d <分支名>
#合并某分支到当前分支(把另一个分支的内容搞到这个分支来) git merge <合并的分支> (若合并的分支commit id在当前分支之后能够串起来,继续提交,则没有冲突,为Fast-forward。)
git merge dev
git branch -d dev
#强制删除某分支(不限制该分支必须合并到当前分支或者push到远程仓库)
git branch -D dev
#比较工作区与上次索引的差异(上次索引指的在暂存区中的文件状态或者仓库中的文件状态) a代表之前的状态 b代表之后的状态 参考下边(可以理解为git diff 索引 工作区)
git diff
#比较两个commit id的差异 git diff   (旧状态放前边或者叫做原点,新状态放后边或者叫做偏移点)
bogon:gitlearn gaofeilong$ git diff a4c70a1 b73c007
diff --git a/a.txt b/a.txt
index 7898192..422c2b7 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1,2 @@
 a
+b
diff --git a/test.txt b/test.txt
index 814f4a4..58ac960 100644
--- a/test.txt
+++ b/test.txt
@@ -1,2 +1,3 @@
-one
 two
+three
+four
#上每组结果解析:第一行为解析后的命令;第二行为索引;第三a代表前边的旧id,第四b代表后边的新id;---代表-代表a,+++代表+代表b,后边的指的diff文件;@@ -1 +1,2 @@中-1代表a文件从第1行开始,一共1行默认不写,+1,2代表b文件从第1行开始,一共2行(展示diff范围);-代表后来(b代表后来,参考a为原点)删除了该行,红色展示,+代表后来增加该行,绿色展示(最后的+-仅代表增删,不代表ab)。
#所有情况merge分支 合并某分支到当前分支中 git merge <分支名> 解决状态git add <冲突文件> 提交数据 git commit -m 
#合并策略 1.若两个分支提交路径存在重合,则直接采用fast forward模式(快进模式),自动merge(最终状态就是干净的工作区);2.若两个分支提交路径存在分叉。①若仓库中每个文件提交路径都是重合的,则采用recursive策略,本质就是每个文件单独的fast forward。自动merge,最终状态为干净的工作区。②若仓库中存在非重合提交路径的文件。观察从共同起点开始,每行是否发生了变化,改变行中提交路径是否重合(或者理解为变化行中是否两个分支都改动了) ,如果行提交路径重合,则自动merge叫做recursive策略。如果全部搞定(recursive策略)则merge完毕。如果存在非重合提交行(或者理解为两个分支都有改动,行冲突),则先把重合提交路径的文件自动采用recursive模式,并且冲突文件中重合行自动merge(recursive模式),冲突行采用特殊格式展示冲突,这里需要人为merge。自动merge完毕的文件为resolution状态,如果一个文件全部被recursive模式自动merge,则文件自动resolution,本质就是处于暂存区。存在冲突行的文件没有add到暂存区,conflict部分自动展示为特定格式。需要手动将特性格式部分修正为最终状态。add到暂存区(这个动作意味着冲突解决了)。统一提交到仓库中,解决完冲突。
git merge dev
#查看本地分支、merge分支与工作区的diff差异(这里不能add,add后认为resolution了,diff后到暂存区就被“拦截”了,没有任何差异)
#这里隐含了默认 本地分支 vs 工作区 及 merge分支 vs工作区 git diff <文件名(可以加也可以不加)>
bogon:gitlearn gaofeilong$ git diff
diff --cc readme.txt
index e59222f,220e3b1..0000000
--- a/readme.txt
+++ b/readme.txt
@@@ -1,2 -1,3 +1,7 @@@
  Git is a version control system.
++<<<<<<< HEAD
 +Creating a branch is quick and simple(master).
++=======
+ test the second line.
+ Creating a branch is quick and simple(dev).
++>>>>>>> dev
#以上解析:1.第一行表示存在三个状态diff(可能为本地分支被diff的文件)(-表示,作用于@行)。2.第二行表示索引信息。3.第三行可能表示merge分支被diff的文件(-表示,作用于@行)。4.第四行表示工作区被diff的文件(+表示,作用于@行)。5.第五行(@行)分别表示本地分支、merge分支及工作区文件(第一和二的-表示本地分支及merge分支,第三个+表示工作区文件)。每组数字中第一个数字代表从哪一行开始,第二个数字表示涉及多少行(如果只有一行,这里会忽略)。6.下边是diff区域,本地分支与工作区diff和merge分支与工作区diff联合展示。每行开始有两个字符,第一个字符表示本地分支与工作区的差异,第二个字符表示merge分支与工作区的差异(工作区都理解为后来状态)。如果字符表示为空格则没有差异;如果字符表现为+,则表示工作区增加一行;如果字符表示为-,则表示工作区减去一行。(某行存在冲突的时候,HEAD和分支名分别会展示出来(执行完merge命令后,会写文件),各自表示各自的+和-)。
#本地分支与工作区diff(执行完merge命令,需要手动处理冲突,还没处理的时候)(工作区表示后来状态)
git diff --ours
#merge分支与工作区diff(执行完merge命令,需要手动处理冲突,还没处理的时候)(工作区表示后来状态)
git diff --theirs
#标记文件未解决状态 resolution (执行完merge命令,需要手动处理冲突)  git add <文件名>
git add readme.txt
#提交merge结果(执行完merge命令,需要手动处理冲突,所有的冲突都解决了后) commit -m <描述信息>
git commit -m '解决冲突'
#中止merge 如果执行完merge后,仍然需要手动处理merge,但是不想要继续手动merge了(是否标记add都行),使用此命令中止merge
git merge --abort
#禁用"Fast Forward"模式merge,比如某个merge由于提交路径重合,直接基于Fast Forward就能merge完毕,但是快进模式不能展示这段提交是merge来的,所以有的场景可以禁用,最终git提交路径会单独展示是merge来的 git merge --no-ff -m <描述信息> <分支名>
git merge --no-ff -m 'merge dev to master' dev
#展示当前分支的提交日志,来源(merge来)于不同分支的提交记录以分支合并图展示
git log --graph
#储藏工作目录和索引状态(储存在缓存中,没有持久化)(当前的工作目录会变得和仓库一样,干净的状态)(只能储藏有变动的工作区,每次压栈,最后一次储藏的为0号索引)
git stash
#查看储藏列表
git stash list
#应用储藏信息 git stash apply <索引号(不指定默认就是0号索引,格式如stash@{1},可以写入多个储藏信息,依次添加)>
git stash apply
#删除储藏信息 git stash drop <索引号(不指定默认0号索引)>
git stash drop
#弹出并应用某储藏信息 会弹栈(删除0号索引的储藏信息),然后写入储藏信息
git stash pop
#复制某次commit id的提交(对提交内容进行复制,会生成新的commit id,与merge有所不同)(仅针对本次commit id重做commit,本次commit id之前的commit不会重做) git cherry-pick 
git cherry-pick 4c805e2
#建立本地某分支和远程某分支的关联 git branch --set-upstream-to=<远程仓库名称>/<远程分支名称> <本地分支名称>
git branch --set-upstream-to=origin/dev dev
#取消本地分支与远程某分支的关联
git branch --unset-upstream
#检出远程仓库某分支到本地新建分支,并且建立关联关系 git checkout -b <本地新分支> <远程仓库名称>/<远程仓库分支> 或 git switch -c <本地新分支> <远程仓库名称>/<远程仓库分支>
git checkout -b dev origin/dev
git switch -c dev origin/dev
#加载远程仓库某远程分支(本质git内部remote路径维护了远程分支指针(会指向某对象,猜测对象与本地指针指向的一样,在一个地方维护),指针和data都在本地储存)(这里仅加载了一个分支的数据) git fetch <远程仓库名称> <远程仓库分支>
git fetch origin dev
#加载远程库所有分支及标签(有新分支则拉取新的分支,没有新分支旧分支(旧分支是否关联本地分支不关心)有新的提交也更新)(若远程仓库发现新tag也会被加载)
git fetch
#merge远程分支到本地分支(这里采用的是远程分支中本地储存的指针和data)(没有网络请求) git merge <远程仓库名称>/<本地分支名称>
git merge origin/dev
#拉取远程仓库某分支到本地某分支 git pull <远程仓库名称> <远程分支名>:<本地分支名>
#注意!!! 与push完全相反([本地分支名]:[远程分支名]),push本地推到远程,pull远程拉取到本地
#注意!!! 最好当前分支就是目标拉取的本地分支,因为这个命令还会自动拉取到本地分支一份。
#git 所有的pull命令都等于先fetch后merge
git pull origin dev:dev
#拉取远程某分支到本地分支 git pull <远程仓库名称> <远程分支名>
git pull origin dev
#拉取与本地分支关联的远程分支到本地分支 这个命令可以理解为 先git fetch(拉取所有的远程分支) 再git merge FETCH_HEAD (FETCH_HEAD为fetch过程中与当前本地分支关联的远程分支commit id) 当前本地分支若没有关联远程,这里会报错
git pull
#已经被删除掉的远程分支,把本地缓存删掉(否则即使远程分支没了,本地还有缓存文件)(origin) git remote prune <远程主机名>
git remote prune origin
#把本地未push的分叉提交历史整理成直线 应用场景,如果提交远程仓库,发现远程仓库代码发生变更,则需要merge远程,比如采用git pull,merge完毕后,基于与远程共同commit id节点往后观察,会发现有多个分叉,代表不同的提交分支,如果感觉分叉比较乱,可以使用rebase命令(变基),该命令本质就是重置每次的commit id(回退到远程一样的commit id节点,merge远程(此时commit id与远程一致),将自己每次commit的代码重新提交(如果这里存在和远程代码冲突,可能需要手动处理冲突),最终发现提交路径是条直线,因为是基于远程commit id提交的代码)
git rebase
#若变基存在冲突,则需要手动处理冲突,将冲突的文件置为已解决,采用git add  或者git rm 标记为已解决,然后基于变基 git rebase --continue
git add test.txt
git rm a.txt
git rebase --continue
#git标签:标签本质是指向了某个commit id,commit id为了不重复,名字叫长、没有规律,不方便人记忆。所以git采用标签功能
#创建标签(简单模式) git tag <标签名字>  这里的可以不指定,默认是HEAD(当前分支最后提交的commit id)(新创建的tag名字若和历史标签冲突,本次创建会失败)
git tag v1.0
git tag v1.0 1eb6b7d52180ca06f41de89630d16ed4d055bb6e
#创建标签(详细模式)(简单模式没有tag的描述信息,详细模式会有) git tag -a <标签名字> -m <标签描述信息>  这里的可以不指定,默认是HEAD
git tag -a v1.0 -m '十月一前发布tag'
git tag -a v1.0 -m '十月一前发布tag' 1eb6b7d52180ca06f41de89630d16ed4d055bb6e
#查看所有标签 所有的标签会换行展示出来,无论是否当前分支存在tag的commit id
git tag
#查看所有标签 并且基于某种规则搜索 git tag -l '*搜索内容*'
git tag -l '*feilong.gao'
btag-20210121-123012-feilong.gao
btag-20210121-123407-feilong.gao
#查看某个标签的详细信息
git show v1.0
#举例
bogon:gitlearn gaofeilong$ git show v1.0 #展示v1.0标签的详细信息
tag v1.0 #标签名字 (只有详细模式会展示)
Tagger: feilong.gao <[email protected]> #标签创建人 (只有详细模式会展示)
Date:   Sun Aug 29 15:55:57 2021 +0800 #标签创建时间 (只有详细模式会展示)

十月一放假前发布标签 #标签描述信息 此信息是创建标签的时候传入的 (只有详细模式会展示)

commit fb3d6d8c91d70532c46c47e17f310a72cb16bb4e (tag: v4.0, tag: v1.0)#标签指向的commit id 该commit id还被哪些tag指向了
Author: feilong.gao <[email protected]> #该commit id提交人
Date:   Sun Aug 22 23:18:33 2021 +0800 #该commit id提交时间

    撤销最后三次提交 #该commit id提交的描述信息

diff --git a/a.txt b/a.txt #该commit id提交的变更 本质是 git diff this_commit_id^ this_commit_id 
index 01e79c3..e69de29 100644
--- a/a.txt
+++ b/a.txt
@@ -1,3 +0,0 @@
-1
-2
-3
#删除某标签 git tag -d ... 后边可以追加多个tag名字
git tag -d v1.0
git tag -d v1.0 v2.0
#推送某标签到远程仓库中(无论push还是fetch,git是分布式思想,以自己为重要地位,假设远程仓库存在该tag,tag内容完全一样,则显示为Everything up-to-date表示无需重复推送;假设远程仓库存在该tag,tag内容不一样,远程仓库会拒绝被推送,本地会报错。只有远程仓库不存在,会推送成功。fetch场景,假设远程仓库存在本地没有的tag,本地拉取最新的(直接git tag就能查到,不会本地区分fetch和pull隔离一个远程对象存储);假设本地存在同名的tag,无论是否内容一致都不会再次加载,假设不一致也不会报错,因为假设远程和本地一致,不报错可以理解,假设不一致,本地可能存在大量冲突的,本地为准,大量报错没有意义,本地也不会处理。) git push <远程仓库名称> <标签名称>
git push origin v1.0
#推送本地所有标签到远程仓库 git push <仓库名称> --tags 如果本地有远程不存在的tag,远程被推送。如果远程存在同名分支,判断是否内容一致,一致则没有信息,不一致则提示报错,但是不影响其他的推送
git push origin --tags
#删除远程标签 git push <仓库名称> :/refs/tags/<标签名> git push <仓库名称> :<标签名> git push origin --delete <标签名>
git push origin :refs/tags/v1.0
git push origin :v1.0
git push origin --delete v1.0 #推荐此方式 后边可以追加多个 git push origin --delete v1.0 v2.0
#拉取远程仓库的分支及标签 本地可能加载到新的标签,如果本地和远程标签重名则跳过,无论内容是否一致
git fetch
#基于某标签,检出某新分支 git checkout -b <新分支名>  git switch -c <新分支名>   注意新分支有了新的提交后,不影响原来的标签,标签是静态的
git checkout -b test01 v1.0
git switch -c test01 v1.0
#喜欢开源社区github的代码可以 fork他们仓库的代码到自己仓库中,自己开发完毕,基于自己仓库发送pull request请求给开源社区
#让Git显示颜色,会让命令输出看起来更醒目
git config --global color.ui true

你可能感兴趣的:(工具,git,学习,笔记)