Git的基本使用

项目开发

在项目开发过程中使用git,通常分为以下几种情况。

  • 初始化

    • Maintainer创建仓库
    • 创建主要的几个分支,master(默认就有)、develop
    • 设置分支保护规则
  • 导入现有的项目

  • 开发基本操作

    • 克隆远程仓库
    • 切换到开发分支
    • 提交到本地仓库
    • 推送到远程仓库
    • 发起合并请求
    • 合并其它分支到当前分支
    • 解决冲突

接下来我们将针对以上情况分别给出示例。

git工作区介绍

git区域:

本地库:历史版本

暂存区:临时存储

工作区:写代码的地方

提交流程: ​ 工作区->暂存区->本地库

git文件状态:

在Git中,文件有两种状态:tracked(已跟踪)和untracked(未跟踪)。

Tracked文件是指已被纳入版本控制的文件,这些文件有快照记录,并可能处于不同的状态,如未修改、已修改或已暂存。这些文件是在上次快照中有记录并且在下次要提交的快照(暂缓区)也有记录的文件。

Untracked文件则是指除了已跟踪文件之外的所有文件。这些文件既没有快照记录,也没有被放入暂缓区。通常,新创建的文件或者从其他地方复制过来的文件,如果还没有被Git跟踪,就会处于未跟踪状态。

总的来说,已跟踪文件是那些Git知道其状态的文件,而未跟踪文件则是那些Git尚未开始跟踪其变化的文件。如通常我们使用Idea编辑代码的时候,新建一个文件,就会提示是否要加入到版本控制,如果加入了就是tracked文件,未加入则是untracked跟版本库完全没有关联。

git常用命令

初始化

git init:在当前文件夹中,初始化一个仓库。执行该命令后会生成一个.git的隐藏文件夹。

配置

git config -list:查看所有配置

git的配置分为局部配置和全局配置,区别在于git config 后面是否加上 -gobal参数。

git config 配置项:查看指定配置项,git config -global 配置项,查看配置项在全局中的配置。

git config 配置项 值:设置配置项的值。

常用设置项设置

  • git config --global user.name "用户名" # 设置用户名
  • git config --global user.email "用户邮箱" #设置邮箱
  • git config --global user.name # 查看用户名是否配置成功
  • git config --global user.email # 查看邮箱是否配置

本地文件操作

git add 文件名:将当前工作区的文件存入暂存区。

  • git add 文件名 将工作区的某个文件添加到暂存区
  • git add . 将当前工作区的所有文件都加入暂存区
  • git add -u 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件
  • git add -A 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件

git commit -m '-fix:xxx':将暂存区的文件,提交到本地仓库,该操作首先要执行git add将文件进行版本追踪后才能提交到本地仓库,如果要直接将新文件(untracked)提交到本地仓库,需要增加一个-a参数,如git commit -a -m "提交说明"

git stash:将暂存区的代码进行存储,这个命令在分支之间切换非常有用。它会将你本地的所有tracked文件进行保存下来,以便切换到其他任务或分支,并在稍后恢复之前的状态。

场景:当我们遇到个突发情况,比如让你去看下生产master分支的问题,但是你本地开发到一半,不好提交。这个时候直接切换到master是会报错的,因为本地工作区将恢复到master分支的代码,现在你开发到一半的会被删除,git是不允许你这样做的。这时候我们就可以先将本地代码add到暂存区,然后通过git statsh保存起来。

操作步骤:

  • git add .
  • git stash save "xxx"
  • git checkout master
  • git stash apply

常用参数:

git stash:直接保存存储区的数据

git stash save "备注的内容" # 保存当前未 commit 的代码并添加备注 git stash list # 列出 stash 的所有记录 git stash clear # 删除 stash 的所有记录 git stash apply # 应用最近一次的 stash git stash pop # 应用最近一次的 stash ,随后删除该记录 git stash drop # 删除最近的一次 stash

多条git stash记录:

$ git stash list stash@{0}: WIP on ... stash@{1}: WIP on ... stash@{2}: On ...

应用到其中一条:git stash apply stash@{1}

远程仓库操作

git clone 远程仓库地址:将远程仓库克隆到本地。

git remote add origin 远程仓库地址:将本地仓库和远程仓库相关联。默认使用clone后会自动生成origin地址信息,不用特殊设置。

附带操作:

  • git remote set-url origin <新的远程Git仓库地址>:修改远程仓库地址,通常用于远程仓库迁移了或者ip地址变了。
  • git remote -v:查看远程仓库信息。
  • git remote rm origin:删除关联信息。

git pull origin 分支名称:从远程仓库拉取最新的分支代码,并自动合并到本地工作区,能够直接在文件中看到变化。

