GIT操作 之 具体场景应用举例

当你基础入门了git指令后,比如 添加add 、提交commit 、分支branchstash等等,但等遇到具体一些场景时候,又不太知道从何操作起。本文主要是从使用需求出发,来描述操作过程。

1. 保存工作现场

场景: 线上运行着稳定版本stable1.0,你在QA上开发新版本dev2.0。突然stable1.0出现bug了,你需求切分支过去修改bug。但是,dev2.0的代码不过完整,还不想提交。肿么办?

解决: 这种情况相当于是要在本地保存修改,但有想切换分支(当前分支若有文件修改没有提交,会无法切分支)。这时候我们可以使用git stash来保存当前工作现场。
具体操作如下:

#在dev2.0分支下,保存工作现场
git stash

#切换到stable1.0去修改bug
git checkout stable1.0

#创建修复分支
git checkout -b stable1.0-bug1

#coding...修改好了之后
git add ./
git commit -m "fix bug1"

#合并修复分支,并删除修复分支
git checkout stable1.0
git merge --no-ff -m "merge fix bug1" stable1.0-bug1
git branch -d stable1.0-bug1

#接下来回到dev2.0,继续愉快的玩耍吧
git checkout dev2.0

#查看保存的工作现场
git stash list

#恢复stash内容
git stash apply

#删除stash内容
git stash drop

#以上的恢复和删除 stash内容 可以合并为 pop指令
git stash pop

#嗯,一切如常,仿佛啥也没发生过一样...

2. 本地更改保存分支替换

场景: 你在分支A愉快的玩耍着,但突然发现这些本地修改出现了点问题,比如改乱了,或者是在研究阶段等等,总之就是不能保存在分支A上面了,可是又想要保留这些修改。于是你想创建一个新分支来放置这些修改,可是现在在分支A上,怎么优雅地挪动这些修改呢?

解决: 这种情况有两种解决方案。

  1. 直接从分支A创建一个新分支B,然后在新分支B上面进行add和commit即可。
  2. 利用stash把本地修改保存在当前工作现场,然后在任意分支创建一个新分支B,然后在新分支B下进行stash pop即可。
    具体操作如下:
#方法1
git branch -b branch-B
git add ./
git commit -m "some edit..."

#方法2
git stash
git checkout -b branch-B
git stash pop
git add ./
git commit -m "some edit..."

3. 给分支添加描述

场景: 修复bug创建分支,临时创意创建分支,突然想备份个版本又创建分支……(一不小心还忘记删掉无用分支)久而久之,你突然不知道你为什么创建分支,而且这些分支该何去何从呢?这时候你突然想,要是创建分支能像commit那样写个备注啥的就好了。

解决: 给分支添加描述,不是不可能,只是操作方式并和commit不一样。
具体操作如下:

#给当前分支添加描述
git branch --edit-description

#执行上面指令,界面会进入一个编辑界面,可以按【insert】键,然后在里面噼里啪啦写下你的感言
#写完后,【Q】键退出编辑,然后输入":wq!"保存退出。

#查看分支描述
git config branch.<branch>.description

注意:

  1. 分支描述是保存在.git/config下的,是本地存储,所以不能被推送。当删除分支时,对应的分支描述也会一起删除。
  2. 设置 git config --global branchdesc true, 就可以将此描述推送到合并提交。即git merge --log<branch>,分支描述会添加到合并提交消息。(此条规则我还没有测试,你们可以先测测看。)

4. 从指定分支的指定版本中拉取新分支

场景: 你在开发分支B上愉快的玩耍着新版本需求R,但突然间这个新版本需求被拆分成两个小版本R1 R2了,且还在R1中补充了更新的一些需求。但你已经杂糅一起开发了啊?肿么办?
git log查看下提交日志,发现分支B上最新两次commit是R2的,之前都是R1的。
那我们就想,从提交前2次的版本checkout出新的分支作为R1需求开发分支B1。

解决:
一开始想要 git reset进行版本回滚,但我们只是要拆分啊,不是要撤销。后来也想到git resvert操作,但也一样不行。后来重温了下 git branch 语法,才发现其实很简单。
我们熟悉从当前分支创建一个分支的命令,如下:

# 从当前版本新建一个分支
git branch new-branch

这个命令实际上是下面命令的缩写:

git branch new-branch current-branch

也就是说,当我们不指定创建分支的起点,Git默认从当前活动分支开始创建新分支。既然如此,那我们可以通过提供这个起点(commit id),来指定要新分支指向的版本号。

# eg. 假设我们要指向的版本号是169d2dc,这是一个 SHA1 散列值(Hash 值),每次git commit时都会这个id。
git branch new-branch 169d2dc

