Git使用规范(Android版)

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

引言

本文根据Git分支管理策略,结合Git Flow分支管理实践,制定了这个适合Android开发中的Git版本管理规范。同时结合实际操作演示了使用示例,希望对你有所帮助。


1. 各分支简介

下面分支中提到的的 version 应该替换为具体的版本,name 应该替换为具体的开发人员姓名,content 应该替换为需要优化的地方。

master分支


git的默认分⽀,主分支,不轻易改动,上面的代码为生产环境的最新发布版本。在新版本发布后,将新版本代码合并到该分支,并在该分支上打 tag 标签。

分支来源命名规则命名示例合并目标应用环境
生产

develop分支


通常创建git项⽬目的同时就创建 develop ,是开发人员⽤的主要分支,以 master 为分⽀来源。其最新代码代表着开发⼈员为下一个发布版本提交的最新代码。不能代表最新的特性代码,也不代表正在发布的版本代码。

分支来源命名规则命名示例合并目标应用环境
master--release-version开发


feature分⽀


feature 分支,即新功能分支(有时也称之为特性分支),主要被用于即将开发的或更长期的功 能开发。它有可能被合并到 develop 分支或者被废弃掉。

分支来源命名规则命名示例合并目标应用环境
developfeature-versionfeature-1.0.0develop开发


release分⽀


release 分支专供测试使用,允许我们在发布前,做最后⼀点点改动,比如元数据(如版本信息、编译参数等)的修改等。

分支来源命名规则命名示例合并目标应用环境
develop
release-fix-version
fix-version
release-versionrelease-1.0.0develop
master
测试


release-fix分⽀

release-fix分支用于解决测试人员对release代码分支提出的BUG。

分支来源命名规则命名示例合并目标应用环境
releaserelease-fix-versionrelease-fix-1.0.0release测试


fix分支

fix分支用于解决生产环境发现的BUG。标准的该分支一般命名为hotfixes,Android版中为了区分热修复而重命名。

分支来源命名规则命名示例合并目标应用环境
masterfix-versionfix-1.0.0release测试


refactor分支

refactor分支用户重构和优化代码,区别于修改 fix 分支,refactor分支不一定会在下一个版本中上线,而 fix分支一定会在下一个版本中上线。

分支来源命名规则命名示例合并目标应用环境
developrefactor-contentrefactor-layoutdevelop开发


各分支关系图

以经典的Git 流程图为例,适用于所有开发。

2. 提交规范

feat: 新功能(feature)

fix: 修复bug

docs: 文档(documentation)

style: 格式(不影响代运行的变动)

refactor: 重构(既不是新增功能,也不是修改bug的变动)

test: 增加测试

chore: 构建过程、辅助工具、编辑器配置的变动

示例:

  1. fix(首页):修复缓存异常
  2. feat(用户):新增修改用户头像的功能


3. 使用示例

根据需要整理了一个适用于Android团队的Git流程图,如下图所示:

3.1 创建项目

创建 master 分支,然后基于 master 创建出 develop 分支。

