GIT的资料

                                                         GIT 
        git仓库中提交记录保存的是你的目录下的文件快照,提交记录即可能轻量,每次提交时,不会盲目复制整个目录,条件允许的情况下,会将当前的版本与之前的版本进行比较,将所有的差异打包到一起作为一个提交记录
        git保存了历史提交记录。

        hide goal 关闭窗口
        git commit  将含有o/main和main*的main*向下提交一次


   git branch
git 的 分支也是非常轻量级的,只是简单的指向某个提交记录(早建分支,多用分支)
即使创建再多的分支也不会造成存储或内存上的开销,并且按逻辑分解工作到不同的分支要比维护臃肿的分支要简单的多
分支和提交记录协作,建立分支,相当于基于这个提交以及他所有的父提交进行新的工作

git  branch newImage  git commit   新创建的分支newImage指向提交记录  ,main分支前进了   main上的*号代表当前所在的分支是main

git checkout newImage; git commit  可以实现在提交修改之前先切换到新的分支上

git checkout -b <your-branch-name>   创建一个新的分支同时切换到新的创建的分支上


分支与合并
合并:新建一个分支,在其上开发某个 新功能,开发完成后再合并回主线
git merge bufFix 
在git 中合并两个分支时会产生一个特殊的提交记录,他有两个父节点。(要把两个父节点本身及他们所有的祖先都包含进来)
每个分支上都有一个独立的提交,这意味着没有一个分支包含我们修改的所有内容,通过合并分支来解决,合并完成后,main现在指向一个拥有两个父节点的提交记录。从main沿箭头往上看,在达到起点的路上会经过所有的提交记录。这意味着main包含了对代码库的所有修改

把main分支合并到bufFix    git checkout bufFix;   git merge  main(每个分支都包含了代码库的所有修改)
可以用objective 命令来打开对话框

 git rebase
rebase(可以创造更线性的提交历史,使得代码库的历史提交记录变得更清晰)就是取出一系列的提交记录,复制他们,然后在另一个地方逐个的放下去。

将bugFix 上的分支直接移到main分支上    git rebase main  现在bugFix分支上的工作在main的最顶端,同时得到更为线程的提交序列
           	注意,c3依然存在(数上那个半透明的节点),而C3'是我们rebase到main分支上的c3的副本(main还没有更新)
现在切换到main上,把它rebase到bugFix分支上    git rebase bugFix

head
head(指向当前分支上最近一次的提交记录) 是一个对当前检出记录的符号引用---也就是指向你正在其基础上进行工作的提交记录
大多数修改提交树的git命令都是从改变head的指向开始的。  head通常情况下都是指向分支名的。在提交之前,改变了bugFix的状态,这一变化通过head变得可见

提交前后head的位置 git checkout c1; git checkout main;  git commit ;  git checkout c2(head指向了main,随着提交向前移动)
想看head的指向,可以通过cat  .git/HEAD 查看,如果HEAD的指向是一个引用,还可以用 git symbolic-ref HEAD查看它的指向。

分离的HEAD
分离的HEAD就是让其指向了某个具体的提交记录而不是分支名。
HEAD—>main–>c1 使用git checkout c1 命令后

相对引用
git log 来查看提交记录的哈希值           git对哈希的处理很智能,只需提交能够唯一标识提交记录的前几个字符即可。
通过哈希值提交记录不方便,所以git 引入了相对引用   使用相对引用的话 ,就可以从一个易于记忆的地方开始计算(bugFix分支或HEAD)

相对引用很给力,下面有两种简单的方法:使用^向上移动1个提交记录
				使用~<num>向上移动多个提交记录   ~4

操作符(^)把这个符号加在引用名称的后面,表示让GIT寻找指定提交记录的父节点
所以main^相当于“main的父节点”    main^^是main的第二个父节点
切换到main的父节点(git   checkout main^)


可以将HEAD作为相对引用的参照。使用HEAD在提交树中向上移动几次,命令如下:
git  checkout c3;   git  checkout HEAD^;   git checkout HEAD^;   git  checkout  HEAD^

“~”操作符     在提交树上移动很多步,引入~    后需跟数字,不跟时和^相同  git  checkout HEAD~4

