Git 切分支进行代码版本差异化管理

一、写在前面

我有一个 iOS SDK 工程,除了常规的初始化、登录支付等接口,还包含第三方相关的接口。这时候想分一个版本出来,要求这个版本移除第三方接口。但是因为这个工程还在不断的维护,因此要求后面的更新,需要覆盖原来的版本和分出来的不带第三方的版本,这种情况就可以通过 Git 分支来实现。大概思路就是:原来只有一个 main/master 分支,那么包含第三方的版本默认为 main 分支,新增一个 remove-ads 分支。在 remove-ads 分支中,删除或注释掉第三方接口。当 main 分支有更新时,再同步到 remove-ads 分支。这样就实现了区分,后面的更新也能覆盖两个分支。

二、分支操作

1、查看分支

git branch 查看本地的分支

% git branch
* master

git branch -r 查看远程仓库的分支

% git branch -r
  origin/master

git branch -a 查看本地和远程所有分支

% git branch -a
* master
  remotes/origin/master

可以看到,当前仓库的本地和远程仓库都是 master 分支,也就是 main 分支。(注意执行 Git 操作,都是在代码仓库的目录下进行的,Git 仓库下都有一个隐藏文件 .git

2、检查状态

git status 检查当前的状态,确保本地和远程的代码一致,以避免潜在的冲突。如果存在未提交的更改,Git 可能会拒绝切换分支。

% git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。

无文件要提交,干净的工作区

3、本地创建并切换分支

git checkout -b remove-ads 本地创建并切换到 remove-ads 分支。如果你是第一次使用分支,担心操作出问题,可以先压缩备份下代码工程。

% git checkout -b remove-ads
切换到一个新分支 'remove-ads'

看星号,说明本地已经成功创建并切换到 remove-ads 分支:

% git branch
  master
* remove-ads

而远程仓库依旧只有 master 分支。

% git branch -r
  origin/master

4、将本地分支推送到远程仓库

为了在远程仓库上同步这个新分支,并与其他开发者共享,我们需要将它推送到远程仓库。
使用 git push origin remove-ads 会将 remove-ads 分支推送到远程仓库 origin,并创建一个同名的远程分支。

% git push origin remove-ads
总共 0(差异 0),复用 0(差异 0),包复用 0
remote: 
remote: To create a merge request for remove-ads, visit:
remote:   http://xx.xx.xxx.xxx/Vampire/SW_iOS_SDK_NEW/merge_requests/new?merge_request%5Bsource_branch%5D=remove-ads
remote: 
To ssh://xx.xx.xxx.xxx:2333/Vampire/SW_iOS_SDK_NEW.git
 * [new branch]      remove-ads -> remove-ads

git branch -r 再次查看,remove-ads 分支已经成功推送到远程仓库。

% git branch -r
  origin/master
  origin/remove-ads

5、设置追踪分支(可选)

为了简化后续的操作,可以设置本地分支与远程分支的关联,以便后续使用 git pushgit pull 时不需要指定远程分支名称。

% git branch --set-upstream-to=origin/remove-ads remove-ads
分支 'remove-ads' 设置为跟踪 'origin/remove-ads'。

如果不设置追踪分支,那么后续对分支执行 git pushgit pull 操作就需要指定远程仓库分支:

% git push origin remove-ads
% git pull origin remove-ads

总的来说,还是设置追踪分支更方便,因为一般情况下,本地仓库和远程仓库会保持一致的分支情况和分支名称。

6、修改分支代码

上面的操作完成后,就可以在本地针对 remove-ads 分支进行代码的修改,例如我当前的需求:删除或注释掉第三方接口。修改完毕再同步推送到远程仓库。

% git add .

% git commit -m '移除第三方接口'
[remove-ads 9ffdc86] 移除第三方接口
 1213 files changed, 80 insertions(+), 41489 deletions(-)
 ...

推送到远程仓库,注意这里直接使用 git push 是因为前面已经设置了分支追踪。

% git push
枚举对象中: 56, 完成.
对象计数中: 100% (56/56), 完成.
使用 8 个线程进行压缩
压缩对象中: 100% (29/29), 完成.
写入对象中: 100% (29/29), 91.14 KiB | 1.69 MiB/s, 完成.
总共 29(差异 20),复用 0(差异 0),包复用 0
remote: 
remote: To create a merge request for remove-ads, visit:
remote:   http://xx.xx.xxx.xxx/Vampire/SW_iOS_SDK_NEW/merge_requests/new?merge_request%5Bsource_branch%5D=remove-ads
remote: 
To ssh://xx.xx.xxx.xxx:2333/Vampire/SW_iOS_SDK_NEW.git
   e32bf32..9ffdc86  remove-ads -> remove-ads

7、切回主分支

git checkout master 切回主分支,可以在主分支上正常开发了,也不影响 remove-ads 分支的代码。

% git checkout master
正在更新文件: 100% (1213/1213), 完成.
切换到分支 'master'
您的分支与上游分支 'origin/master' 一致。

8、同步修改到分支

如果在主分支修改了一些公共的代码,需要同步到 remove-ads 子分支。那么需要先切换到子分支,再使用 git merge master 合并主分支的修改。

% git checkout remove-ads
切换到分支 'remove-ads'
您的分支与上游分支 'origin/remove-ads' 一致。

% git merge master
Merge made by the 'ort' strategy.
 .../SWGame_Logical/SWGame_Public/SWGame_ViewControllerManager.m           | 2 ++
 1 file changed, 2 insertions(+)

同样的,本地合并完成后,再推送到远程仓库即可。

% git status
位于分支 remove-ads
您的分支领先 'origin/remove-ads' 共 2 个提交。
  (使用 "git push" 来发布您的本地提交)

无文件要提交,干净的工作区
% git push
枚举对象中: 16, 完成.
对象计数中: 100% (16/16), 完成.
使用 8 个线程进行压缩
压缩对象中: 100% (6/6), 完成.
写入对象中: 100% (6/6), 576 字节 | 576.00 KiB/s, 完成.
总共 6(差异 4),复用 0(差异 0),包复用 0
remote: 
remote: To create a merge request for remove-ads, visit:
remote:   http://xx.xx.xxx.xxx/Vampire/SW_iOS_SDK_NEW/merge_requests/new?merge_request%5Bsource_branch%5D=remove-ads
remote: 
To ssh://xx.xx.xxx.xxx:2333/Vampire/SW_iOS_SDK_NEW.git
   9ffdc86..8d0c113  remove-ads -> remove-ads

从 Git 可视化工具 Sourcetree 也可以清楚的看到我们的切分支过程:


git-branch.png

三、暂存操作

在切换分支的开发中,会遇到这样一种情况:
我正在主分支上进行开发,还未开发完成,因此不想提交代码。但是这时候接到一个需求,要求对 remove-ads 子分支进行修改,并导出 SDK 文件,这时候我需要切换到 remove-ads 分支进行开发。但是主分支代码不体检,Git 是不允许切换分支的。

% git checkout remove-ads
错误:您对下列文件的本地修改将被检出操作覆盖:
    SWGameSDK/SWGameSDK/SWGame_Api/SWGame_Api.h
请在切换分支前提交或贮藏您的修改。
正在终止

那么就涉及到 暂存 的操作了。具体如下:

1、将未完成的代码暂存到 stash 中

在 main 分支上,使用 git stash 命令可以将当前未完成的代码暂存起来,不影响切换分支。git stash 会将当前分支上的未提交更改(包括已跟踪的文件和未提交的修改)存入一个临时区域,并恢复上一次提交的状态。

% git stash
保存工作目录和索引状态 WIP on master: 4806dee 主分支修改测试

2、切换到 remove-ads 分支进行修改

代码暂存后,可以自由地切换到 remove-ads 分支进行工作。

git checkout remove-ads

3、切换到 master 分支并恢复未完成的工作

完成 remove-ads 分支的工作后,切换回 master 分支。

git checkout master

然后使用 git stash pop 恢复之前暂存的代码。该命令会将之前的暂存内容恢复到工作区,同时从 stash 中移除该存储点,如果暂存过程没有冲突,未完成代码将会恢复。

% git stash pop
位于分支 master
您的分支与上游分支 'origin/master' 一致。

尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git restore <文件>..." 丢弃工作区的改动)
    修改:     SWGameSDK/SWGameSDK/SWGame_Api/SWGame_Api.h

修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
丢弃了 refs/stash@{0}(48769d4112625cc27e49c48a478afa1207034106

4、继续在 master 分支上开发

现在可以继续在 master 分支上完成之前未完成的开发。
需要注意的点:

  • 如果 git stash pop 过程中出现冲突,Git 会提示手动解决冲突,解决冲突后再继续开发。
  • 如果不想立即应用暂存的内容,可以先使用 git stash list 查看所有暂存点,然后稍后使用 git stash apply stash@{n} 来恢复特定的暂存点。

当使用 git stash 时,Git 会将当前的修改保存到一个堆栈(stash stack)中,并按照顺序给这些暂存点编号。每次暂存的内容都会生成一个唯一的标识,如 stash@{0}、stash@{1},依次类推。

  • stash@{0} 表示最新的暂存点。
  • stash@{1} 表示倒数第二个暂存点,依次类推。

git stash apply stash@{n} 允许你选择应用特定的暂存点,而不仅仅是最新的一个。但是需要注意的是,git stash apply stash@{n} 不会删除暂存点。

% git stash list
stash@{0}: WIP on master: 4806dee 主分支修改测试

% git stash apply stash@{0}
位于分支 master
您的分支与上游分支 'origin/master' 一致。

尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git restore <文件>..." 丢弃工作区的改动)
    修改:     SWGameSDK/SWGameSDK/SWGame_Api/SWGame_Api.h

修改尚未加入提交(使用 "git add" 和/或 "git commit -a"

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

推荐阅读更多精彩内容