3.2 新功能开发

  1. 基于 develop 分支,创建 feature-version 分支,如果开发人员少,可以都在 feature-version分支上进行开发。如果开发人员比较多,基于feature-version 分支继续创建每个人的单独开发分支,命名如 feature-version-name。
  2. 完成开发。
  3. 联调代码,完成自测。
  4. 如果有多个 feature 分支,将其全部合并到 feature 分支,然后拉取 develop 分支的代码到 feature分支,解决可能存在的冲突,然后提交 MR 到 develop 分支,删除 feature 分支。剩下操作参照[11.3.3 测试新功能)](#11.3.3 测试新功能)。           

补充说明:feature-version 分支上开发时 在单独的开发分支上可以commit和push代码进行同步代码,只是在该迭代开发完成后才进行合并代码(MR)到develop,此时没有push权限,只能请求合并权限(MR),MR在gitlab中操作。

3.3 测试新功能

  1. 检查 MR 到 develop 上的代码,确认后,同意 MR。
  2. 在 develop 分支上创建 release-version 。
  3. 检查 MR 到 release-version 上的代码,确认后,同意 MR,修改应用 versionCode 和 versionName,在 release-version 上打测试环境的安装包,提交给测试人员进行测试。
  4. 如果测试人员发现BUG,基于 release-version 分支创建 release-fix-version分支,修复BUG,修复完成后,提交MR 到 release-version,删除 release-fix-version分支。
  5. 重复进行步骤3、4,直到测试通过。

3.4 发布新功能

  1. 基于 release-version 分支打正式包,提交到应用市场。
  2. 提交 MR 到 master 分支,同意后,在 master 分支上打 对应版本的 tag。
  3. 提交 MR 到 develop 分支。
  4. 删除 release-version 分支。

3.5 修复线上BUG

  1. 定位到 BUG 产生的地方,基于 master 分支 创建 fix-version 分支修复 BUG,这里的 version 为 BUG 产生的分支。
  2. 修复完成后,提交 MR 到 release-version 上。
  3. 检查 MR 到 release-version 上的代码,确认后,同意 MR,在 release-version 上打测试环境的安装包,提交给测试人员进行测试。
  4. 如果测试人员发现BUG,基于 release-version 分支创建 release-fix-version分支,修复BUG,修复完成后,提交MR 到 release-version,删除 release-fix-version分支。
  5. 重复进行步骤3、4,直到测试通过。
  6. 如果 BUG 十分严重,需要马上发版,则修改应用 versionCode 和 versionName,剩下操作参照[11.3.4 发布新功能)](#11.3.4 发布新功能)。如果不严重,则提交 MR 到 develop 分支。

3.6重构代码

  1. 基于 develop 分支,创建 refactor-content 分支。
  2. 完成优化。
  3. 测试优化。
  4. 提交 MR 到 develop 分支。

4. 代码评审

在两个及两个以上开发人员的项目中,应该进行代码评审,检查代码风格和是否有潜在的BUG。

MR时需要做简易Code Review,项目发布后做详细Code Review 之后在重构分支上合并,此分支测试后手于Master合并,测试风险控制)

5.Android studio提交规范

git commit --amend  //提交后会与最后一次提交进行合并生成一个新的提交,之前的提交会被废弃掉。

修改的文件已被git commit,但想再次修改不再产生新的Commit.

git commit --amend -m"说明"

目的:如果你仍然有文件没有提交,想追加到最后这个commit上的话,用上述命令,可以保持commit提交历史的干净性。

扩展:合并 commit 保持分支干净整洁

Android Studio中 在更新代码(pull)时,

Update type:

  • Merge:更新时执行合并操作。等价于执行git fetch && git merge或者git pull --no-rebase。
  • Rebase:更新时执行rebase操作。等价于执行git fetch && git rebase或者git pull --rebase。
  • Branch Default:在.git/config文件中指定不同分支的更新类型。

注:不能选择"Rebase",只能选择 “Merge”或Branch Default。因为Rebase(变基)除了了给你带来看上去简洁的历史记录,只会让你的⼯工作变得更更加困难且更更容易易犯错,因为它会擦掉分⽀支的提交历史,并且提交记录并⾮非按时间有序显示。

  • clean working tree before update: 选择默认选项:Using Stash
  • Using Stash:使用git stash储藏本地修改。
  • Using Shelve:使用IDEA内置的Shelve功能储藏本地修改。

通常选择Merge和Using Stash即可,单击OK后,IDEA执行步骤如下:

  • 第1步:使用git stash储藏本地修改
  • 第2步:执行git fetch && git merge拉取远程分支并合并
  • 第3步:执行git stash pop恢复储藏

代码更新及提交规范小结:先执行Pull拉取服务器最新代码,更新时选择“Merge”和“Using Stash”,最后Commit和push到相应分支。

如果先创建本地提交,然后在执行更新操作,这样会导致Git自动生成一个合并提交,导致提交历史不够简洁。

扩展:Git如何在不提交当前分支的情况下切换到其它分支进行操作

  • 储存当前分支的修改

       git stash

  • 查看储存的修改信息

       git stash list

  • 恢复stash的修改

方法一:

git stash apply
//但是恢复后,stash内容并不删除,
这时候再执行git stash list 命令,id 为xxx的储藏项目还会在列表中,你需要用git stash drop 来删除;