git fetch origin 分支名称:git fetch是将数据拉取到本地仓库,它并不会自动合并或修改当前的工作。在进行检查后再决定是否合并到本地工作区。

将远程仓库代码合并到本地仓库:git merge origin/master。这个比git pull更加细粒度。

查看提交记录:git log origin/master

查看文件内容:git show

查看详情:git show --stat

git push origin 分支名称:提交本地仓库的代码到远程仓库。这里和svn的不同的是,提交到远程的文件取决于你本地仓库的文件变更,而不能像svn一样,一次只提交指定的一两个文件。

-f:加了-f参数后将强推本地仓库到远程仓库,这个挺有用的。当本地发生过提交的回撤(被本地回撤的递交已经被推送到远程仓库),需要使用-f这个强制参数,否则不会成功。强制推送可能会覆盖远程仓库中的更改,因此在使用时需要谨慎。

以上是git远程仓库的常用操作命令,指的一提的是git的远程仓库跟svn差别很大,从开发的角度来说git的远程仓库只用于协作和记录保存属于一个存储、同步用的,它与本地关系是一个关联关系,即使没有远程仓库,一个人依旧能够使用版本管理工具。而SVN的远程仓库,它在存储和同步的基础上还要负责版本管理、日志记录、甚至于合并等功能。

日志

git log:查看所有的commit记录。

git log -p -记录条数:查看指定条数最近的commit记录。

git log --pretty=oneline:只显示版本号和提交信息

git reflog:这个能够看到你的所有提交记录,包括其commit、reset、checkout等记录。

这个在我们版本回退后,要反悔非常重要,比如我们执行了git reset HEAD^回退到了上个版本,此时再看版本树是没有回退之前的记录了,这时候就可以使用git reflog来查看,然后进行回退。

版本回退

git reset HEAD^: 恢复成上次提交的版本。

git reset HEAD^^: 恢复成上上次提交的版本,就是多个^,以此类推或用~次数。

git reset --hard 版本号:用于版本回退到指定的版本,会直接将所有都恢复到指定版本。

--hard:修改HEAD指针指向,暂存区内容丢失,工作区恢复以前状态;这是用得最多的情况,就是回退到某个指定版本。

--mixed:修改HEAD指针指向,暂存区内容丢失,工作区不变;该参数是git reset的默认参数也就是说git reset命令后面不加任何参数,就是这个效果。它的作用就是,当我们文件进行了git add操作后,想要反悔,不将本次add操作commit,就可以使用这种方式清空暂存区。

--soft:只是改变HEAD指针指向,缓存区和工作区不变;它的作用在于mixed重置了暂存区,而使用这个参数它将会重置本地仓库commit记录到指定版本,一般用于撤销已经commit的记录,比如你是新来的写完代码已经commit到本地仓库,上传到远程仓库了,这时候Leader告诉你commit的注释内容有严格格式要求不能胡写,这时候就可以使用git reset -soft回退commit记录,然后通过git commit -amend修改commit信息,再次提交即可。

分支操作

git branch :查看本地分支。

git branch -a :查看本地和远程分支。

git branch 分支名:创建一个分支,基于当前分支。

git checkout 分支名:切换到一个分支。

git branch -b 分支名:创建一个分支,并自动切换到新建的分支。

git branch -b 新分支名 已存在的分支:基于已经存在的分支创建一个新分支,并自动切换到新分支上。

在git中分支操作非常常用,比svn要频繁得多

分支合并

git rebase 分支名称:变基合并,将当前分支变更追加到指定分支后面。

git rebase --continue,在解决冲突后继续合并。

git rebase -i:可以进入交互式模式,在这个模式下可以执行批量操作,调整commit顺序等。

git merge 分支名称:将指定分支合并到当前分支,如果出现冲突,会生成一条合并记录。

--no-ff:禁止快速合并参数,加了该参数后使用merge合并一定会产生一条合并记录。通常在合并请求处理的时候合并可以这个参数。

它俩的区别:

rebase:会导致当前分支变基到目标分支上,合并后的commit提交记录,不是原始的commit提交记录。

merge:是属于直接合并的,如果有冲突或者加了参数--no-ff后会产生一个合并记录。

通常来说,要求可追溯则使用merge它能够显示出当前分支是基于什么分支checkout出来的,要求线性合并就可以采用rebase,rebase后是无法追溯的因为它们都被合成一个分支树,但是它不会有多余的枝丫。在我们通常就采用merge,这样也方便看追溯,分支太多的时候,会进行修剪操作。

不推荐在公共分支上使用rebase合并,因为这样会将非公共分支的提交记录全部复制到公共分支上,使用merge产生一个merge记录更好。

文件比较

git diff 工作区与暂存区的差异

