Git学习下

本文详细介绍Git的分支创建、合并、冲突解决及标签管理,包括fast-forward模式、rebase操作、远程仓库协作流程,以及如何在多人环境中有效管理代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Git学习下

分支创建与合并

  平时版本库的分支如下
在这里插入图片描述
  每次提交后git commit,分支在时间轴上就会变长,每一个节点就是一个版本,HEAD指针指向当前版本。
在这里插入图片描述
  新建分支就是新建一个指针,指向当前master提交处,可以切换HEAD指针到dev分支上进行修改。(新建分支其实就是新建了一个指针,所以执行速度非常快,工作区文件无任何变化)
git checkout -b dev //新建分支并切换到该分支
可以用下面两句替换:
git branch dev //新建dev分支
git checkout dev //切换到dev分支(深层动作:HEAD指针指示到dev)
可以用:
git branch来查看当前处于哪个分支
在这里插入图片描述
  在dev分支上改动并提交时(commit),时间轴上的版本仍然在变长,但master指针不动,dev分支指针跟踪
在这里插入图片描述
如果想把改动合并到master分支上,先切换到master分支:
git checkout master //HEAD指针重新指示master,如下
在这里插入图片描述
  在dev分支上完成了改动,想要合并(merge)到master分支上,其实就是master指针指向dev处(fast forward模式),所以就是指针变化,速度很快。git的版本控制更像是一条链表,链表的每个节点存储着每次提交(commit)后的版本。
git merge dev //合并分支dev
在这里插入图片描述
合并完后可以把dev分支删除,其实就是把dev指针删除。
git branch -d dev
在这里插入图片描述
在多人协作中,如果出现分支合并的冲突时,需要他们协作商量着改。

解决冲突

场景如下:
  我们新建一个分支feature1,在该分支上改动readme文件并add/commit后,时间轴上增加一个节点并存储改动。我们切换到master分支上也改动readme文件并add/commit后,时间轴上也增加一个节点来存储改动。
git checkout -b feature1
改动readme
git add readme.txt
git commit -m “modify in feature1”
//之后再切换回master,改动readme
git checkout master
改动readme
git add readme.txt
git commit -m “modify in master” //分支生长如下图
在这里插入图片描述
  不同分支上有不同提交时,链表会变成这样。开发分支最后还是要合并到主分支上,但这时合并git会报错冲突,这时就需要人为的协商来解决冲突。
git merge feature1 //合并会提示冲突
也可以
git status //这也可以告诉我们冲突文件
在这里插入图片描述
  之后我们就需要打开冲突文件,协商着解决冲突。用notepad++打开冲突文件,发现git将每个分支上做的改动写入了冲突文件,并用<<<===>>>来划分不同分支做的改动,方便进行对比来消除冲突,这一点git还是挺人性化的。当然文件也可以用cat/vi readme.txt等命令来打开查看。
在这里插入图片描述
  修改完冲突文件后,不要git merge(合并会提示出错)了,直接在master上提交就行了,因为在master分支上已经将冲突文件改正了,所以直接提交即可。
git add readme.txt //加入暂存区
git commit -m “conflict solve” //直接提交就完事
在这里插入图片描述
  合并(merge)发生冲突时处在图中h处,这时修改冲突文件后直接提交即可,commit后则处在图中head/master处,而开发分支feature1还可以自由发展,发展到一定程度还可以merge到主分支master上,也可以删掉该开发分支。
git branch -d feature1 //删除feature1分支
git log --graph --pretty=oneline --abbrev-commit //可查看提交日志

分支管理策略

  在dev分支上开发完后要合并到master分支上,如果是git merge dev,其默认情况下是fast forward模式进行合并,就是前面提到的合并模式,直接将master指针指示到dev指针处。
在这里插入图片描述
  这种模式虽然速度快,但删除分支dev后,会丢掉分支信息,有时要关闭fast forward模式来进行分支合并:
git merge --no-ff -m "merge with no-ff" dev
–no-ff参数:表示禁用fast forward
本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去,如下图
在这里插入图片描述
  不禁用FF模式,则master指针指向dev处,禁用FF模式后并commit则新生成一个节点存储,删除dev分支(其实是dev指针),则不会丢失分支信息。
实际开发中:

  • Master分支是稳定的,用于软件版本发布,不用来开发
  • Dev分支不稳定,用来开发,开发完一个版本后再merge到master上,在master上发布
  • 所有小伙伴都在dev分支上干活,每个人都有自己的分支,时不时将工作merge到dev上
    在这里插入图片描述
      类似树状结构,每个人是叶子,将各自工作merge到父辈,父辈功能开发差不多时merge到master上发布。在dev分支下,每个开发者都有其下的开发分支,每个开发者在开发之前要git pull拉取dev上最新代码,之后开发完再合并分支,这样就没有冲突,两个人要是修改的是同一个位置,就需要协商解决冲突。

Bug分支

场景如下:
  你在dev分支上进行开发,但已经发布的软件出现了紧急bug,由于发布的版本是在master分支上,所以你需要切换到master分支上改正bug(一般需要在master上新建一个分支修改bug后合并到master分支上),但dev分支上你手头的工作不能马上整完,所以你还不能commit,这时你需要保留现场:
git stash //将当前分支工作压入栈保存
注:
  git status 查看当前分支下是否有未被git追踪的文件(Untracked files:从未被add过的文件),如果有的话需要先git add,不然在改完bug无法commit。
  另外,改完某部分后git add,但没有git commit(即时间轴上为增加一个节点),再切换回master上后发现dev上的改动,在master上是存在的,如果dev中git add后,使用git stash后,切换回master分支后,dev上的改变就不会在master中存在。
当bug修复后,切回dev分支
git status //则发现工作区为空的
因为其进行的工作被压入栈中
git stash list //查看栈中的工作
git stash apply//恢复工作,但栈中内容不删除
git stash drop //用其删除栈中内容
前俩个命令可整合成一句
git stash pop //将栈中工作出栈还原并删除栈中内容(常用)
也可以用list中的标号来还原特定的工作区
git stash apply stash@{0}

Feature分支

在dev分支上做了改动,切换到master分支上打算要合并dev分支,但还没合并,上级说该功能不要了而且要销毁:
git branch -d dev //提示dev没有被合并报错,删除会丢失信息(soft)
git branch -D dev //强制删除(hard)
//相当于白忙活了一场

多人协作(需要用远程仓库)

git remote //查看远程仓库的信息,一般显示仓库名称origin
git remote -v //显示更详细
推送到远程仓库:
git push origin ***(master或其他的分支)
如推到origin仓库的master或dev分支上

  • master分支一般时刻与远程同步
  • dev分支是开发分支,所以成员都在其上工作,所以也要与远程同步

抓取远程仓库分支 :
git clone ***(SSH) //从远程仓库clone下来
git branch //一般只会有master分支,只把master分支抓取到了本地
但想要更改项目的dev分支,所以需要将远程dev分支也抓取下来:
git checkout -b dev origin/dev //将远程dev分支创建到本地
开发完功能后推到远程仓库的dev分支
git push origin dev
你的小伙伴已经更改了远程仓库的dev分支,若你也要更改dev分支
git push origin dev //会推送失败
git pull //把最新的提交抓取下来在本地合并,解决冲突
pull也失败了(提示no tracking information),因为没指定本地dev分支与远程的origin/dev分支,设置这俩个链接
git branch --set-upstream-to=origin/dev dev
git pull一下
git push
  push时可能有些文件有冲突,再按之前的方法协商修改。多人协作就这些步骤,一旦熟悉就非常简单。

Rebase

  rebase操作可以把本地未push的分叉提交历史整理成直线

标签管理

创建标签:
  标签是打在最新的commit上的,标签是指向commit的死指针,分支是指向commit的活指针,

git tag v1.0// 打标签
git tag //显示所有标签(按字母顺序显示)
git show v1.0 //显示标签的详细信息
git tag v0.9 ***(commit id)//可以给某一次提交打标签
git tag -a v0.1 -m "version 0.1 released" 1094adb

-a:打标签
-m:说明文字
1094adb: commit id

操作标签:

git tag -d v0.1   //标签打错了,删除标签(本地标签)
git push origin v1.0  //推送该标签到远程仓库
git push origin --tagsv //一次性推送全部标签

如果要删除远程仓库的标签就稍微麻烦点(分两步):

  • git tag -d v0.9 //先删除本地的标签
  • git push origin :refs/tags/v0.9 //删除远程仓库标签,命令还是用push

使用GitHub

  先fork一个开源项目到自己GitHub下,然后再git clone到本地进行开发,开发完后往自己GitHub中推送(push),如果你希望你做的修改让这个开源项目接受,你可以在GitHub上发起pull request请求,别人接不接受就不一定了。
在这里插入图片描述

  • 可任意fork项目
  • fork到自己的GitHub上有读写权限
  • 点击pull request可以贡献自己的代码

  另外,一个本地仓库和远程仓库关联后,本地的推送都会推到这个远程仓库中,如果要关联另外一个远程仓库,则会报错fatal: remote origin already exists
git remote -v //查看远程仓库信息
git remote rm origin //先将远程仓库删除
  之后再关联另一个远程仓库即可。当然也可以关联俩个远程仓库(但每个远程仓库名字都不能用origin)
在这里插入图片描述
实际应用中,经常关联多个远程仓库,一般为:

  • 自己的GitHub仓库
  • 公司的远程仓库

自定义git

配置别名:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
  这个命令变态的长,起别名进行简化变为git lg这些全局(global)配置(config)都存储在主目录(在C盘某个地方C:\Users\dell-pc).gitconfig文件下,打开在alias下即可进行修改,或者不用运行上面命令,直接在config文件里添加别名,另外不想用别名时在config文件里删除即可。
  在仓库下.git里也有个config文件(.git/config),这个配置文件是局部配置(local),仅对该仓库有作用,主目录下的.gitconfig文件是对全部git仓库有作用。

忽略特殊文件

  创建.gitignore文件

搭建git服务器

  但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓库使用。需要用Linux系统机器(Ubuntu或Debian)搭建git服务器。

Reference

https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001375840038939c291467cc7c747b1810aab2fb8863508000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值