前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单的Git常识

简单的Git常识

原创
作者头像
patientCat
发布2022-07-26 15:57:35
3710
发布2022-07-26 15:57:35
举报
文章被收录于专栏:常用工具知识

Git 学习

toc

luke的git手册

Git基本概念图
Git基本概念图

git对象学习

四种对象

blob

<img src="https://i.loli.net/2021/10/14/2VkCxGANThj8XJO.png" style="zoom:50%;" />

  1. 文件名为sha-1算法和内容hash得到的

tree

<img src="https://i.loli.net/2021/10/14/z4QpUq1xCV5nil6.png" style="zoom:50%;" />

  1. tree对象类似目录这么一个概念,主要记录下属的blob和tree对象。
  2. tree本身的文件名也是sha-1的哈希值。
  3. Git 根据某一时刻暂存区(即 index 区域)所表示的状态创建并记录一个对应的树对象,

commit

<img src="https://i.loli.net/2021/10/14/MYxLgJ9h1HCIND2.png" style="zoom:50%;" />

  1. commit记录的是一条commit信息,是和git commit 对应的。
  2. commit链接一个tree对象。
  3. commit有一个parent属性,用来将一个分支串起来。

tag

我们都知道,对一个分支来说。会一直向前走。但是有时候我们在分支上需要一个固定的坐标。就可以使用tag。

当然也可以通过移动Head指针,指向对应的Commit Id,只不过tag做了一个类似alias的功能

一个基本的流程串联

脑子里有颗树

这里是git的最底层原理,用来理解其怎么实现,但最重要的开始理解文章最开始的Git基本概念图。

代码语言:shell
复制
git init
echo "ver1" > file.txt
git add file.txt
git status

Changes to be committed:
new file: file

暂存区新加文件file

代码语言:shell
复制
git commit -m "first commit"

git commit 根据暂存区文件生成一个tree对象,并用commit链接tree对象。

此时的逻辑图是这样的

<img src="https://i.loli.net/2021/10/14/GeOT1YwzP8IApvb.png" style="zoom:50%;" />

代码语言:shell
复制
echo "ver2" >> file
echo "new" > new
git add file
git add new
git commit -m "second commit"

此时的逻辑图是这样的

<img src="https://i.loli.net/2021/10/14/J9IcHVCzDOlQGqL.png" style="zoom:50%;" />

代码语言:shell
复制
git rm new
git commit -m "third commit"

<img src="https://i.loli.net/2021/10/14/ZEUWXaevwFI9JHG.png" style="zoom:50%;" />

获取和创建Git仓库

本地工作流

git add/rm

git status

git commit

git reset

git restore

git add / rm / restore

git add

代码语言:txt
复制
git add <file> 将文件提交到暂存区

一旦文件git add后,就相当于被track了,任何对文件的改动都会被git所记录。

git restore

代码语言:txt
复制
git restore --staged <place> 从HEAD中恢复文件到暂存区

git restore <place> 将文件从暂存区恢复到工作区

git restore --source <branch>:<place> 从其他的commit恢复文件

这里的<place> 可以是file,也可以是正则之类的东西

测验

代码语言:shell
复制
git init
echo "123" > file
git add file
rm file

如何将file恢复。

git restore file

代码语言:shell
复制
git commit -m "ver1"
echo "error" > file
git add file
rm file

如何恢复commit中的file

git restore --staged file git restore file

如何恢复内容是“error”的file

git restore file

git commit / reset

git commit 用来将暂存区的文件提交到本地数据库中。

git commit --ammend

会取消上一次的commit,并合并你暂存区的文件,重新提交一次commit

  1. 主要被用来fix上次commit忘记提交的一些细节。
  2. 仅仅在自己的commit后使用,因为--ammend会撤销上一次的commit。所以对公共的commit使用会影响别人。
代码语言:txt
复制
git reset 用来回退版本

git reset HEAD

git reset --soft <verID>

