Git详细使用指南(含详细命令、实操)

举报
长路 发表于 2022/11/28 19:23:05 2022/11/28
【摘要】 文章目录前言相关网站一、初始Git配置2.1、设置修改、查看用户名及邮箱2.2、生成与查看SSH key2.3、Github、Gitee配置SSH keyGithubGitee二、基本常识2.1、认识工作区与暂存区三、常用快捷命令配置与帮助版本库操作查看日志记录分支远程仓库抓取与拉取查看远程仓库关联远程仓库重命名远程仓库与移除推送远程仓库标签版本回退变基(git rebase)基础变基交互式变基(

@[toc]

前言

建议刚开始学习的话可以去看一些入门视屏教程,先学一下git基本的操作能将本地项目推送到远程仓库就可以。平时使用的话尽可能多练练命令,多去搞清其中的原理,实践出真理嘛,还有就是多去官网看教程,英文看不懂可以看中文的,官网才是最详细最标准的,我这段时间重新巩固学习git就是去的官网,我下面相关网站也列出来了。

所有博客文章目录索引:博客目录索引(持续更新)

认识Git

git是项目管理工具,github(国外的)、gitee(国内的)是公网上的项目托管平台,一般公司内部直接使用gitlab(自己搭的服务器独立使用,在私网里)。

  • 通过远程仓库来统一管理我们的代码,利于合作协同开发。

多人开发:多个人一般在项目托管平台克隆一份到本地,接着设分支来进行自己单个模块开发,任务完成推送到项目托管平台,在项目托管平台最终进行合并。

  • 大致流程:以后上线的功能合并到master分支(归项目经理管)上;dev分支(托管日常的代码,一般都是拉dev分支进行多人开发,多人开发之后先合并到dev分支上,若是项目功能大致完成测试通过最终再合并到master分支上);若是项目规模大,还有一个release分支(测试分支,交由测试人员进行测试,拉的是dev分支,测试通过再合并到master分支上)。


相关网站

官网

教程文档

Git图形界面工具(多种):https://git-scm.com/downloads/guis 比较帅的图形界面:https://www.gitkraken.com/

服务器上搭建Git:服务器上搭建Git

Gitee的Git文档(包含所有有关git的工具、插件、说明文档等):Gitee常用命令


学习视频

【git和gitee】理论与实战讲解



一、初始Git配置

2.1、设置修改、查看用户名及邮箱

Git下载好之后,首先应当配置用户名及邮箱

设置或修改本地Git工具的用户名及邮箱:

  • git config --global user.name "xxxxxx":设置用户名。
  • git config --global user.email "xxxxxx":设置邮箱。

查看用户名及邮箱:

  • git config user.name:查看用户名。
  • git config user.email:查看邮箱。


2.2、生成与查看SSH key

生成SSH key

首先打开git bush来输入下面命令:

  • ssh-keygen -t rsa -C <“邮箱”>:参数为指定邮箱,一般设置你配置的邮箱,可进行覆盖

image-20210322155723766


查看SSH key:之后连接到Gitee或Github都需要使用该密钥

方式一(直接输入命令):cat ~/.ssh/id_rsa.pub

方式二(本地手动查看):默认在C盘的用户目录下,我的路径是C:\Users\93997\.ssh

image-20210322155944976



2.3、Github、Gitee配置SSH key

Github

①登陆Github,之后进入setting,选择SSH and GPG keys,点击New SSH key新增密钥:

image-20210322160228675

②添加title与key(之前生成的SSH key)

QQ截图20200818174546.jpg

点击Add SSH key即可!

测试通信:ssh -T git@github.com,出现以下信息表示通信成功!

image-20210322161625152



Gitee

GiteeGithub设置大致相同同样也是添加SSH公钥即可!同样也是输入标题与公钥即可!

image.png

测试Gitee通信:ssh -T git@gitee.com

image-20210322161909340



2.4、快速克隆与连接远程仓库

语法git clone http://username:password@gitlab.com/test.git

示例

changlu/123456
如:原本连接地址  http://192.168.1.2244:8040/test/test-ui.git
=》 http://changlu:123456@192.168.1.2244:8040/test/test-ui.git


二、基本常识

2.1、认识工作区与暂存区

在Git中包含三个区域分别是:工作区暂存区历史记录区。与其他版本控制系统不同地方有暂存区概念,并且暂存区与历史记录区被统一划分在版本库中。

三个区域对应三种状态如下

  • 工作区(working directry):包含.git的目录称为从工作区。—已修改
  • 暂存区(stage index):使用git add命令提交指定文件暂存的区域(属于版本库)。—已暂存
  • 历史记录区(history):使用git commit命令将暂存区中的文件提交到历史记录区(属于版本库)。查看日志记录只会记录每次commit操作!—已提交

  • 该图可以看到指定add、commit命令存放的位置!


三、常用快捷命令

配置与帮助

检查配置信息:

  • git config --list:列出所有Git当前找到的配置,如用户名、密码、过滤属性值等等。(可能会看到重复的变量名,因为会从不同的文件中读取同一个配置)
  • git config <key>:检查Git某一项配置。例如查看用户名:git config user.name

获取帮助:

  • git help <verb>git <verb> --help:获取指定命令的帮助,跳转指定页面包含详细介绍。
  • git <verb> -h:-h为help简写,在cmd中获取到帮助描述。


版本库操作

git init:在指定目录创建一个.git的子目录,也就是该目录下创建了一个git仓库用来管理。

git clone <url>克隆指定的仓库。

git status:检查当前文件状态,会有较详细的信息描述。

  • git status -sgit status --short:缩短状态命令输出,简洁查看信息。若无任何信息说明暂时没有所需提交文件。
    • ?? file1:在工作区,表示该文件还未添加到暂存区。
    • A file2:在暂存区,表示该文件还未提交到版本库。

添加到暂存区

git add <filename>:添加指定文件到暂存区。

git add .:添加所有修改文件到暂存区。

情况1:若是你是用git add添加一个文件到暂存区了,接着你对该文件进行修改,之后使用git commit提交,注意了提交的是之前添加到暂存区的版本而不是你之后修改的!!!想要提交新的你还得重新git add接着git comit

提交到版本库

git commit -m "描述信息" :将暂存区的提交到版本库,并且会提示哪个分支提交的,多少文件修订、多少行添加和删改过。

git commit -a -m "描述信息":添加-a选项,可自动将所有跟踪文件暂存起来并提交,跳过git add步骤。

  • 包含所有修改过的文件,注意有时该选项会将不需要的文件添加到提交中。
  • 注意:只针对于修改文件可以直接跳过git add,对于新创建的文件还是需要使用git add的!

git commit --amend -m [message]:如果代码没有任何新变化,则用来改写上一次commit提交信息

git commit --amend [file1] [file2] ...:重做上一次commit,并包括指定文件的新变化。


比较命令

git diff:比较工作目录中当前文件和暂存区域快照之间的差异。

git diff --stagedgit diff --cached:比较暂存区与版本区最后一次提交的文件差异。


移动文件

git mv <file_from> <file_to>:重命名文件,改名放入暂存区。查看状态会显示重命名操作。

  • 使用git mv相当于执行三条语句如下:

  • $ mv README.md README
    $ git rm README.md
    $ git add README
    

删除操作

格式:git rm [-r | -f | --cached]

  • -r:覆盖最新检查。
  • -f:递归删除文件目录。
  • --cached:从索引中删除路径,工作区保留。(简单说就是在最新提交中删除指定文件索引,原本工作目录保留)

小例子

  • git rm -r <filename>:删除工作区中的指定文件,注意并不会删除索引,所以还是需要进行提交操作。
  • git rm -r --cached <filename>:删除最新提交中的指定索引。
  • git rm -r --cached *:删除最新提交的所有索引(需要提交)。

查看日志记录

git log:列出所有提交情况,最近更新的在最上面,列出内容为每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。

git log -pgit log --patch:可显示每次提交所引入的差异(用于代码审查),并且可限制日志条数数量,如再添加-2参数表示最近两次提交。

git log --stat:快速浏览某个提交变化,只显示简略信息。

定制默认格式来展示提交历史:选项--pretty

  • git log --pretty=oneline:在一行中显示日志信息,仅包含哈希值以及提交信息。

  • git log --pretty=short:非一行,包含哈希值、作者auther、提交信息。

  • git log --pretty=full:非一行,包含哈希值、作者auther、提交者commit、提交信息。

  • git log --pretty=fuller:非一行,包含哈希值、作者auther、作者日期、提交者commit、提交日期、提交信息。

  • git log --pretty=format:"%h - %an, %ar : %s"(建议!!!):定制记录显示格式。常用选项如下:

    • 选项 说明
      %H 提交的完整哈希值
      %h 提交的简写哈希值
      %T 树的完整哈希值
      %t 树的简写哈希值
      %P 父提交的完整哈希值
      %p 父提交的简写哈希值
      %an 作者名字
      %ae 作者的电子邮件地址
      %ad 作者修订日期(可以用 --date=选项 来定制格式)
      %ar 作者修订日期,按多久以前的方式显示
      %cn 提交者的名字
      %ce 提交者的电子邮件地址
      %cd 提交日期
      %cr 提交日期(距今多长时间)
      %s 提交说明

作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。

git log --pretty=format:"%cd %h %s" --graph:添加选项--graph能够展示形象展示分支、合并历史,包含提交的时间。

  • 时间样式修改:Mon Oct 20 17:26:23 2014 => 2014-10-21 14:55:24 +0800。需要你进行配置:git config log.date iso-strict-local。全局设置为:git config --global log.date iso-strict-local

image-20210717093354008



分支

查看:当前使用的分支前有*号

git branch:查看所有本地分支,信息有分支名(简略信息)。

git branch -v:查看所有本地分支,信息有分支名、哈希值、最新的操作说明及相关文件名。

git branch -r:查看所有的远程分支。

git branch -a:列出所有本地分支和远程分支

创建:创建了分支之后默认保存master最新的版本及操作。

git branch <branchName>:创建指定名称的分支。

切换分支:文件中的内容会进行改变,即为对应切换分支的内容!!!

注意:在切换分支时最好将工作区以及暂存区的中的修改了但未提交了的进行提交。

git checkout <branchName>:切换指定名称的分支,并更新工作区。

git checkout -b <branchName>:直接创建并切换到该分支。

  • 实际使用了两条命令:git branch <branchName>git checkout <branchName>

删除分支

git branch -b <branchName>:删除指定的分支。

合并分支:一般都是master合并其他分支,首先需要切换到master主分支,接着合并其他分支

git merge <mergeBranchName>:合并其他分支,合并之后会切换到目标合并分支。

  • 一般合并好之后当前分支是在目标分支上的,合并之后目标分支已经没有用了(解决问题了),之后我们切换到主分支,接着删除该目标分支即可!!!

说明:合并分支出现的冲突问题见下面4.1部分!!!



远程仓库

抓取与拉取

url:指的是对应仓库的ssh地址或url地址;remoteName:表示关联仓库名称。

git clone <url>:默认只有一个本地分支为master以及包含所有远程分支。若只是通过git branch -v只能查看到本地分支,想要切换其他远程分支进行开发,直接git checkout <远程分支名>命令切换即可!

  • git clone -b <分支名> <url>:克隆指定远程仓库的指定分支。例如:git clone -b dev git@gitee.com:changluJava/exer.git

git pull [remote] [branch]:取回远程仓库的变化,并与本地分支合并。使用git pull默认更新当前分支,自动合并操作。

  • 简单来说就是根据远程仓库来更新指定分支内容!

git fetch <remote>:下载远程仓库的所有变动(所有分支),但是不会自动合并。

  • 使用git fetch命令之后,接着使用git merge进行合并。

说明:推荐使用git pull来进行更新指定分支内容!git fetch并不常用。



查看远程仓库

git remote -v:查看该仓库所有的关联仓库名称、远程仓库地址。

git remote showgit remote:仅仅获取远程仓库的remote名称。

git remote show <remote>:查看某一个远程仓库信息,例如git remote show origin,即可查看origin远程仓库的URL、跟踪分支的信息(告诉你处于的分支)



关联远程仓库

git remote add 名称标识 ssh地址:添加一个关联远程库。



重命名远程仓库与移除

重命名:

  • git remote rename <remoteOld> <remoteNew>:修改一个远程仓库名称。这样也会修改所有远程跟踪的分支名称。举例:git remote rename origin github ,修改仓库名后,对应分支名称也会随之改变,原本origin/master会改变为github/master。
    • 可事先使用查看关联仓库之后选定修改:git remote -vgit remote

移除:

  • git remote rm <remote>:删除指定的远程仓库,包含这个仓库所有的相关远程跟踪分支及配置信息。


推送远程仓库

remote指的是关联仓库名称、branch为对应关联仓库的分支

git push <remote> <branch>(常用):将指定branch分支推送到指定remote服务器上。

git push [remote] --force:强行推送当前分支到远程仓库,即使有冲突。

git push [remote] --all:推送所有分支到远程仓库

git push -u <remote> <branch>:添加-u选项,记住推送的远程仓库及指定分支。

  • 记住之后直接使用git push即可推送到指定远程仓库及分支。


标签

查看标签

git tag:以字母顺序列出所有列表标签。

git tag -l <通配符序列>git tag --list <通配符序列>:按照特定模式查找标签,例如git tag -l "v1.8.5*",查看所有1.8.5系列的标签。

git show <v.版本>:查看指定标签的信息。

  • 对于轻量标签:仅有提交信息(提交哈希值、作者邮箱、日期),无额外的标签信息(下面图片信息没有)。
  • 对于附注标签:查看标签信息和对应的提交信息(打标签者的信息、打标签的日期时间、附注信息及具体的提交信息)。

image-20210322144134291


创建标签:轻量标签与附注标签

轻量标签(临时打标签建议使用):只是某个特定提交的引用。只是将提交检验和存储到一个文件,没有保存任何其他信息。

  • git tag <v.版本>:最近提交的指定分支打上轻量标签。例如:git tag v1.0-lw

附注标签(建议使用):存储在 Git 数据库中的一个完整对象,可被校验,包含打标签者的名字、电子邮件地址、日期时间及标签信息( 可使用GNU Privacy Guard (GPG)签名并验证)。

  • git tag -a <v.版本> -m <msg>:指定-a选项表示附注标签,-m后表示标签描述。

后期打标签:之前多次提交都没有打标签,想给之前某次提交打上标签。

首先使用git log --pretty=oneline命令查看所有的提交日志,包含对应提交的哈希值如下:

image-20210322144634443

git tag -a <v.版本> <某次提交哈希值>:给指定提交记录打上标签(附注标签)即可。


推送标签:即共享标签,默认情况下你使用git push并不会把打上的标签传送到远程服务器上,可理解为对于标签需要额外使用命令上传。

git push <remote> <tagname>:将指定标签推送到远程仓库中去。例如:git push origin v1.5

git push <remote> --tags:将会把所有不在远程仓库服务器上的标签全部传送到指定关联的远程仓库中。


删除标签:删除本地标签与删除远程仓库的标签需要使用不同命令,轻量、附注标签都可删。

删除本地仓库标签:

  • git tag -d <tagname>:在本地删除指定标签,远程仓库并不会删除该标签的。示例:git tag -d v0.6-lw

删除远程仓库标签:

  • 方式一(较复杂): git push <remote> :refs/tags/<tagname>:将冒号前面的空值推送到远程标签名,从而高效地删除指定标签。示例:git push origin :refs/tags/v1.0-lw
  • 方式二(直观):git push origin --delete <tagname>:比较容易看懂。示例:git push origin --delete v1.0

检出标签:若是想要修复某个标签下的项目bug(旧版本错误检测),那么首先需要找到对应标签的提交记录(即该提交的哈希值)。

前提说明:使用的check out <tagname>来查看指定标签对应的提交记录(找到哈希值)。

问题描述:使用该命令会让你的仓库处于分离头指针状态,此时不会指向任意分支,也就是说在该状态下你提交的任何东西不属于任何分支并且无法访问,除非通过确切的提交哈希来访问(不过这也没有意义的)。

较好解决方案:创建一个新分支在该分支上进行检出标签获取到对应标签的提交哈希,接着切回原来的master主分支即可!!!

  1. 创建并切换分支:git checkout -b findTagHash
  2. 检出标签:git checkout v1.0
    • image-20210322152525027
    • 此时头指针处于分离状态也就是之前提出的问题:
      • image-20210322152623461
  3. 切回主分支master,并删除findTagHash分支:git checkout mastergit branch -d findTagHash

后话:拿到哈希值之后我们可以进行版本回退到原来分支将以前的标签删除掉并且进行修改bug,正式提交好之后打上原先的标签版本,最后推送到远程仓库再发布版本就OK了!



版本回退

注意了回退版本并不是删除了最新的版本,仅仅只是回退!

回退一个版本:HEAD~,回退上上版本:HEAD~~~表示回退版本的个数,若是回退到第100个:HEAD~100

git reset:重置暂存区的文件与某次提交(commit)保持一致,工作区文件内容保持不变。(主要用于提交有误时进行悔步,工作区与暂存区保持不变,可进行重新提交)。

git reset --hard:重置暂存区与工作区与指定commit保持一致。

方式一(根据指定数量回退):

  • git reset --hard <指定回退哪个版本>:回退指定数量版本,例如回退一个版本git reset --hard HEAD~

方式二(根据提交哈希回退):建议先使用git log --pretty=oneline来查看所有提交记录其中包含哈希值

  • git reset --hard <提交哈希>:通过哈希值来进行回退,哈希值只需要部分即可。

说明:使用提交哈希还可以回到未来版本,意思就是我可以回到过去也可以回到将来只需要有该提交哈希即可。

注意注意(重点):若是你回到过去了想要回到以前的最新的版本,单单使用git log --pretty=oneline是查看不到之前最新的版本的,只能查看到当前回退时的最高版本;想要查看所有的记录包含以前最新的使用git reflog命令查看获取到提交哈希!!!



变基(git rebase)

基础变基

我们在碰到下面多个分支情况时,一般使用git merge来进行合并,如下:

image-20210324213817142

image-20210324213933410

当我们使用变基时,上面1图experiment会自动合并到master的同一级,使用如下命令就会有下面的效果:

$ git checkout experiment
$ git rebase master

image-20210324214004380

  • 通过变基我们可以看到在历史记录中就不会出现合并的图像。

接着返回master分支再进行快速合并:

$ git checkout master
$ git merge experiment

image-20210324214933912



交互式变基(合并提交)

git rebase -i :进行交互式变基。

本案例演示多个提交合并为一个提交

方式一:使用两个提交值来指定范围:git rebase -i <早的提交值> <晚的提交值>

首先看下历史提交记录:

image-20210324220633039

$ git rebase -i ba802 d42290  # 实际上范围(ba802,d42290]

image-20210324220852808

将两次的合并消息更改为一次的合并消息:

image-20210324221141179

关闭了之后表示修改完成,提示信息如下:

image-20210324221255642

最终我们查看下历史提交记录:

image-20210324221441632


方式二:通过使用head~或者head~2来进行指定合并的部分

$ git rebase -i head~2  # 表示将最近的2个进行合并,经历的步骤与上面大致相同!

额外说明(针对于上面修改为s以及其他介绍):一般使用s,与上一次提交合并

p,pick:直接使用该次提交
r,reword:使用该次提交,但重新编辑提交信息 (修改编辑信息)
e,edit:停止到该次提交,通过`git commit --amend`追加提交,完毕之后不要忘记使用`git rebase --continue`完成这此rebase
s,squash,压缩提交,将和上一次提交合并为一个提交
x,exec,运行命令
d,drop,移除这次提交
  • 修改成不同字符包含其他不同的功能效果,例如改为r则是编辑修改commit(git rebase -i head~或根据指定的提交值)提交信息…


四、实际场景

4.1、本地创建分支来解决多个问题

无冲突问题(完整实例)

实验背景:仅有一个master,并且只提交一次。

案例学习网站(Git官网):Git分支简介

建议:在整个学习过程中建议多使用git branch -v来查看当前所在的分支。

第一次master提交状态如下:

image-20210322111622591

此时有人告知你项目出现了一个问题(issue22)需要你解决,此时我们创建一个分支来进行解决。

接着创建一个分支issue22并切换:git checkout -b issue22

修改了一半bug(已经提交到版本库)。

image-20210322111724980

  • 此时当前分支为issue22,内容与当前master分支是一样的,我们现在基于issue22分支来进行修改bug操作。

突然项目有一个紧急问题issue500出现,需要赶紧修复,此时issue22还没有解决,所以我们需要切回master分支,并且重新基于master分支创建一个issue500分支。

  • 切换回master分支:git checkout master
  • 基于master分支来创建issue500分支:git checkout -b issue500

切换之后我们进行改bug,待问题解决之后进行了commit提交,此时状态如下:

image-20210322111813842

此时我们需要做的是将issue500分支合并到master主分支上,所以我们现在需要切回master分支之后合并issue500分支。

  • 切回master分支:git checkout master

    +合并issue500分支(确保被合并分支已经提交):git merge issue500

image-20210322110410639

image-20210322111421630

合并之后我们可以看到上面的master实际上就是指向issue500分支上,此时我们不需要该分支了,则可以删除issue500分支:

  • 删除issue500分支:git branch -d issue500

image-20210322111522801

OK,到目前为止紧急问题解决并且合并分支结束,此时我们需要回到原本的issue22分支去解决对应问题:

  • 切换到issue22分支:git checkout issue22

切换之后并解决isuue22中的问题进行commit:

image-20210322112127532

接着我们又是将issue22分支合并到master主分支上去了,切换master分支并合并issue22分支:

  • 切换master分支:git checkout master
  • 合并issue22分支:git merge issue22

需要注意的是:现在的master所在分支提交并不是issue22分支所在提交的直接祖先,可以看到前面岔开了,对于这种情况Git会使用C3、C4所指的快照与他们的共同祖先C1做一个简单的合并操作

image-20210322112931851

  • 该合并使用到三个快照:和之前将分支指针向前推进所不同的是,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。 这个被称作一次合并提交,它的特别之处在于他有不止一个父提交。

此时已经解决好问题了,issue22分支我们不再需要了可以直接删除该分支:git branch -d issue22,此时状态如下:

image-20210322113219982

OK至此,通过使用分支完美解决问题!不过忽略了一个情况就是在进行不同分支合并时如上合并mater与issue22时,可能会出现合并冲突的情况(即是因为两个分支都修改了同一个代码文件的同一部分内容)。详细看下面的合并冲突解决。



合并冲突解决(连上)

image-20210322112127532

我们重新回到合并master与issue22状态,此时已经切换回master分支,进行合并issue22分支:

image-20210322113701638

  • 此时 Git 做了合并,但是没有自动地创建一个新的合并提交。 Git 会暂停下来,等待你去解决合并产生的冲突。

出现上面情况描述merge failed表示合并失败,这种情况就是出现了合并冲突,其实际上已经进行了合并,只不过并没有进行创建新的合并提交!

当前情况如下:只是并没有提交操作

image-20210322114000690

我们可以使用git status来查看当前状态:

image-20210322114236114

解决过程:通过手动解决

打开合并失败的文件,我们可以看到在指定部分出现了<<<与>>>的符号,上面的是master主分支描述,下面的是待合并的分支描述

image-20210322114338137

我们只需要将这部分内容替换为你想要合并的结果如下:

image-20210322114459196

仅仅手动解决冲突问题还不够,我们需要使用git add命令来标记为冲突已解决。一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决

  • 暂存有冲突文件:git add test.txt

暂存好之后表示冲突解决,但是我们实际上此时还没有进行本次的合并提交,我们可以使用git status来查看描述:

image-20210322114907877

既然如此我们来进行本次合并操作的提交:git commit -m "解决master与issue22的合并冲突问题"

说明:此时我们已经完美解决合并冲突的情况!!!

image-20210322133411375

额外说明:完成合并操作后,issue22分支实际上还是存在的,我们不再需要该分支,使用命令删除:git branch -d issue22即可。

我们还可以通过使用查看日志命令进行查看提交信息:git log --pretty=format:"%h %s" --graph

image-20210322133532764

  • 和我们之前自己画的图大致相同!


4.2、模拟多人协同开发

前提准备

①准备2个账号。②指定仓库包含两个分支(masterdev)。

测试目的

  • ①邀请成员开发,设置master为保护分支(只供管理者使用)。
  • ②测试多人对同一个分支dev进行开发,在git本地进行合并之后push到远程仓库的dev
  • ③第二个开发者推送时出现合并异常情况,需要在本地先进行合并提交。
  • ④普通开发者无法push到远程仓库master

两个分支:master(主)、dev(开发)

image-20210323161627978

  • 开发者都在dev分支中进行开发,最终也都是提交的dev分支。
  • master是主分支一般作为最终发布版本,通常是项目经理来将测试好的dev合并到master上。这里暂时还没有设置为保护分支。

master分支及dev分支所包含内容:

  • image-20210323165613559
  • image-20210323170315775
    • dev分支是通过管理者创建分支dev之后push到远程仓库。(建议这种方式)

设置master为保护分支

打开所有分支,选择保护分支:

image-20210323162534125

设置好之后为如下效果:

image-20210323162626573

仓库选择管理,其中可查看保护分支,默认推送、合并只能是仓库管理员,我们也可以在这个保护分支设置中设置其他分支的规则:

image-20210323162737945


邀请开发者协同开发

​ 长路:管理员

​ coldercl:开发者

管理—开发者—添加仓库成员,点击邀请成员:

image-20210323162040139

三种方式都可以,这里选择直接添加,我们发出邀请请求,被邀请用户需要进行同意:

image-20210323162148009

同意加入过后,我们即可查看到开发者信息:

image-20210323162423874



协同开发过程

设置两个文件夹分别来作为多位开发者:

image-20210323222512965

前提说明codercl长路账号预先同时克隆一份项目(版本1)。

注意:使用不同账号推送分支到远程仓库时记得删除凭证手动输入账号登陆。

image-20210323221526810

codercl(开发者)开发dev分支

$ git clone https://gitee.com/changluJava/exer.git  # 克隆项目下来(版本1)
$ cd exer/ 
$ git checkout dev  # 首先切换到dev分支(开发分支)
$ git checkout -b "version1"  # 通过dev分支来创建分支version1进行开发
# 这里作为开发操作过程
$ touch codercl.txt
$ git add .
$ git commit -m "version1 commit"  # version1分支提交(完成开发)
# 切换回dev分支,合并version1分支
$ git checkout dev  
$ git merge version1
# 开发完之后version1分支就不需要使用了,直接删除即可!
$ git branch -d version1
# 推送本地的dev分支到远程仓库(记得删除windows凭证,手动登陆(coldercl的账号))
$ git push origin dev

image-20210323221940143

image-20210323221810330

  • 此时为版本2。

长路(管理者、开发者)开发dev分支

$ git clone https://gitee.com/changluJava/exer.git # 该操作是之前版本1的时候克隆下来的(处于版本1)
$ cd exer/
$ git checkout dev  # 切换为dev分支(开发分支)
$ git checkout -b version2 # 在dev开发分支基础上创建一个分支version2并且切换,在该分支上进行开发
# 进行开发操作
$ touch version2.txt
$ git add .
$ git commit -m "version2 commit"  # 开发完成提交到version2分支
# 切换为dev分支来合并version2分支(此时合并是ok的!)
$ git checkout dev
$ git merge version2
# 将dev开发分支提交到远程仓库 (注意需要清除windows凭证,手动输入账号密码登陆(长路的账号))
$ git push origin dev

此时我们可以看到push操作出现了失败:

image-20210323223542562

由于之前coldercl开发者已经在此提交前提交了一次了(version2),此时远程仓库dev分支的版本(version2)与coldercl开发者初始克隆下来的版本(version1)不一致,所以导致推送失败,需要你先进行git pull将最新dev分支内容合并到本地dev分支。

$ git pull  # 拉取远程仓库上的dev最新分支合并到本地

image-20210323223945525

  • 需要说明的是有时候会出现合并冲突问题,你需要在本地进行解决与上面4.1中合并冲突解决相似,记住合并冲突解决是在本地进行操作的,合并解决了之后重新推送到远程仓库的dev分支!
# 本次演示并没有合并冲突的情况,所以我们直接推送即可
$ git push origin dev  # 将合并好之后的分支推送到远程仓库的dev分支

image-20210323224149511

image-20210323224250891


开发者完成之后(即多人协作完成后),项目经理完成masterdev的合并操作!

这里长路就是管理者,我们就将其看做是项目经理,进行以下操作:

$ git clone https://gitee.com/changluJava/exer.git
$ cd exer/
# 默认克隆下的本地分支仅有master,依旧包含远程分支master、dev
# 这里我们直接切换dev分支即可添加远程分支dev到本地分支中去,并且切换过去
$ git checkout dev
# 此时有了本地分支dev(开发者的分支),接着就开始合并dev分支到master
$ git checkout master
$ git merge dev
# 将合并后的分支推送到远程仓库
$ git push origin master  # 修改windows凭证(改为长路的账号)

image-20210323231623587

  • 这是执行完git checkout dev之后进行查看本地分支,此时该dev分支指向的是远程分支dev(开发者分支)。千万不要创建分支名称为dev,不然该分支是基于master创建的分支!!!

image-20210323231756883

  • 我们使用长路(管理者)账号才能够进行master分支的推送(如上),否则仅仅使用开发者账号推送会报错:
    • image-20210323231927963

OK,我们合并分支操作也已经完成了!我们查看一下远程仓库有没有进行合并操作:

image-20210323232024358



总结

1、多人协同开发时,最好设置多个分支,例如master(主)、dev(开发分支),将master分支设置为保护分支,开发者仅能够提交dev分支。

2、开发者克隆远程仓库文件到本地后,首先切换到dev分支,接着创建并切换到新的分支来进行开发,开发完成之后将其开发分支合并到dev分支上,接着推送到远程仓库的dev分支中。(尽量多git pull将最新的代码先拉下合并到dev分支)

3、管理员合并dev分支到master分支,同样也是先克隆一份到本地目录,直接切换dev分支(远程dev分支),接着切换回master分支,对dev进行合并,最终提交到远程仓库的master分支即可(尽量只可管理员操作)。



4.3、多团队开发

前提描述

多团队开发与之前的多人协同开发最大的不同是,多团队开发并没有被仓库管理者邀请为开发者,而是通过fork项目开发之后向原项目者进行pull request来达到多团队开发的效果。

一般来说对于masterdev分支都会设置保护分支只需要相应权限的人才能够推送分支到远程仓库:

image-20210324093301149

  • 一般dev分支的可推送代码成员是开发者。

接着其他团队想要参与到你的项目,为你的项目做贡献,此时该项目的两个分支仅仅只能够开发者进行推送分支,那么其他团队怎么来和你一起完善这个项目呢?

  • 这就需要先fork该项目到自己的仓库中(与fork的项目一致),此时你可以克隆在你账号下的这个项目来进行开发,最终合并分支推送到这个fork的项目仓库中(仅仅只会推送到在自己账号的fork项目中),接着你向原仓库发起pull request(合并分支请求),等待原仓库管理者测试审核通过,就能够合并分支啦!

OK,接下来我们来实操一下进行多团队协作开发。



协作过程

原仓库账号:长路,项目exer

其他团队账号:coldercl(非exer的开发者)

首先登陆coldercl账号,找到指定长路的exer项目,点击fork

image-20210324094417161

image-20210324094616809


①codercl对fork项目进行开发发出pull request(合并请求到原仓库)

image-20210324094733863

  • fork之后的项目相当于复制拷贝了一份目标仓库到自己的本地,原本两个分支也不再是保护分支,你可以对其进行任意推送操作(仅仅是对在自己仓库的下fork项目,并不会推送到原仓库)。

接下来就模拟一下开发操作:

$ git clone https://gitee.com/codercl/exer.git # 克隆fork的项目到本地
$ cd exer/
# 进行开发并提交,最终push到远程仓库中
$ touch dev.txt
$ git add .
$ git commit -m "codercl发现了一个重大bug"
$ git push origin master

image-20210324095353657

接下来就是发出pull request(合并请求)到原仓库:

image-20210324095504002

image-20210324095735600

②回到长路账号确定测试、审查通过

image-20210324143927679

你可以选择直接自动合并也可以进行手动合并,这里直接进行合并分支(左边提示没有冲突):

image-20210324144105215

  • 若是有冲突的话可进行手动合并(可见左边具体操作步骤),一般是长路管理员将原仓库克隆下来,之后切换为master分支,接着使用git pull命令将codercl账号的master分支拉下来到本地master分支下接着在本地解决冲突最终上传到远程仓库上。

点击接受Pull Request,完成合并!

image-20210324144453404

image-20210324144623714

说明:完成之后之后协助账号以及原仓库都会显示在pull request中指定合并请求记录会显示已合并!!!



4.4、提出Issue

在每个人的仓库中都包含了Issues,意思是提出问题或者说是提出开发任务。

①在自己仓库中新建issue,你可以指派任务、设置负责人,对于Issue的标签设置包含不同类型,管理者可以通过发布Issue来让开发者知晓下一步的开发任务(会有提示)或者修正bug等。

image-20210324205907339

②非开发者成员也可以对该项目提出Issue,可以看到仅仅只有标题和正文可供填写,大多用于提出相应的问题告知开发者吧。

image-20210324210443082



五、忽略文件

5.1、.gitignore文件设置

在有.git的目录下创建.gitignore文件即可!

目的:将一些文件不纳入到git管理,不希望它们总出现在未跟踪文件列表,这类文件一般是日志文件、临时文件、编译产生的中间文件、工具自动生成的文件等等。

使用说明:在.gitignore文件中输入指定需要过滤的文件名称即可,添加即可生效不会被追踪管理。

  • 注意:若是已经提交的文件,在.gitignore文件中设置也没有用!

格式规范

  1. 空行、#开头的会被git忽略,相当于注释。
  2. 可使用glob模式来进行匹配相应文件。

glog模式介绍:也就是简化了的shell命令

  • "*":星号匹配零个或多个任意字符
  • []:匹配任何一个列在方括号中的字符,如[ab]匹配a或者匹配b
  • "?":问号匹配一个任意字符
  • [n-m]:匹配所有在这两个字符范围内的字符,如[0-9]表示匹配所有0到9的数字

忽略指定文件目录下的:

#忽略指定文件目录下的
/addons/*
#不忽略指定文件目录下的
!/addons/wuji_*

Java开发通用模板

#java
*.class

#package file
*.war
*.ear
*.zip
*.tar.gz
*.rar
#maven ignore
target/
build/

#eclipse ignore
.settings/
.project
.classpatch

#Intellij idea
.idea/
/idea/
*.ipr
*.iml
*.iws

# temp file
*.log
*.cache
*.diff
*.patch
*.tmp

# system ignore
.DS_Store
Thumbs.db

实际案例

案例描述:原本的项目没有设置.gitignore文件,一些没有必要的文件都交给了git管理,现在我想忽略掉指定提交的文件!

解决方案:简单粗暴方式

git rm -r --cached .   # 删除最新提交索引中所有内容(历史提交区删除,工作区不删除) 
git add .              # 将现有文件全部提交暂存区
git commit -m "忽略文件" # 提交文件

建议:若只是想要将提交中的一部分忽略掉,实际上只需要git rm -f --cached <filename>命令将指定文件从索引中删除即可,若是原本项目中没有.gitignore,建议也将.gitignore进行提交。


参考资料

[1]. git官网文档 建议看官方文档,内容比较完善

[2]. Git 三大区域的操作分析

[3]. git的三个区域与.git目录解析【图文经典版】 介绍.git文件目录中的内容

[4]. .gitignore文件 详细介绍了.gitignore中的设置

[5]. 关于github:为什么不git clone克隆所有分支? 说明git clone默认只有一个本地分支master的原因

[6]. git reset 命令 菜鸟教程中的git reset的相关操作

[7]. [Git] Git整理(四) git rebase 的使用 介绍了git rebase的详细说明,包含交互式变基的不同参数介绍及案例

[8]. 修改git log默认的时间显示方式

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。