注意: 如果有一个分支上多个 stash,如果需要恢复指定的 stash ,可以在命令尾部加id,如git stash apply stash@{0},同样删除指定 stash 项目则执行如 git stash drop stash@{1} 。

方法二:

git stash pop

该命令恢复的同时把 stash 存储列表的内容也删了。这时候再执行git stash list 命令,id 为xxx 的储藏项目不会在列表中。

延伸:

--------------恢复&删除

git checkout -- readme.txt    回复工作区

git checkout .   #本地所有修改的、没有提交的,都恢复到原来的状态

git reset --hard HASH #返回到某个节点,不保留修改。
git reset --soft HASH #返回到某个节点。保留修改

git reset --hard HEAD^    回到上个版本

--------------暂存当前分支修改

git stash #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。

git stash save '本次暂存的标识名字'

git stash pop stash@{index} 恢复指定的暂存工作 恢复后,暂存区域会删除当前的记录
git stash apply stash@{index} 恢复指定的暂存工作 恢复后,暂存区域会保留当前的记录
git stash list 查看记录
git stash drop stash@{index} 删除某个暂存

git stash clear 删除全部暂存

6.主库权限管理

项目权限分配:

  • Owner:拥有主库的所有权限。
  • Committer:具有将开发人员的合并请求(MR)合入主库的权限。基于安全考虑,我们设置为只能通过MR的方式将代码合入主库,而不能直接push到主库。
  • Developer:只能从自己的个人代码库(服务端)提交合并代码的请求(MR),是否能够合入,由Committer进行审核。

7.git分支管理中用到的命令汇总

  • 预发布分支

创建一个功能分支(feature-x)并切换到当前分支:

git chechout -b feature-x (develop)
  • 开发完成后,将功能分支合并到develop分支:
git checkout develop 

git merge --no-ff feature-x


//注意:切换分支前 记得先缓存 stash

  • 删除feature分支:
//删除本地分支
git branch -d feature-x //如果分支上的代码没有合并,会失败
git branch -D feature-x //强制删除
//删除远程分支
git push origin --delete feature-x
//or
git push orgin :feature-x (origin有空格) 

//查看remote地址,远程分支,还有本地分支与之相对应关系等信息
 git remote show origin
//在本地删除远程不存在的分支
git remote prune origin

注:删除前 本地分支不能是即将要删除的分支 ,需要先切换到不同分支后再删除其他分支,不能当前分支删除所在的分支。

  • 创建一个预发布分支(release-1.x):
git checkout -b release-1.x develop
  • 确认没有问题后,合并master分支:
git checkout master

git merge --no-ff release-1.x
  • 对合并生成的新节点,做一个标签
git tag -a V1.x -m "标签说明"

  • 再合并到develop分支:
git checkout deveop

git merge --no-ff release-1.x

  • 最后,删除预发布分支:
git branch -d release-1.x

修复分支

创建一个修补bug分支:

git checkout -b fix-0.1 master 

修补结束后,合并到master分支:

git checkout master

git merge --no-ff fix-2.x

git tag -a 2.x

再合并到develop分支

git checkout develop

git merge --no-ff -fix-2.x

最后删除 修补bug 分支

git branch -d fix-2.x

其他:如本地缓存策略、回滚(慎用)等等。

//存储你的工作区间
git stash 
//查看存储列表
git stash list
//应用相应的缓存列表
git stash apply --index

8.避免代码冲突Tips

为了尽量避免冲突发生,养成如下开发习惯:

  • 编码前先更新
  • 提交前先更新
  • 提交前检查是否有编译错误
  • 提交粒度尽可能小,描述尽可能准确
  • 修改了公共文件,尽早通知其他成员更新
  • 最后一条,也是最重要的,团队分工要明确

9.Andorid迭代开发中git使用示例


9.1 准备开始

应用场景示例:下面即将开始版本号1.8.0的迭代开发工作。

  • 创建 master 分支,然后基于 master 创建出 develop 分支。(此处操作往往在上一次开发结束后就已完成)
  • 基于 develop 分支,创建 feature-1.8.0(迭代版本号)迭代开发分支