git diff 分支名 工作区与某分支的差异,远程分支这样写:remotes/origin/分支名

git diff HEAD 工作区与HEAD指针指向的内容差异

git diff 提交id 文件路径 工作区某文件当前版本与历史版本的差异

git diff --stage 工作区文件与上次提交的差异(1.6 版本前用 --cached)

git diff 版本TAG 查看从某个版本后都改动内容

git diff 分支A 分支B 比较从分支A和分支B的差异(也支持比较两个TAG)

git diff 分支A...分支B 比较两分支在分开后各自的改动

实际操作

初始化

操作人员:组长|主程序员

新建仓库的时候,可以有两种方式创建,一种是直接在gitlab网页端进行创建,还有就是采用git init在本地创建,然后通过git remote add 进行远程关联,并提交到远程仓库中。

网页端创建项目:

本地创建项目:

git init git add . git commit -m '-chore init' git remote add origin [email protected]:帐号名/仓库名.git git pull origin master git push origin master # -f 强推

git clone [email protected]:git帐号名/仓库名.git

创建核心分支:

创建develop分支: git checkout -b develop master 该操作后会自动切换到develop分支

提交到远程仓库中,便于组员合并:git push origin develop

操作后在远程仓库就可以看到这个分支

设置核心分支为受保护的

简单开发流程

拉取已存在项目

每个成员都拉取项目

git clone http://192.168.x.x:9080/example/example-git.git

设置局部账号:

git config user.name "xxxx" git config user.email "[email protected]"

#完成配置后可以用git config --list 去查看

git config user.name

为了方便不同用户的提交,设置一下git config credential.helper ""每次远程pull、push操作都输入账号密码。

创建开发分支

开发成员拉取项目:git clone http://x.x.x.x:9080/example/example-git.git ,此时开发人员拉取项目默认是master分支,无法往远程仓库中提交的,需要创建自己的开发分支。

开发成员创建开发分支:

查看所有分支:git branch -a

可以看到主分支master以及开发分支develop,还有组长自己创建的开发分支feature/GroupLeader

此时我们开发人员刚来的时候需要从develop开发分支上创建

切换到开发分支git checkout develop

创建自己的开发分支git checkout -b feature/zhangsan

此时就可以愉快的写代码了。

提交开发分支到远程仓库

将修改文件添加到暂存区:git add .

将暂存区的文件提交到本地仓库:git commit -m "-feat:xxx模块新增xxx功能。"

推送到远程仓库: git push origin feature/zhangsan

此时远程仓库中就有了zhangsan的分支,并且还有zhangsan提交的代码。

提交代码合并请求到develop分支

1、开发人员自己写的代码合并到develop分支上,需要首先切换到develop分支,切换到develop分支:git checkout develop

注意切换前一定要保证工作区的代码都已经提交到了本地仓库或者放入了暂存区,如果没有提交切换分支将会报错。

提交到本地仓库:git add . git commit -m "xx"

将工作区放入暂存区:git stash。todo:git stash的用法

之所以有这个限制是防止数据丢失,因为分支的切换会改变本地文件内容,如果没有这个限制的话就会导致工作区的文件被覆盖,导致数据丢失;还有一点隐含的作用就是提醒你这个分支的任务完成了吗就要切换到其它分支,更加便于分支的管理,防止你合并一些半吊子文件进去。

2、拉取develop最新的代码: git pull origin develop

在开发这段时间内,可能会有其它开发人员往这个分支上提交代码,因此每次合并分支前一定要先拉取该分支最新的代码。

3、切换回本地分支:git checkout feature/zhangsan

4、将develop分支最新代码通过变基(rebase)的方式合并到feature/zhangsan分支:git rebase develop

ps:如果确定develop分支没有变化以上四步不用操作

5、将feature/zhangsan推送到远程远程仓库中git push origin feature/zhangsan

6、在gitlab提起合并请求

ps:如果当前用户具有对develop分支提交合并的权限比如组长,他自己写完代码后最好还是通过流程提起合并请求进行合并,指派给自己即可。

处理合并请求

当待处理的合并请求时,在网页端可以看到合并请求的信息。

随便点进去一个,可以看到具体的合并请求详情

如果登录用户是指派的处理人的,可以查看到处理合并的按钮以及处理方式"命令行"。

如果登录用户不是指派的处理人,则只能看到请求信息,没有处理权限

接受合并
线上合并

处理合并有两种,一种是在网页端,直接点击合并按钮,这种适用于对代码有底的情况,直接在网页上合并。

线下合并

如果摸不定,需要验证测试的最好还是在本地进行合并后提交,具体操作方式,可以点击命令行查看具体操作方式。