强制修改分支的位置    相对引用最多的就是移动分支,可以直接使用-f 选项让分支指向另一个提交。(把一个提交移动到另一个提交上)git branch -f bugFix main   /git  branch -f  main  HEAD~3(此命令会将main分支强制指向HEAD的第三级父提交)

撤销变更
撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(便更是通过哪种方式撤销的)组成
撤销变更的方式:git reset git revert
git reset (远程分支无效)通过把分支记录回退几个提交记录来实现撤销改动。向上移动分支,原来指向的提交记录就跟没有提交过一样。
git reset HEAD~1 不知道c2这个提交了
git revert HEAD 在要 撤销的提交记录后面居然多了一个新的提交(c2’),这是因为新提交记录引入了更改—这些更改刚好是用来撤销C2这个提交的。也就是说c2’和c1是相同的。revert之后就可以把你的更改推送到远程仓库与别人分享

整理提交记录
git cherry-pick 将一些提交复制到当前所在的位置(HEAD)下面,最直接。
、 git cherry-pick c2 c4

交互式的rebase
当你知道所要提交记录时(并且知道这些提交记录的 哈希值),用cherry-pick 最简单不过了
若不清楚提交对象的哈希值时,利用交互式的rebase(如果想从一些列的提交记录中找到想要的记录,最好的方法)
交互式的rebase指的是使用带参数的rebase命令(-- interactive) 简写-i 如果在命令后增加了这个选项,git会打开一个UI的界面并列出将要被复制到目标分支的备选提交记录,还会显示每个提交的哈希值和提交说明。

当rebase UI界面时,做三件事:调整提交记录的顺序(鼠标拖放完成)
			删除你不想要的提交(通过切换pick的状态来完成,关闭意味着你不想要这个提交记录)		
			合并提交(允许你把多个提交记录合并成一个)
git rebase -i HEAD~4(在对话框中按你指定的方式进行复制)  使用undo ,reset来修正错误

本地栈式提交
正在解决棘手的bug ,为了便于调试而在代码中添加了一些调试命令并在控制台打印了一些信息,这些调试和打印语句都在他们各自的提交记录中。最后就差把bugFix分支里的工作合并回main分支了。你可以通过fast-forward快速合并到mian分支上,但这样的话main分支就会包含这些调试语句了

git rebase -i
  	git cherry-pick

提交的技巧#1
之前在newImage分支上进行了一次提交,然后有基于它创建了caption 分支,然后又提交了一次。此时你想对某个之前的提交记录进行了一些小小的调整。
通过以下的方法来解决:
先用git rebase -i将提交重新排序,然后把我们想要修改的提交记录挪到最前
再用 git commit --amend来进行一些小修改
然后再用git rebase -i来将他们调回原来的顺序
最后把main移到修改的最前端
目标状态中的那几个‘—我们把这个提交移动了两次,每次都会产生一个‘,而C2上多出来的是使用amend参数提交时产生的。对比结果的时候只会对比提交树的结构,对于‘的数量上的不同,并不对比,只要你的main分支结构和目标结构相同

提交的技巧2
技巧1要进行两次排序,rebase -i 而这有可能造成由rebase而导致的冲突
cherry-pick 可以将提交树上任何地方的提交记录取过来追加到HEAD上在(只要不是head上游的提交)
git cherry-pick c2

git tags
可以永久的将某个特定的提交命名为里程碑,然后可以像分支一样引用了,他们并不会随着新的提交而移动。不能检出到某个标签上面进行修改提交,标识了某个特定位置
git tag v1 c1

git describe
标签在代码库中起着“锚点”的作用,描述最近的锚点(git describe),能在提交历史中移动了多次后找到方向。
git bisect(查找产生bug的提交记录的命令)
git describe的语法:
git describe
可以是任何能被git 识别成提交记录的引用,如果没有指定的话看看,git会以你目前所检出的位置(HEAD)
输出结果:
__g
tag 表示的是离ref最近的标签,numCommits是表示这个ref与tag相差多少个提交记录,hash表示的是你所给定的ref所表示的提交记录哈希值的前几位
当ref提交记录上有某个标签时,则只输出标签名

	git describe main会输出:v1_2_gC2

多分支rebase
希望得到有序的提交历史,也就是最终结果是c6’在c7’上面,c5’在c6’上面(失败用reset重置)
git rebase main side (side分支复制到main下面)