git checkout -b feature-1.8.0
  • 创建好后 立即push到服务器。如果没有push前,pull(更新)会失败,因为无法追踪当前分支,当前分支不在远程服务器上。

pull失败时会出现:

在这里插入图片描述
push成功时会出现:

å¨è¿éæå¥å¾çæè¿°

在gitlab中查看当前分支是否存在。

å¨è¿éæå¥å¾çæè¿°

或者用命令直接查看

å¨è¿éæå¥å¾çæè¿°
OK. 开始开发功能。

9.2开发中

小组成员之间都有该分支 的pull和push权限。开发中按照Git提交规范和Android studio提交规范执行。

git提交命令分类如下:

feat: 新功能(feature)

fix: 修复bug

docs: 文档(documentation)

style: 格式(不影响代运行的变动)

refactor: 重构(既不是新增功能,也不是修改bug的变动)

test: 增加测试

chore: 构建过程、辅助工具、编辑器配置的变动

操作示例:

  • fix(首页):修复缓存异常
  • feat(用户):新增修改用户头像的功能


9.3 开发完成

准备提交测试。开发完成后,将功能分支合并到develop分支。

目的:将当前的开发分支(如feature-1.8.0)合并到develop分支

操作方法:在GitLab主页中去操作,创建合并请求(MR),操作步骤见下文。

权限管理: 涉及到安全、权限、流程规范等因素,不能直接用git命令合并。所以需要在GitLab中去MR。

下面介绍常用的两种代码合并方式。

9.3.1 方式一:无权限设置

如果不涉及到权限、审核等安全因素,可以直接用以下操作用命令或Android stutdio上操作。

git checkout develop 

git merge --no-ff feature-x

或者在Android stuio中直接操作:步骤如下:

å¨è¿éæå¥å¾çæè¿°

此时会出现和develop不同的分支 如果没有需要合并的代码或已合并,列表中就不会再出现分支。

å¨è¿éæå¥å¾çæè¿°

注意,合并操作需要在GitLab中进行,

å¨è¿éæå¥å¾çæè¿°
注意,默认策略为"recursive"

å¨è¿éæå¥å¾çæè¿°

å¨è¿éæå¥å¾çæè¿°

如果没有设置合并权限,会合并成功。如果 设置了合并权限,只能完成本地的合并,push时会失败,需要在Gitlab中去创建合并请求 MR。相应的人员审核后,代码才能合并成功。

9.3.2 方式二:有权限设置

团队开发按照流程规范我们统一采用方式二。

权限设置如下所示,可以设置各个分支的权限。

此处的设置一般会放在Git流程规范形成后,开发迭代任务前完成。开发过程中检查一次即可。

å¨è¿éæå¥å¾çæè¿°
创建MR步骤

1.在项目的仓库主页中找到Create Merge request

å¨è¿éæå¥å¾çæè¿°

2.填写请求内容

注意Title和内容的的填写规范:可参考《MR注释规范》

在这里插入图片描述
在这里插入图片描述

查看MR中的具体代码改变了哪些。


在这里插入图片描述


注意写明请求内容,分支来源和目标分支。最后“提交”。到此,MR完成。

3.处理MR

紧接着,会邮件通知委托人,进行MR处理,确认没有问题时,会通过,合并完成。如果发现有问题,则关闭请求,合并失败,需要请求人修改代码后重新MR.

å¨è¿éæå¥å¾çæè¿°
回到Android studio中,查看git log操作记录。可以发现已经合并完成。此时develop上已经合并了feature-1.8.0的最新代码。


OK,开始打包预发布测试版本。

9.4 预发布


由于此前的迭代开发分支feature-1.8.0的代码已合并到develop上。现在develop创建 release-1.8.0 。

git切换到release-1.8.0打测试环境的安装包给测试。

操作示例:

1.创建release-1.8.0 并切换到当前分支

git checkout -b release-1.8.0

2.打包(测试环境)(打包命令需要在build.gradle中配置)

Mac环境:./gradlew clean resguardCtest 

Windows环境:gradlew clean resguardCtest
 

9.5 Bug修复