git reset --mixed <verID> 默认

git reset --hard <verID>



git reset HEAD 默认使用–soft。

reset

reset --soft 本质就是移动了HEAD指针。

git reset HEAD 主要是用来回滚暂存区。

git reset HEAD

重置暂存区,主要用来roll back

代码语言:shell
复制
git init
echo ver1 > file
git add file
git commit -m "ver1"
代码语言:shell
复制
echo ver2 >> file
git add file
代码语言:shell
复制
git reset HEAD

<img src="https://i.loli.net/2021/10/14/ziEJ5tVhlXmC2qD.png" style="zoom:50%;" />

git reset 三种模式
代码语言:shell
复制
echo ver1 > file.txt
git add file.txt
git commit -m "ver1"

echo ver2 >> file.txt
git add file.txt
git commit -m "ver2"

echo ver3 >> file.txt
git add file.txt
git commit -m "ver3"
git reset --soft
代码语言:shell
复制
git reset --soft HEAD^

仅仅移动HEAD指针。workspace和staging area都不受影响。

git reset --mixed
代码语言:shell
复制
git reset --mixed HEAD^ 

HEAD 指针移动,同时暂存区也会被回滚到ver2

git reset --hard

同时会撤销暂存区,workspace,和local repository。是一个非常危险的命令。

cherry-pick 和 git stash

cherry-pick

负责将某个commit-id的commit复制到当前分支上。

git stash

用来保存暂存区和工作区的文件内容

  1. git stash save "save message"。
  2. git stash apply stash@{num} 应用第几个存储。
  3. git stash list 来列举哪些存储。

交互远程仓库

远程分支和本地分支

代码语言:txt
复制
远程分支的本质上也是一个分支。其就是在本机中远程仓库对应分支的映射分支。

远程分支的名字就是 <repo>/<local-branchname>,一般为origin/<local-branchname>。默认的远程仓库名就是origin。

git push

代码语言:txt
复制
git push <remote> <place>



1. 将本地分支的所有commit提交到<remote>/<place>分支下,同时更新远程仓库中的对应分支。



git push <remote> <source>:<dest>

1. 同上,但是将本地分支commit提交到<remote>/<dest>分支下,同时更新远程仓库的<dest>分支。



git push <remote>  :<dest> 可以删除远程分支

git fetch/pull

git fetch

会干俩件事

  • 从远程仓库下载本地仓库中缺失的提交记录。
  • 更新远程分支指针(如 origin/master)。
代码语言:txt
复制
git fetch <repo> <place>

<repo> 远程仓库名

<place> 分支名
代码语言:shell
复制
git fetch

会更新所有分支

代码语言:shell
复制
git fetch origin foo

下载本地foo分支缺失的commit,然后更新origin/foo指针。

git pull

git pull就是在完成git fetch后,会用当前分支merge远程分支。

git merge/rebase

merge

git merge 可以分为两种情况。1. fast forward 2. 三路合并

fast forward

<img src="https://i.loli.net/2021/10/14/qwXf2axEPv4KQ9R.png" style="zoom:50%;" />

当前分支master和目标分支feature没有分叉。则可以直接进行fast forward合并。

<img src="https://i.loli.net/2021/10/14/CrpnOyY5ExPflW7.png" style="zoom:50%;" />

三路合并

<img src="https://i.loli.net/2021/10/14/GrYEejxZps2Nvfb.png" style="zoom:50%;" />

当在master分支,merge feature分支时。

  1. 去寻找common recent accestor,就是M3。如果期间feature分支同步过master,则会cra就会变化。
  2. 比较cra和当前分支diff1,cra和目标分支diff2。
  3. 如果俩个diff在同一位置发生改动,则冲突。否则,保留有改动的一方即可。

<img src="https://i.loli.net/2021/10/14/4QjrApsFaW2iTxX.png" style="zoom:50%;" />

理解了这个原理后,如何快速造一个confict出来。