选择父提交记录
该操作符后面的数字与~后面的不同,并不是用来指定向上返回几代,而是指定合并提交记录的某个父提交 git默认选择合并提交的“第一个父提交”,在操作符^后跟一个数字就可改变这一默认行为
这里有有一个和并提交记录,如果不加数字修改符直接检出main ^,会直接回到第一个父提交记录
git checkout main^ main*的HEAD指向上个提交,*消失

git checkout main^2

git  checkout HEAD~^2~2    将HEAD从c7直接移动到c3

远程仓库
、 只是你的仓库在另一台机器上的拷贝,可以通过因特网与这台机器通信,也就是增加或是获取提交记录
特性:
是一个强大的备份,本地仓库也有恢复文件到指定版本的能力,但所有的信息都是保存在本地的。有了远程仓库后,即使丢了本地数据,仍可以通过远程仓库拿到丢失的数据
项目托管,代码社交化

创建远程仓库的命令
git clone 在本地创建一个远程仓库的拷贝(虚线)

远程分支
git clone后本地仓库多了一个o/main的分支,这种类型分支就叫远程分支,拥有一些特殊属性。远程分支反映了远程仓库的状态,远程分支有一个特别的属性,在你检出时自动进入分离HEAD状态。
远程分支命名规则:格式:/ 名为O/main的分支,这个分支叫main,远程仓库名o
大多数开发人员会将主要的远程仓库命名为origin,并不是o。这是因为你用git clone某个仓库时,git已经帮你把远程仓库的名称设置为origin了
当使用git时,远程默认为origin