测试反馈难免会有bug或细节调整,此时需要创建修复分支,方法如下:

1.基于release-1.8.0创建 release-fix-1.8.0_1 同时记录修复次数。注:最后一位数字表示修复次数。

git checkout -b release-fix-1.8.0_1


2.修复完成后,提交MR到release-1.8.0,在提交MR时删除release-fix-1.8.0_1。同时在release-1.8.0打包测试。在当前分支打包 流程细节参考预发布流程。

3.重复进行步骤1、2,直到测试通过。

小结: 实际开发中,可以根据实际需要减少重复的开发分支的合并和建立,注意在git上记录操作节点,方便后期查询追踪。

9.6 发布App

最后一次给测试的包测试环境通过后,需要打正式环境的包,提交应用市场。

操作示例:

1.切换到发布分支release-1.8.0

git checkout release-1.8.0

2.打包(正式环境)

Mac环境:./gradlew clean resguardRelease

Windows环境:gradlew clean resguardRelease

打包成功后,生成的母包 用python命令打包成对应App市场的渠道包,准备进行分发,上传应用市场。

3.代码合并、tag管理、删除多余分支

  • 提交 MR 到 master 分支,同意后,在 master 分支上打 对应版本的 tag(v1.8.0)。
  • 提交 MR 到develop分支。
  • 删除 release-1.8.0 分支。 最后git上只有master 、develop分支和tag历史版本记录。
  • 至此,当前迭代开发工作结束。开始准备创建分支重构代码、线上bug修复等等。

总结: git的使用规范在项目开发至关重要,文中的使用示例 是在项目中的实际操作总结。


扩展

1. 新建代码库

 # 下载一个项目和它的整个代码历史

git clone url

 # 下载一个项目某个分支代码历史

git clone -b branch-name  url

2. 配置

# 显示当前的Git配置

git config --list

# 设置提交代码时的用户信息

git config [--global] user.name "name"

git config [--global] user.email "email"

3. 增加到暂存区

Git Version 1. x :

# 将当前目录下所有新增和修改存至缓存区,但不包括删除

git add .

# 将目录下所有修改和删除存至缓存区,但不包括新增、

git add -u(git add --update)

# 缓存所有改动(是上面两个功能的合集)

git add -A (git add --all)

4. 代码提交/撤销

提交:

# 提交暂存区到仓库区

git commit -m "提交的描述信息"

撤销提交:

# 撤销后 不会清除提交前的暂存区和工作区(上一次提交/要撤销的commit_id)

git reset --soft HEAD^/commit_id

# 撤销后 清空了提交前的暂存区但是工作区存在

git reset HEAD^/commit_id

# 撤销后 清空了提交前的工作区和暂存区,所有的内容都回到了上一commit的状态。

git reset --hard HEAD^/commit_id

# 强制撤销已经push到远端的commit(看不到这个历史痕迹)

git reset --soft HEAD^/commit_id

git push origin <分支名> --force

*若在你的commitX 后别人提交了新的commit Y,然后你强制撤销推送,那位仁兄的commit Y也跟着一起消失了。

#功能分支代码切回主分支 并保留历史线路

 git merge --no-ff xxx 

5. 分支

# 列出所有本地分支

 git branch

# 新建一个feature-x分支

git branch feature-x(仍停留在当前分支)

git checkout -b feature-x(已经切换到该分支)

# 合并指定分支(feature-x)到当前分支

git merge feature-x(历史提交记录会留下合并痕迹) 

git rebase feature-x (历史提交记录不会留下合并痕迹)

# 删除分支feature-x

git branch -d feature-x

# 删除远程分支feature-x

git push origin --delete feature-x

6. 查看信息

# 显示有变更的文件

git status

# 显示当前分支的版本历史

git log

7. 远程同步

# 推送commit到远程分支

git push

# 拉取本地没有的远程分支到本地

git checkout -b 本地分支名 origin/远程分支名

# 上传本地指定分支(feature-x)到远程仓库(在远程仓库生成该分支上游分支)

 git push origin feature-x(git push --set-upstream origin feature-x)

# 推送所有分支到远程仓库

 git push origin  --all