代码语言:shell
复制
git init
echo "hello" > test.txt
git add test.txt
git commit -m "m1"
git switch -c feature
echo "world" >> test.txt
git commit -am "f1"
git switch master
echo "nihao" >> test.txt
git merge feature

rebase

Reapply commits on top of another base tip 这里的官方解释很明确

合并分支

代码语言:txt
复制
git rebase <upstream> <branch>

1. 如果指定了branch,就会先执行git switch branch,然后执行git rebase
2. 如果没有指定<upstream> ,则默认以本分支的远程分支为upstream
流程
  1. 将本分支所有的commit,但是在upstream里没有的commit保存到临时区。
  2. 将分支指针移动到upstream,然后将临时区的所有commit依次apply。

合并commit

代码语言:txt
复制
git rebase -i <commit-id>
  1. 改变commit顺序
  2. 合并多个commit,
    1. pick:保留该commit
    2. reword:保留该commit,但是要修改commit注释
    3. squash:将该commit和前一个commit合并
    4. drop:不要该commit

常见的使用场景

1. 准备开发feature

一般从master中checkout一个新的分支出来

代码语言:shell
复制
git switch master
git pull master
git switch -c feature/${someone_name}/${feature_name}

2. 准备测试

一般测试时,是合到experiment分支上去的。

重新checkout一个feature的exp分支出来。

代码语言:shell
复制
git switch experiment
git switch -c feature/${someone_name}/${feature_name}_exp
git merge feature/${someone_name}/${feature_name}

这么做的原因是因为万一experiment分支有了Bug代码,但不是你提交的。暂时修改不了,可以让自己的${feature_name}_exp作为测试分支。因为这个分支不会有别人的测试代码。

3. 准备合入master

  1. 合并commit成一个 git rebase -i
  2. git pull origin master 更新master分支
  3. git rebase origin/master ,当前分支rebase master分支
  4. git push origin 自己的分支名

4. git commit --ammend使用(新手不建议使用)

代码语言:shell
复制
git commit -m "commit"
git push origin branch_name

这时候发现有个代码写错了,改动了一番后,想使用

代码语言:shell
复制
git commit --ammend
这时候直接
git push -f origin branch_name

因为commit --ammend会重新生成一个commit id,和远程仓库不一致。

这里不建议新手使用是因为,如果已经把commit1提交到远程仓库,然后通过ammend再去修改,这时候需要push --force,所以只能对自己的分支这么搞,和别人合作时不可以。

犯错时用到的高级特性

  1. git revert 用来消除掉自己的一次commit,所以这里要求自己的commit每次最好是功能完备的。

通过找到一个commit id。

比如说 git revert -i 1e1f61f8125a1706c98a465287a5c22e15a4cc83

学习网站

git 算是日常开发中用到的非常重要的工具。建议熟练掌握。

建议完成里面所有的官卡。基本上就对git非常熟悉了。可以大胆地玩了。

https://learngitbranching.js.org/?locale=zh_CN

参考资料

https://git-scm.com/book/zh/v2

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Git 学习
  • luke的git手册
  • git对象学习
    • 四种对象
      • blob
      • tree
      • commit
      • tag
  • 一个基本的流程串联
    • 脑子里有颗树
    • 获取和创建Git仓库
    • 本地工作流
      • git add / rm / restore
        • git add
        • git restore
        • 测验
      • git commit / reset
        • reset
      • cherry-pick 和 git stash
        • cherry-pick
        • git stash
        • 远程分支和本地分支
    • 交互远程仓库
      • git push
        • git fetch/pull
          • git fetch
          • git pull
        • git merge/rebase
          • merge
          • rebase
          • 合并分支
          • 合并commit
      • 常见的使用场景
        • 1. 准备开发feature
          • 2. 准备测试
            • 3. 准备合入master
            • 4. git commit --ammend使用(新手不建议使用)
          • 犯错时用到的高级特性
          • 学习网站
          • 参考资料
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档