git fetch
向远程仓库传输数据
从远程仓库获取数据(git fetch)
git fetch完成了什么:
从远程仓库下载本地仓库中缺失的提交记录
更新远程分支指针(如o/main)
git fetch 实际上将本地仓库中的远程分支更新成了远程仓库相应分支最新的状态
git fetch 通常通过互联网(使用 http:// 或 git:// 协议) 与远程仓库通信。
git fetch 并不会改变你本地仓库的状态。它不会更新你的 main 分支,也不会修改你磁盘上的文件
git pull
将变化更新到我们的工作中
当远程分支中有新的提交时,你可以像合并本地分支那样合并远程分支,执行以下命令:
git cherry-pick o/main
git rebase o/main
git merge o/main
git pull(先抓取更新再合并到本地分支)
git pull(相当于git fetch和git merge)

fakeTeamwork 默认操作就是在远程仓库的main分支上做一次提交,完成了远程仓库增加了衣蛾新的提交,我们还没有下载它,因为没有执行git fetch
git fakeTeamwork foo3 模拟队友推送了3个提交记录到远程仓库的foo分支

git push
将你的变更上传到指定的远程仓库,并在远程仓库上合并你的新的提交记录。(发布成果的命令)
注意:git push不带任何参数时的行为与git的一个名为push default的配置有关。它的默认取值取决于你正使用的git的版本,但我们使用的是upstream,推送之前检查一下配置

git pull --rebase是fetch和rebase的简写

远程服务器拒绝(remote rejected)

如果你是在一个大的合作团队中工作, 很可能是main被锁定了, 需要一些Pull Request流程来合并修改。如果你直接提交(commit)到本地main, 然后试图推送(push)修改, 你将会收到这样类似的信息:

! [远程服务器拒绝] main -> main (TF402455: 不允许推送(push)这个分支; 你必须使用pull request来更新这个分支.)
远程服务器拒绝直接推送(push)提交到main, 因为策略配置要求 pull requests 来提交更新.

你应该按照流程,新建一个分支, 推送(push)这个分支并申请pull request,但是你忘记并直接提交给了main.现在你卡住并且无法推送你的更新.

新建一个分支feature, 推送到远程服务器. 然后reset你的main分支和远程服务器保持一致, 否则下次你pull并且他人的提交和你冲突的时候就会有问题.
	
git reset --hard o/main(将main*与o/main向上合并在一起)

合并特性分支
步骤:将特性分支集成到main上---->推送并更新远程分支
git pull --rebase ;git push
执行这两个命令:将我们的工作rebase到远程分支的最新提交记录—>向远程仓库推送我们的工作

为了push新变更到远程仓库,要做的就是包含远程仓库中最新变更。意思是只要你的本地分支包含了远程分支(o/main)中的最新变更就可以了。	         


rebase的优缺点
优点:rebase使你的提交树变得很干净,所有的提交都在一条线上
缺点:rebase修改了提交树的历史
喜欢保留历史使用merge,喜欢树干净使用rebase

远程跟踪分支
远程分支(o/main)与本地分支main关联情况:
pull操作时,提交记录会被先下载到o/main上,之后再合并到本地的main分支。隐含的合并目标由这个关联确定的。

push操作时,我们把工作从main推到远程仓库中的main分支(同时会更新远程分支o/main)。这个推送的目的地也是由这种关系确定的

main和o/main的关联关系就是由“remote tracking”属性决定的。main被设定为跟踪o/main------意味着为main分支指定了推送的目的地及拉取后合并的目标
当克隆仓库的时候,main分支上的这个属性就被设置好了。
当克隆时,git会为远程仓库中的每个分支在本地仓库中创建一个远程分支(o/main)。然后再创建一个跟踪远程仓库中活动分支的本地分支,默认清空下这个本地分支被命名为main



自己指定这个属性
可以任意分支跟踪o/main,然后分支会像main分支一样得到隐含的push目的地以及merge的目标。你可以让任意分支跟踪 o/main, 然后该分支会像 main 分支一样得到隐含的 push 目的地以及 merge 的目标。 这意味着你可以在分支 totallyNotMain 上执行 git push,将工作推送到远程仓库的 main 分支上。

有两种方法设置这个属性,第一种就是通过远程分支检出一个新的分支,执行:
git checkout -b totallyNotMain o/main   就可以创建一个名为totallyNotMain的分支,它跟踪远程分支o/main

git checkout -b foo o/main  ;  git commit ; git push      将一个不叫main的分支上的工作推送到了远程仓库中的main的分支上
另一种设置远程追踪分支的方法就是使用:git branch -u 命令,执行: git branch -u o/main foo  这样foo就跟踪o/main了。如果当前就在foo分支上,还可省略foo:git branch -u o/main



git push   git 是通过当前检出分支的属性来确定远程仓库以及要push的目的地的。
这是未指定参数时的行为,我们可以push指定参数,语法:git push <remote> <place>
git push origin main

把这个命令意思就是:

切到本地仓库中的“main”分支,获取所有的提交,再到远程仓库“origin”中找到“main”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我。

我们通过“place”参数来告诉 Git 提交记录来自于 main, 要推送到远程仓库中的 main。它实际就是要同步的两个仓库的位置。

需要注意的是,因为我们通过指定参数告诉了 Git 所有它需要的信息, 所以它就忽略了我们所检出的分支的属性!
远程分支使用o/开头是因为origin/对于UI来说太长了

要同时为源和目的地指定 <place> 的话,只需要用冒号 : 将二者连起来就可以了:

git push origin <source>:<destination>一旦你指定了独立的来源和目的地,就可以组织出言简意赅的远程操作命令了,source是任何git能识别的位置
	source指远程仓库的位置,destination才是要放置提交的本地仓库的位置
	git push origin foo^:main  git 将foo^解析为一个位置,上传到未被包含到远程仓库里main分支中的提交记录。

git fetch 的参数
git fetch 的参数和 git push 极其相似。他们的概念是相同的,只是方向相反罢了
git fetch origin foo git会到远程仓库的foo分支上,然后获取所有本地不存在的提交,放到本地的o/foo上。

git fetch 不会更新你的本地的非远程分支,只是下载提交记录
如果git fetch没有参数,它会下载所有的提交记录到各个远程分支

Git 有两种关于 的用法是比较诡异的,即你可以在 git push 或 git fetch 时不指定任何 source,方法就是仅保留冒号和 destination 部分,source 部分留空。

git push origin  :foo   通过给push传空值source,成功删除了远程仓库中的foo分支  origin和冒号之间有空格
git fetch origin  :bar    如果fetch空到本地,会在本地创建一个新分支

以下命令在 Git 中是等效的:

git pull origin foo 相当于:

git fetch origin foo; git merge o/foo

还有…

git pull origin bar~1:bugFix 相当于:

git fetch origin bar~1:bugFix; git merge bugFix

看到了? git pull 实际上就是 fetch + merge 的缩写, git pull 唯一关注的是提交最终合并到哪里(也就是为 git fetch 所提供的 destination 参数)

git pull origin bar:foo
git pull origin main:side

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值