从branchA分支拉了一份代码,做了一些修改,但是不想提交到branchA分支,想新建一个分支branchB保存代码。

操作方法:

添加本地需要提交代码

git add .

提交本地代码

git commit -m "add my code to new branchB"

push 到git仓库(提交到远程某个不存在的分支)

git push origin branchA:branchB

仓库中原本没有branchB,提交后会生成新分支branchB,并将本地基于branchA修改的代码提交到branchB中

切换新分支

git checkout -b branchB origin/branchB

git本地新建的项目上传到远程某个不存在的分支

git push origin dev(本地分支):branch_new(仓库中不存在的分支)

8、修改远程

git remote set-url origin url

 先删后加

git remote rm origin
git remote add origin git@github.com:sheng/demo.git

 修改config文件

如果你的项目有加入版本控制,那可以到项目根目录下,查看隐藏文件夹, 发现.git文件夹,找到其中的config文件,就可以修改其中的git remote origin地址了。

9. 修改注释

# 修改最后一次注释

如果你只想修改最后一次注释(就是最新的一次提交),那好办:
git commit --amend
出现有注释的界面(你的注释应该显示在第一行), 输入i进入修改模式,修改好注释后,按Esc键 退出编辑模式,输入:wq保存并退出。ok,修改完成。
例如修改时编辑界面的图:

# 修改之前的某次注释

git rebase -i HEAD~2

最后的数字2指的是显示到倒数第几次 比如这个输入的2就会显示倒数的两次注释(最上面两行)

  • 你想修改哪条注释 就把哪条注释前面的pick换成edit。方法就是上面说的编辑方式:i---编辑,把pick换成edit---Esc---:wq.

  • 然后:(接下来的步骤Terminal会提示)
    git commit --amend

  • 修改注释,保存并退出后,输入:
    git rebase --continue

其实这个原理我的理解就是先版本回退到你想修改的某次版本,然后修改当前的commit注释,然后再回到本地最新的版本

# 修改之前的某几次注释

修改多次的注释其实步骤和上面的一样,不同点在于:

  1. 同上
  2. 你可以将多个想修改的commit注释前面的pick换成edit
  3. 依次修改你的注释(顺序是从旧到新),Terminal基本都会提示你接下来的操作,每修改一个注释都要重复上面的3和4步,直到修改完你所选择的所有注释

# 已经将代码push到远程仓库

首先,你把最新的版本从远程仓库先pull下来,修改的方法都如上,最后修改完成后,强制push到远程仓库:
 

git push --force origin master
 

注:很重要的一点是,你最好保证在你强制push之前没有人提交代码,如果在你push之前有人提交了新的代码到远程仓库,然后你又强制push,那么会被你的强制更新覆盖!!!

最后,可以检查一下远程的提交记录~~

一、修改最近一次提交的commit信息
1.首先通过 git log 查看commit信息

2.使用指令:git commit --amend 进入命令模式(修改号commit信息保存后退出编辑模式)

3. git push --force 到远程仓库(注意:必须加上 --force 如果只使用 git push 会报错)

二、修改最近两个或者两次上的commit信息
1.首先通过 git log 查看commit信息

2.使用指令:git rebase -i HEAD~2(把对应的 pick 改成 e 或者 edit 后保存)

3.使用 git commit --amend 去修改具体的commit信息

4.用 git rebase --continue 完成

5.git push --force 到远程仓库(注意:必须加上 --force 如果只使用 git push 会报错)

6.去远程仓库查看提交记录


延伸:

Git撤销&回滚操作(git reset 和 get revert)

git的工作流

工作区:即自己当前分支所修改的代码,git add xx 之前的!不包括 git add xx 和 git commit xxx 之后的。

暂存区:已经 git add xxx 进去,且未 git commit xxx 的。

本地分支:已经git commit -m xxx 提交到本地分支的。
 

代码回滚

在上传代码到远程仓库的时候,不免会出现问题,任何过程都有可能要回滚代码:

1、在工作区的代码

git checkout -- a.txt   # 丢弃某个文件,或者
git checkout -- .       # 丢弃全部