下载远程最新的代码到本地:git fetch origin:用于从远程仓库(origin)获取最新的更新。这个命令不会自动合并到当前分支,而是将远程仓库的更新下载到本地,以便你可以查看和合并这些更改。

本地创建zhangsan分支,用于合并:git checkout -b feature/zhangsan origin/feature/zhangsan

切换到develop分支:git checkout develop。一般切换后再拉一下,最新的代码git pull origin develop

执行合并:可以用rebase合并,也可以用merge合并。处理合并请求一般最好还是用merge方式进行合并git merge --no-ff feature/zhangsan

执行完合并后推送到远程仓库:git push origin develop

ps:通过上面两种合并后,在界面上可以看到具体结果,以及操作过程。

拒绝合并

当组长不合并这个请求的时候可以选择将这个合并请求关闭,并对此做出讨论,等待张三修改后重新提交。

此时开发成员zhangsan需要根据组长意见进行修改代码再次提交分支合并,由组长处理新的合并请求。

预生产(测试环境)版本发布

这个操作通常由组长即Maintainer操作的,有的在开发到上线这个阶段有两个环境,一个是测试环境,一个是预生产环境。

测试环境,主要就是让内部测试人员进行测试,对数据真实性要求不高,数据价值也不高。

预生产环境,在上线前使用一部分真实数据来进行测试,对通过了测试环境的软件进一步测试,保证可靠性,有时候也会拿这一部分来做临时灰度发布的场景。

组长对release分支进行操作,首先需要对release分支进行设置保护,不能有开发人员进行干扰(也可以不设置,具体看测试要求,这里主要是演示一下使用通配符配置保护分支)。

我们可以对分支使用通配符匹配的方式对分支进行保护,因为这个分支是需要暴露出去的,所以可能会维护多个版本,并且是需要长久保存的,从这个分支开始就需要注重版本号管理了。

创建预发布分支
  • 预发布分支是基于develop分支创建的
  • 先保证develop分支是最新的代码git pull origin develop
  • 创建release分支git checkout -b release/1.0.1 develop
  • 提交到远程仓库git push origin release/1.0.1

此时可以通知测试人员对分支进行部署测试了。

预发布分支bug修改

在预发布环境下的软件要经历测试小姐姐的不断蹂躏,因此大多数软件的小身板是扛不住的,被测试小姐姐玩坏后是需要修复的,这就进入了修改bug阶段(bugfix)。

这就需要创建bugfix分支,这个分支有的团队是直接从develop分支基础上创建,有的在整个测试阶段都是基于release分支创建的。我们团队确定了版本后,进入测试-发布阶段了,这段时间的代码都是基于release创建的,因为develop分支可能此时已经进入了下一个版本功能的迭代了。

拉取最新的远程分支和代码git pull origin

创建bugfix分支git checkout -b bugfix/1632 origin/release/1.0.1;bugfix/后面的数字通常为测试提交bug的编号,有的用禅道就是禅道的编号。

修复bug后提交到远程仓库

在远程仓库上发起合并请求,由小组长进行合并到release/1.0.1分支中,通知测试继续测试,如果没有自动化部署是需要再部署的;并且在合并的时候一般来说这种分支合并后就给其删除了。

版本发布

测试通过后,我们就需要将release进行发布,将release代码合并到master分支和develop分支上,master分支永远保持着和生产环境相同的代码,合并到develop上是为了将测试阶段修改的代码合回去,继续开发。

这一步的操作也完全由组长来操作,因为这三个分支的合并只有组长有权限。

同样的操作再对develop分支执行一次。

git工具:一般用Idea或者VSCode插件已经很好用了,如果要用工具的话可以考虑:TortoiseGit小乌龟(免费,跟SVN小乌龟一样,用惯了小乌龟的可以使用这个)、GitKraken(付费,但是好用)。

相关推荐
bubiyoushang8885 小时前
解决 Git 访问 GitHub 时的 SSL 错误
git·github·ssl
海码00710 小时前
【版本控制】Git 和 GitHub 入门教程
git·github
网硕互联的小客服13 小时前
503 Service Unavailable:服务器暂时无法处理请求,可能是超载或维护中如何处理?
服务器·git·github
abcnull14 小时前
github开源协议选择
git·github·开源协议
安庆平.Я17 小时前
git互联GitHub 使用教程
git·github
自来也_1 天前
Git配置代理
git
Jooolin2 天前
【编程史】Git是如何诞生的?这可并非计划之中...
linux·git·ai编程
Lw老王要学习2 天前
VScode 使用 git 提交数据到指定库的完整指南
windows·git·vscode
去旅行、在路上2 天前
Git & Svn
git·svn
abcnull2 天前
github中main与master,master无法合并到main
git·github