一. 靜態(tài)庫符號沖突解決
1.1 鏈接同名靜態(tài)庫會不會沖突反浓?
首先打開第一份工程LGTestApp
榴捡,導(dǎo)入了AFNetworking
庫
platform :ios, '14.0'
target 'LGTestApp' do
# use_frameworks!
pod 'AFNetworking'
end
接下來往工程中Frameworks
目錄下導(dǎo)入AFNetworking_static
目錄下的libAFNetworking.a
溫馨小提示:
把Pods/Pods-LGTestApp.debug.xcconfig
配置文件中的
OTHER_LDFLAGS = $(inherited) -all_load -l"AFNetworking"
工程鏈接靜態(tài)庫中所有代碼
改成默認(rèn)OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking"
墓懂,工程鏈接靜態(tài)庫的方式會變成统捶,鏈接所有與OC相關(guān)的類或者分類到當(dāng)前工程ipa包中。
此時cocoapods鏈接了一個AFNetworking
庫沃粗,手動又拖進(jìn)去一個AFNetworking
庫粥惧,Cmd + R會不會報沖突?
不會報錯最盅,cocoapods正常通過三要素進(jìn)行鏈接突雪,第一點(diǎn)通過HEADER_SEARCH_PATHS
找到api,第二點(diǎn)通過LIBRARY_SEARCH_PATHS
找到路徑檩禾,最后通過OTHER_LDFLAGS
根據(jù)庫的名稱鏈接庫挂签。當(dāng)把一個庫拖入Frameworks
目錄下,此時鏈接庫的方式是通過靜態(tài)庫的路徑進(jìn)行鏈接盼产。相當(dāng)于OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking" /Users/wn/Documents/資料/上課代碼/01-靜態(tài)庫沖突原因/LGTestApp/libAFNetworking.a
饵婆,這個時候鏈接器發(fā)現(xiàn)靜態(tài)庫同名,會優(yōu)先鏈接第一個庫戏售,第二個庫就不會鏈接侨核。
1.2 鏈接同名靜態(tài)庫報沖突的情況?
修改AFNetworking_static
目錄下的libAFNetworking.a
名稱為libAFNetworking2.a
灌灾,導(dǎo)入Frameworks
目錄下搓译,鏈接器會認(rèn)為是兩個不同的靜態(tài)庫,這個時候相同的靜態(tài)庫起不同的名字就會沖突锋喜。此時報了duplicate symbols for architecture x86_64
符號沖突些己,重復(fù)定義符號豌鸡。
OC為什么是一門動態(tài)語言?
當(dāng)把代碼編譯到MachO之后段标,MachO中有一個__Data段涯冠,這個段的__Object_section中存放著所有與類相關(guān)的內(nèi)容。當(dāng)把MachO加載到內(nèi)存時逼庞,Runtime會把section讀出來蛇更,生成相應(yīng)的Class_RO,Class_RW結(jié)構(gòu)體赛糟,動態(tài)化的初始化對象派任。
下面我們創(chuàng)建一個單符號沖突的情況?
創(chuàng)建AFNetworking2
靜態(tài)庫璧南,靜態(tài)庫內(nèi)容如下
// AFNetworking.h內(nèi)容
#import <Foundation/Foundation.h>
void global_function() {
}
@interface AFURLSessionManager : NSObject
@property (readonly, nonatomic, strong) NSURLSession *session;
@end
// AFNetworking.m內(nèi)容
#import "AFNetworking.h"
@implementation AFURLSessionManager
@end
創(chuàng)建完靜態(tài)庫之后掌逛,把靜態(tài)庫工程添加到LGTestApp
把創(chuàng)建的靜態(tài)庫AFNetworking2
添加到Frameworks下
編譯之后報錯如下
- 命令一查看符號
$ tty
/dev/ttys003
// 修改AFNetworking2 靜態(tài)庫中的RunCMD.Config.xcconfig內(nèi)容如下
// 詳細(xì)輸出終端命令
VERBOSE_SCRIPT_LOGGING=-v
MACH_PATH=${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/libAFNetworking2.a
MAP_PATH=${SRCROOT}/cat.m
CMD = nm -pa ${MAP_PATH}
TTY=/dev/ttys003
AFNetworking2
靜態(tài)庫中RunCMD.Config.xcconfig
配置完成之后,Cmd + R 運(yùn)行穆咐,終端打印出符號如下
S
表示存放在其他session颤诀,也就是__Data __ObjC的session段中.
- 命令二查看符號字旭,配置
RunCMD.Config.xcconfig
內(nèi)容如下
// 詳細(xì)輸出終端命令
VERBOSE_SCRIPT_LOGGING=-v
MACH_PATH=${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/libAFNetworking2.a
MAP_PATH=${SRCROOT}/cat.m
CMD = objdump --macho -t ${MACH_PATH}
TTY=/dev/ttys003
Cmd + R 運(yùn)行对湃,終端打印出符號如下
小結(jié)
- 只有全局符號才會產(chǎn)生沖突
解決方法
- 方法一 文件產(chǎn)生沖突,可以使用
ar
命令對靜態(tài)庫進(jìn)行解壓縮遗淳,去掉重復(fù)符號拍柒,再包裝成靜態(tài)庫 - 方法二 符號產(chǎn)生沖突,上面產(chǎn)生沖突的符號
AFURLSessionManager
在不同文件中
1.如果能夠獲取到源碼屈暗,直接修改其中一個符號名稱即可解決拆讯,如CT_AFURLSessionManager
2.如果獲取不到源碼,可以對單獨(dú)的庫指定一些參數(shù)养叛,如OTHER_LDFLAGS = $(inherited) -force_load "庫路徑" -l"AFNetworking"
种呐,如果庫比較多的話,需要對每一個庫進(jìn)行指定弃甥,雖然能解決問題爽室,但是比較麻煩
3.獲取不到源碼,推薦使用objcopy
淆攻,直接對沖突的符號添加前綴或后綴阔墩,以此修改符號
$ llvm-objcopy --prefix-symbols=Cat...
我們發(fā)現(xiàn)llvm-objcopy
命令并不支持MachO文件格式,可以使用下面命令
$ llvm-objcopy --redefine-sym "_OBJC_CLASS_$_AFURLSessionManager"="Cat__OBJC_CLASS_$_AFURLSessionManager"...
成功修改第一個符號的前綴瓶珊,接下來只需要把后面兩個符號前綴修改啸箫,即可解決符號沖突
$ nm -gUAj .a路徑
顯示.a文件內(nèi)所有的全局符號
此時把libAFNetworking2.a
導(dǎo)入Frameworks
目錄下,Cmd + B編譯成功
二. 解決符號沖突原因&腳本
上面我們把符號_OBJC_CLASS_$_AFURLSessionManager
改成了Cat_OBJC_CLASS_$_AFURLSessionManager
伞芹,Cat_OBJC_CLASS_$_AFURLSessionManager
已經(jīng)不屬于OC的符號了忘苛,因為前綴發(fā)生了變化,底層已經(jīng)解析不出來了。所以OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking"
鏈接器在去鏈接AFNetworking2
的時候扎唾,發(fā)現(xiàn)不是OC的符號蜀肘,編譯器會把Cat_OBJC_CLASS_$_AFURLSessionManager
strip掉。
搜索可執(zhí)行文件LGTestApp
帶Cat
的符號稽屏,并沒有找到扮宠,確定編譯器把Cat_OBJC_CLASS_$_AFURLSessionManager
strip掉了
修改OTHER_LDFLAGS = $(inherited) -all_load -l"AFNetworking"
發(fā)現(xiàn)定義的全局符號global_function
以及包含Cat
的符號都存在。
思考一下
上面的靜態(tài)庫AFNetworking2
中符號比較少狐榔,只報了三個符號沖突坛增,當(dāng)沖突的符號比較多時,我們不能一個個的添加前綴或后綴薄腻,那么該怎么解決呢收捣?
- 方法一 首先查看
libAFNetworking.a
靜態(tài)庫的全局符號
$ nm -gUAj libAFNetworking.a路徑
發(fā)現(xiàn)每個符號所在路徑并不相同,我們只需要對符號拼接前綴庵楷,放入原本的路徑即可罢艾,所以我們可以編寫腳本使用正則表達(dá)式
來實現(xiàn)
// main.py腳本內(nèi)容如下
import subprocess
import re # 正則相關(guān)的方法
# path表示路徑,使用nm命令把該路徑的靜態(tài)庫符號輸出
def getSymbols(path):
# 在當(dāng)前進(jìn)程中執(zhí)行命令輸出靜態(tài)庫的符號
# f表示格式化字符串
return subprocess.getoutput(f'nm -gUAj {path}')
# 也可以這樣寫 return subprocess.getoutput("nm -gUAj {}".format(path))
# 修改完成之后輸出到新的路徑尽纽,把上圖中 ‘ ___destory_helper_block_e8_32s’前面的路徑設(shè)置為空咐蚯,這里只需要替換一下
def writeNewSymbolsToFile(syms, path, newPath)
# r表示單引號里面是一個正則表達(dá)式,下面的正則表達(dá)式就能完整匹配到‘ ___destory_helper_block_e8_32s’前面的路徑
newStr = re.sub(rf'{path}[:](.+)(.o: )', '', syms)
# 把上面字符串按照換行符分割成數(shù)組
lines = newStr.splitlines()
newSys = ''
for s in lines:
# 去掉字符串中的換行符
word = s.strip('\n')
newSys += word + ' ' + f'_Cat{word}' + '\n'
print(newSys)
# 打開newPath路徑弄贿,默認(rèn)創(chuàng)建w文件
with open(newPath, 'w') as file:
# 文件寫入newPath
file.write(newSys)
_OBJC_CLASS_$_AFAutoPurgingImageCache _Cat_OBJC_CLASS_$_AFAutoPurgingImageCache
_OBJC_CLASS_$_AFCachedImage _Cat_OBJC_CLASS_$_AFCachedImage
_OBJC_IVAR_$_AFAutoPurgingImageCache._cachedImages _Cat_OBJC_IVAR_$_AFAutoPurgingImageCache._cachedImages
...
我們發(fā)現(xiàn)符號名稱成功修改春锋,此時Cmd + B編譯成功
- 方法二 現(xiàn)在是兩個不同名字,相同符號的靜態(tài)庫差凹,可以把一個靜態(tài)庫改成動態(tài)庫期奔,就可以解決符號沖突的問題
platform :ios, '14.0'
target 'LGTestApp' do
use_frameworks!
pod 'AFNetworking'
end
三. Git集中式開發(fā)
首先我們來創(chuàng)建一個遠(yuǎn)程倉庫,桌面創(chuàng)建目錄遠(yuǎn)程倉庫
并進(jìn)入危尿,在遠(yuǎn)程倉庫
目錄下創(chuàng)建兩個目錄CT.Remote
HK.Remote
// 進(jìn)入CT.Remote目錄呐萌,初始化遠(yuǎn)程倉庫
$ cd /Users/wn/Desktop/遠(yuǎn)程倉庫/CT.Remote
// 初始化Git倉庫,初始化完成之后谊娇,其他地方的代碼就可以push到這個倉庫
$ git init --bare
Initialized empty Git repository in /Users/wn/Desktop/遠(yuǎn)程倉庫/CT.Remote/
// 進(jìn)入HK.Remote目錄肺孤,初始化遠(yuǎn)程倉庫
$ cd /Users/wn/Desktop/遠(yuǎn)程倉庫/HK.Remote
$ git init --bare
Initialized empty Git repository in /Users/wn/Desktop/遠(yuǎn)程倉庫/HK.Remote/
接下來在桌面創(chuàng)建集中式開發(fā)
目錄,并在里面分別創(chuàng)建兩個目錄CT
HK
邮绿,在CT
目錄里面創(chuàng)建空工程LGClass
// LGClass工程中的ViewController.swift類中打印幾句話
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("Hello Cat!")
print("Hello Dog!")
}
}
然后使用git命令分別初始化環(huán)境
$ cd /Users/wn/Desktop/集中式開發(fā)/CT
$ git init
Initialized empty Git repository in /Users/wn/Desktop/集中式開發(fā)/CT/.git/
// 查看是否添加過遠(yuǎn)程倉庫
$ git remote
// 在當(dāng)前目錄添加一個遠(yuǎn)程倉庫渠旁,origin給遠(yuǎn)程倉庫起別名
$ git remote add origin /Users/wn/Desktop/遠(yuǎn)程倉庫/CT.Remote
// 查看到遠(yuǎn)程倉庫origin
$ git remote
origin
// 再添加一個遠(yuǎn)程倉庫
$ git remote add originHK /Users/wn/Desktop/遠(yuǎn)程倉 庫/HK.Remote
// 查看到有兩個遠(yuǎn)程倉庫,意味著當(dāng)前CT目錄下的代碼可以往push到兩個遠(yuǎn)程倉庫
$ git remote
origin
originHK
// 添加到暫存區(qū)并提交代碼
$ git add .
$ git commit -m 'init commit'
[master (root-commit) a4ca154] init commit
16 files changed, 730 insertions(+)
create mode 100644 LGClass/LGClass.xcodeproj/project.pbxproj
create mode 100644 LGClass/LGClass.xcodeproj/project.xcworkspace/contents.xcworkspacedata
create mode 100644 LGClass/LGClass.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
create mode 100644 LGClass/LGClass.xcodeproj/project.xcworkspace/xcuserdata/wn.xcuserdatad/UserInterfaceState.xcuserstate
create mode 100644
...
// 查看當(dāng)前分支
$ git branch
* master
// push到指定的遠(yuǎn)程倉庫船逮,下面報錯提示沒有指定push到遠(yuǎn)程倉庫的哪個分支
$ git push origin
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin master
// push到origin遠(yuǎn)程倉庫的master分支
$ git push --set-upstream origin master
Enumerating objects: 32, done.
Counting objects: 100% (32/32), done.
Delta compression using up to 4 threads
Compressing objects: 100% (28/28), done.
Writing objects: 100% (32/32), 23.48 KiB | 3.35 MiB/s, done.
Total 32 (delta 2), reused 0 (delta 0)
To /Users/wn/Desktop/遠(yuǎn)程倉庫/CT.Remote
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
// 進(jìn)入遠(yuǎn)程倉庫查看提交
$ cd /Users/wn/Desktop/遠(yuǎn)程倉庫/CT.Remote
$ git log
commit a4ca154e8956919d3ee63392788258859afc3dc8 (HEAD -> master)
Author: wn <chris.wang@pingcoo.com>
Date: Sat May 8 22:25:07 2021 +0800
init commit
// 提交到遠(yuǎn)程倉庫originHK的master分支
$ cd /Users/wn/Desktop/集中式開發(fā)/CT
$ git push --set-upstream originHK master
Enumerating objects: 32, done.
Counting objects: 100% (32/32), done.
Delta compression using up to 4 threads
Compressing objects: 100% (28/28), done.
Writing objects: 100% (32/32), 23.48 KiB | 2.94 MiB/s, done.
Total 32 (delta 2), reused 0 (delta 0)
To /Users/wn/Desktop/遠(yuǎn)程倉庫/HK.Remote
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'originHK'.
現(xiàn)在想要在集中式開發(fā) -> HK
目錄下也提交代碼顾腊,操作如下
$ cd /Users/wn/Desktop/集中式開發(fā)/HK
$ git init
Initialized empty Git repository in /Users/wn/Desktop/集中式開發(fā)/HK/.git/
$ git remote add -t master origin /Users/wn/Desktop/遠(yuǎn)程倉庫/CT.Remote
// 成功從遠(yuǎn)程倉庫origin中拉下來代碼
$ git pull
remote: Enumerating objects: 32, done.
remote: Counting objects: 100% (32/32), done.
remote: Compressing objects: 100% (28/28), done.
remote: Total 32 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (32/32), done.
From /Users/wn/Desktop/遠(yuǎn)程倉庫/CT.Remote
* [new branch] master -> origin/master
Fast-forwrod merge:
CT
目錄下成功拉下來LGClass
工程代碼,現(xiàn)在修改代碼如下
// LGClass工程中的ViewController.swift類中打印幾句話
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("Hello Cat!")
print("Hello Dog!")
print("Hello Tiger!")
}
}
$ cd /Users/wn/Desktop/集中式開發(fā)/CT
$ git add .
$ git commit -m 'add tiger'
[master 122e218] add tiger
2 files changed, 1 insertion(+), 5 deletions(-)
rewrite LGClass/LGClass.xcodeproj/project.xcworkspace/xcuserdata/wn.xcuserdatad/UserInterfaceState.xcuserstate (76%)
// 成功提交一次
$ git push
Enumerating objects: 19, done.
Counting objects: 100% (19/19), done.
Delta compression using up to 4 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (10/10), 6.14 KiB | 3.07 MiB/s, done.
Total 10 (delta 4), reused 0 (delta 0)
To /Users/wn/Desktop/遠(yuǎn)程倉庫/HK.Remote
a4ca154..122e218 master -> master
// 查看遠(yuǎn)程提交記錄挖胃,發(fā)現(xiàn)遠(yuǎn)程master分支記錄線條是直的杂靶,這就是單人開發(fā)Fast-forwrod merge形式
$ git log --oneline --decorate --graph --stat
* 761a65c (HEAD -> master) add tiger
| .../UserInterfaceState.xcuserstate | Bin 13336 -> 16644 bytes
| LGClass/LGClass/ViewController.swift | 6 +-----
| 2 files changed, 1 insertion(+), 5 deletions(-)
* a4ca154 (origin/master) init commit
LGClass/LGClass.xcodeproj/project.pbxproj | 344 ++++++++++++++++++++
.../project.xcworkspace/contents.xcworkspacedata | 7 +
.../xcshareddata/IDEWorkspaceChecks.plist | 8 +
.../UserInterfaceState.xcuserstate | Bin 0 -> 13336 bytes
.../ws.xcuserdatad/UserInterfaceState.xcuserstate | Bin 0 -> 15456 bytes
.../xcschemes/xcschememanagement.plist | 14 +
.../xcschemes/xcschememanagement.plist | 14 +
LGClass/LGClass/AppDelegate.swift | 36 ++
.../AccentColor.colorset/Contents.json | 11 +
.../AppIcon.appiconset/Contents.json | 98 ++++++
LGClass/LGClass/Assets.xcassets/Contents.json | 6 +
.../LGClass/Base.lproj/LaunchScreen.storyboard | 25 ++
LGClass/LGClass/Base.lproj/Main.storyboard | 24 ++
LGClass/LGClass/Info.plist | 66 ++++
LGClass/LGClass/SceneDelegate.swift | 52 +++
LGClass/LGClass/ViewController.swift | 25 ++
16 files changed, 730 insertions(+)
// 也可以用glola的全寫形式查看提交記錄梆惯,發(fā)現(xiàn)遠(yuǎn)程master分支記錄線條是直的,這就是單人開發(fā)Fast-forwrod merge形式
$ git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --all
* 122e218 - (HEAD -> master, originHK/master) add tiger (15 minutes ago) <wn>
* a4ca154 - (origin/master) init commit (54 minutes ago) <wn>
- Fast-forwrod merge: 綠色表示遠(yuǎn)程分支吗垮,藍(lán)色表示提交到遠(yuǎn)程的本地分支垛吗,push的時候這倆分支需要進(jìn)行合并,這時發(fā)現(xiàn)遠(yuǎn)程分支后面并沒有新的提交烁登,那么直接把本地提交的代碼合并到遠(yuǎn)程分支后面怯屉,這就是Fast-forwrod merge
多人開發(fā)
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("Hello Cat!")
print("Hello Dog!")
print("Hello Elephant!")
}
}
$ cd /Users/wn/Desktop/集中式開發(fā)/HK
$ git add .
$ git commit -m 'add Elephant'
[master bd5950d] add Elephant
2 files changed, 5 insertions(+), 1 deletion(-)
rewrite LGClass/LGClass.xcodeproj/project.xcworkspace/xcuserdata/wn.xcuserdatad/UserInterfaceState.xcuserstate (94%)
$ git log --oneline --decorate --graph --stat
* bd5950d (HEAD -> master) add Elephant
| .../UserInterfaceState.xcuserstate | Bin 16644 -> 16909 bytes
| LGClass/LGClass/ViewController.swift | 6 +++++-
| 2 files changed, 5 insertions(+), 1 deletion(-)
* a4ca154 (origin/master) init commit
LGClass/LGClass.xcodeproj/project.pbxproj | 344 ++++++++++++++++++++
.../project.xcworkspace/contents.xcworkspacedata | 7 +
.../xcshareddata/IDEWorkspaceChecks.plist | 8 +
.../UserInterfaceState.xcuserstate | Bin 0 -> 13336 bytes
.../ws.xcuserdatad/UserInterfaceState.xcuserstate | Bin 0 -> 15456 bytes
.../xcschemes/xcschememanagement.plist | 14 +
.../xcschemes/xcschememanagement.plist | 14 +
LGClass/LGClass/AppDelegate.swift | 36 ++
.../AccentColor.colorset/Contents.json | 11 +
.../AppIcon.appiconset/Contents.json | 98 ++++++
LGClass/LGClass/Assets.xcassets/Contents.json | 6 +
.../LGClass/Base.lproj/LaunchScreen.storyboard | 25 ++
LGClass/LGClass/Base.lproj/Main.storyboard | 24 ++
LGClass/LGClass/Info.plist | 66 ++++
LGClass/LGClass/SceneDelegate.swift | 52 +++
LGClass/LGClass/ViewController.swift | 25 ++
16 files changed, 730 insertions(+)
// 此時push到遠(yuǎn)程會報錯,提示我們遠(yuǎn)程分支有了新的提交饵沧,在push之前要先git pull 下來代碼
$ git push --set-upstream origin master
锨络![rejected] master -> master (fetch first)
error: failed to push some refs to /Users/wn/Desktop/遠(yuǎn)程倉庫/HK.Remote
hint: Updates were rejected because the remote contains work that you do
hint: (e.g.,’git pull …’) before pushing again
...
// 拉代碼的時候產(chǎn)生了沖突
$ git pull origin master
From /Users/wn/Desktop/遠(yuǎn)程倉庫/HK.Remote
* branch master -> FETCH_HEAD
Auto-merging LGClass/LGClass/ViewController.swift
CONFLICT (content): Merge conflict in LGClass/LGClass/ViewController.swift
Automatic merge failed; fix conflict and then commit the result.
// 此時產(chǎn)生了沖突
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("Hello Cat!")
print("Hello Dog!")
<<<<<<< HEAD
print("Hello Tiger!")
=======
print("Hello Elephant!")
>>>>>>> CommitID
}
}
// 手動解決完上面沖突之后提交代碼
$ git commit -m 'new merge'
- git pull 有兩個命令狼牺,一個git fetch 一個git merge
- git fetch 之后本地有兩個master分支羡儿,一個遠(yuǎn)程一個本地。
// 此時查看遠(yuǎn)程提交記錄是钥,發(fā)現(xiàn)遠(yuǎn)程master分支多了個分支記錄
$ git log --oneline --decorate --graph --stat
// 下面我們來把上面的merge多出來的線條擼直
// 回到commit之前的狀態(tài)掠归,也就是上一個HEAD
$ git rev-parse ORIG_HEAD
761a65cbef6d7bbe6403c3c7aac5051eb70ecc93
// 這時就恢復(fù)到git pull拉取遠(yuǎn)程分支之前的狀態(tài)
$ git reset --hard ORIG_HEAD
// 表示當(dāng)前分支要添加到遠(yuǎn)程分支后面
$ git pull origin master --rebase
// 查看沖突解決沖突
$ git mergetool
// 添加到暫存區(qū),并且添加到遠(yuǎn)程分支后面
$ git add .
$ git rebase --continue
// 此時查看遠(yuǎn)程提交記錄悄泥,發(fā)現(xiàn)遠(yuǎn)程master分支成功擼直
$ git log --oneline --decorate --graph --stat
// 成功解決
$ git push
// 舉例
// 表示當(dāng)前分支與dog分支進(jìn)行合并虏冻,merge與rebase剛好相反
$ git merge dog
- rebase 不是創(chuàng)建一個新的commit,而是將指定的分支放到另一個分支的結(jié)尾
小提示
分支上面保存的是最后一次提交码泞,并不是所有的提交兄旬,branch本質(zhì)上表示當(dāng)前分支的最后一次提交,本地的dev分支提交到遠(yuǎn)程的dev分支余寥,會發(fā)生一次合并