注意:git checkout – . 丢弃全部,也包括:新增的文件会被删除、删除的文件会恢复回来、修改的文件会回去。这几个前提都说的是,回到暂存区之前的样子。对之前保存在暂存区里的代码不会有任何影响。对commit提交到本地分支的代码就更没影响了。当然,如果你之前压根都没有暂存或commit,那就是回到你上次pull下来的样子了。

2、代码git add到缓存区,并未commit提交

git reset HEAD .  或者
git reset HEAD a.txt

这个命令仅改变暂存区,并不改变工作区,这意味着在无任何其他操作的情况下,工作区中的实际文件同该命令运行之前无任何变化

3、git commit到本地分支、但没有git push到远程

git log # 得到你需要回退一次提交的commit id
git reset --hard <commit_id>  # 回到其中你想要的某个版
或者
git reset --hard HEAD^  # 回到最新的一次提交
或者
git reset HEAD^  # 此时代码保留,回到 git add 之前

4、git push把修改提交到远程仓库
1)通过git reset是直接删除指定的commit

git log # 得到你需要回退一次提交的commit id
git reset --hard <commit_id>
git push origin HEAD --force # 强制提交一次,之前错误的提交就从远程仓库删除

2)通过git revert是用一次新的commit来回滚之前的commit

git log # 得到你需要回退一次提交的commit id
git revert <commit_id>  # 撤销指定的版本,撤销也会作为一次提交进行保存

3) git revert 和 git reset的区别
- git revert是用一次新的commit来回滚之前的commit,此次提交之前的commit都会被保留;
- git reset是回到某次提交,提交及之前的commit都会被保留,但是此commit id之后的修改都会被删除

开发过程中,你肯定会遇到这样的场景:

场景一:

糟了,我刚把不想要的代码,commit到本地仓库中了,但是还没有做push操作!

场景二:

彻底完了,刚线上更新的代码出现问题了,需要还原这次提交的代码!

场景三:

刚才我发现之前的某次提交太愚蠢了,现在想要干掉它!

撤销

上述场景一,在未进行git push前的所有操作,都是在“本地仓库”中执行的。我们暂且将“本地仓库”的代码还原操作叫做“撤销”!

情况一:文件被修改了,但未执行git add操作(working tree内撤销)

git checkout fileName
git checkout .

情况二:同时对多个文件执行了git add操作,但本次只想提交其中一部分文件

$ git add *
$ git status
# 取消暂存
$ git reset HEAD <filename>

情况三:文件执行了git add操作,但想撤销对其的修改(index内回滚)

# 取消暂存
git reset HEAD fileName
# 撤销修改
git checkout fileName

情况四:修改的文件已被git commit,但想再次修改不再产生新的Commit

# 修改最后一次提交 
$ git add sample.txt
$ git commit --amend -m"说明"

情况五:已在本地进行了多次git commit操作,现在想撤销到其中某次Commit

git reset [--hard|soft|mixed|merge|keep] [commit|HEAD]

具体参数和使用说明,请查看:Git Pro深入浅出(二)中的重置揭秘部分

回滚

上述场景二,已进行git push,即已推送到“远程仓库”中。我们将已被提交到“远程仓库”的代码还原操作叫做“回滚”!注意:对远程仓库做回滚操作是有风险的,需提前做好备份和通知其他团队成员!

如果你每次更新线上,都会打tag,那恭喜你,你可以很快的处理上述场景二的情况

git checkout <tag>

如果你回到当前HEAD指向

git checkout <branch_name>

情况一:撤销指定文件到指定版本

# 查看指定文件的历史版本
git log <filename>
# 回滚到指定commitID
git checkout <commitID> <filename>

情况二:删除最后一次远程提交

方式一:使用revert

git revert HEAD
git push origin master

方式二:使用reset

git reset --hard HEAD^
git push origin master -f

二者区别:

  • revert是放弃指定提交的修改,但是会生成一次新的提交,需要填写提交注释,以前的历史记录都在;
  • reset是指将HEAD指针指到指定提交,历史记录中不会出现放弃的提交记录。

情况三:回滚某次提交

# 找到要回滚的commitID
git log
git revert commitID

删除某次提交

git log --oneline -n5