当然,我们也可以使用 checkout -b实现创建并检出新分支:

git checkout -b new-branch 169d2dc

拓展:
以下代码,个人没有去试验,大家可以自行试一下。

# 将某个历史版本 checkout 到工作区,但不建议这么做。
git checkout <sha1-of-a-commit>

# 将某个文件的历史版本 checkout 到工作区
git checkout <sha1-of-a-commit> </path/to/your/file>

# 将某个文件的历史版本 checkout 出来,并以一个新的名字保存
git checkout <sha1-of-a-commit>:</path/to/your/file> </new/name/of/the/file>

参考文章:
1.在Git中 Checkout 历史版本

5. 合并分支时,只合并指定文件夹

场景: 我们在开发分支A上面开发者消息模块和详情页模块(两个已经同时在进行了),但突然说消息模块要紧急上线,我们就需要把消息模块剥离到线上分支B。
也就是说,我们希望把A分支上的消息模块代码合并到分支B。

解决:
合并一般采用git merge,但merge方式会将两个分支的内容完全合并。这时候我们可以巧用 git checkout

# 若消息模块是一个文件夹,把分支A的message文件夹检出到当前分支(也就是例子中的B分支)
git checkout A ./message

# 若消息模块是若干个文件夹,把分支A的message相关文件检出到当前分支
git checkout A message.html message.css message.js common.js

注意:在使用git checkout某文件到当前分支时,会将当前分支的对应文件强行覆盖。

文件类型 git checkout的操作结果
新增文件 直接拉取
已有文件的编辑 仅保留在A分支上的编辑
删除文件 不处理

比如common.js,B分支上也有修改,在checkout的时候就会将common.js强行覆盖,这样就导致B分支上的修改内容丢失。那如何避免不强制覆盖呢?

非强制覆盖
想要不强制覆盖,我们可以考虑创建一个中间分支B_TEMP,对分支B进行备份,然后把A分支merge到B_TEMP,在从B_TEMP检出消息模块文件到B分支

# (在分支B)
# 拷贝分支B
git checkout -b B_TEMP

# (在分支B_TEMP)
# 把A分支合并到B_TEMP,这时候在B_TEMP分支里面有消息模块和详情页模块
git merge A

# 切换回分支B(在分支B)
# 再进行从B_TEMP检出
git checkout B_TEMP message.html message.css message.js common.js

总结:其实就是构建一个临时分支,用来保存A/B分支合并(真正的merge)后结果。之后再去覆盖,就会是合并后代码的覆盖。

参考文章:# git小技巧--如何从其他分支merge个别文件或文件夹

6. 本地分支合并乱套,想恢复远程版本

场景: long long ago,你参与了项目A的开发,但中途被调到了项目B,时隔半年又回来项目A帮忙。这时候你在dev分支(对应测试环境)上面进行开发、提交。现在要发布线上了,你就需要合并dev到master分支。
你的操作如下:

#切到本地master
git checkout master

#拉取master最新代码
git pull

#这时候提示了错误:
#error: unable to create file config/dev.env.js: Permission denied Updating ac7cb80..be4852a

#你习惯性查看下分支状态
git status

#发现有一堆的文件需要add/commit。
#但这些文件都不是你修改的,明明是远程master分支上面的修改啊,为什么要你本地add/commit啊

#无奈之下,你乖乖的 add/commit了
git add ./
git commit -m "无奈之举啊"

#这下分支安静了,我们在来拉取下远程代码
git pull

#结果,一堆的CONFLICT啊!!
#那真是无从处理起了。。。。

解决:
这时候只有一个想法,要么把master分支删掉,要么赶紧回退到合并之前啊。。。。

# 强制恢复到远程master分支的最新版本
git reset --hard origin/master

参考文章:
请教大家一个三联用的 git 命令的意思, git fetch --all && git reset --hard origin/master && git pull:我也没太明白这个三联是啥。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容

  • Git 基础 基本原理 客户端并不是只提取最新版本的文件快照,而是把代码仓库完整的镜像下来。这样一来,任何一处协同...
    __silhouette阅读 15,866评论 5 147
  • Git 命令行学习笔记 Git 基础 基本原理 客户端并不是只提取最新版本的文件快照,而是把代码仓库完整的镜像下来...
    sunnyghx阅读 3,910评论 0 11
  • 1.git的安装 1.1 在Windows上安装Git msysgit是Windows版的Git,从https:/...
    落魂灬阅读 12,657评论 4 54
  • 孙大成出差回来了。他打电话说是下午到,可回到家已经深夜了。方芳问他怎么回事,孙大成说总经理叫去应酬。 方芳接着问:...
    一夜春风cf阅读 554评论 6 16