Git撤销&回滚操作-log

git rebase -i "commit id"^

注意:需要注意最后的^号,意思是commit id的前一次提交

git rebase -i "5b3ba7a"^

Git撤销&回滚操作-rebase

在编辑框中删除相关commit,如pick 5b3ba7a test2,然后保存退出(如果遇到冲突需要先解决冲突)!

git push origin master -f

通过上述操作,如果你想对历史多个commit进行处理或者,可以选择git rebase -i,只需删除对应的记录就好。rebase还可对 commit 消息进行编辑,以及合并多个commit。

git cherry-pick命令使用

用途:重新生成commitID,在原先其他分支或者本地分支的其他commit之上,然后git push到远端

1、在分支A重新提交我在分支B做的一次功能修改,并在分支A提交。

2、另一种情况在分支A(在未跟新代码的情况下修改了好几个功能,本地有好几个commit提交),我不能向远端用(git push origin 本地分支 远程分支),我往往会用先用git reset --HARD 到最新mergedID 然后git pull再用git cherry-pick(想要远端提交某个功能的commitID)生成新的commitID,然后再git push 到远端

用途一:

在本地分支B上

①git log

注:选择自己想要在分支A提交的功能,复制分支B的commitID

②git checkout <branchA>

注:切换分支到branchA

③git cherry-pick <commitId>

      注:commitID为之前在分支B复制的那个commitID,会在当前分支生成一个新的commit(没有冲突的情况下)

④git push origin <branchA> <originBranch>

完成

用途二:

在本地分支A上

①我本地修改已经完成,不知道我本地是不是最新的代码

然后我 git commit -m “提交信息”  //把我的修改生成了一个commitID

②git log 

发现我的代码并不是最新merge的基础上修改的

③git reset --hard <远端最新mergedID>

④git pull origin <originBranch>一下跟新远端代码

⑤git reflog  

   注:看我修改的那个commitID 复制一下

⑥git cherry-pick <commitID>

注:我复制过的那个

⑦git push origin <branchA> <originBranch>

完成

eg:

温馨提示:每次的使用git cherry-pick的时候要保证是本地与远端代码保持一致,才可以正确提交,远端才不会有其他提交的信息

git clean

git clean 从你的工作目录中删除所有没有 tracked,没有被管理过的文件。

一定要注意:没有被git add的文件删除了就找不回了,一定要慎用。但是如果被 git add . 就不会被删除。

git clean 和 git reset --hard 结合使用。

clean 影响没有被 track 过的文件(清除未被 add 或被 commit 的本地修改)

reset 影响被 track 过的文件 (回退到上一个 commit)

所以需要 clean 来删除没有 track 过的文件,reset 删除被 track 过的文件

结合两命令 → 让你的工作目录完全回到一个指定的 <commit> 的状态

参数说明:

:显示将要被删除的文件

d :删除未被添加到 git 路径中的文件(将 .gitignore 文件标记的文件全部删除)

f :强制运行

x :删除没有被 track 的文件

git clean -n
// 是一次 clean 的演习, 告诉你哪些文件会被删除,不会真的删除
 
git clean -f
// 删除当前目录下所有没有 track 过的文件
// 不会删除 .gitignore 文件里面指定的文件夹和文件, 不管这些文件有没有被 track 过
 
git clean -f <path>
// 删除指定路径下的没有被 track 过的文件
 
git clean -df
 
// 删除当前目录下没有被 track 过的文件和文件夹
 
git clean -xf
 
// 删除当前目录下所有没有 track 过的文件.
// 不管是否是 .gitignore 文件里面指定的文件夹和文件
 
git clean 
// 对于刚编译过的项目也非常有用
// 如, 他能轻易删除掉编译后生成的 .o 和 .exe 等文件. 这个在打包要发布一个 release 的时候非常有用
 
git reset --hard
git clean -df
git status
// 运行后, 工作目录和缓存区回到最近一次 commit 时候一摸一样的状态。
// 此时建议运行 git status,会告诉你这是一个干净的工作目录, 又是一个新的开始了!

注意:

git add .  git commit  后一定要记得 git push ,不然你又找不回来了。

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值