我正在结束在dev
分支上开发的应用程序的构建,现在想将其添加到master
进行生产。
但是,当我结帐到master
并运行git merge dev
时,收到致命错误refusing to merge unrelated histories
。不幸的是,git pull origin master --allow-unrelated-histories
didn't help resolve the error。
这是master
的状态:
git status
显示我的“分支机构的'origin / master'是最新的”。README.md
。帮助我了解为什么我无法合并。
编辑:我还应该提到git log
会产生以下结果:
commit ac22443836aeaf8abe38aa3761970a4cd3835587 (HEAD -> master, origin/master)
Author: // my info
Date: Fri Dec 21 03:25:26 2018 -0700
Initial commit
(END)
答案 0 :(得分:0)
如果必须使用import React from 'react';
import { createStackNavigator, createSwitchNavigator, createAppContainer } from 'react-navigation';
...
const MainStack = createSwitchNavigator(
{
Home: HomeStack,
Auth: AuthStack
},
{
initialRouteName: 'Home'
}
);
const AppContainer = createAppContainer(MainStack);
class Main extends React.Component {
constructor(props) {
super(props);
}
componentDidMount = () => {
var that = this;
firebase.auth().onAuthStateChanged(async function(user) {
if (user) {
await that.props.getUserProfile(user.uid);
} else {
that.navigation.navigate('Auth');
}
})
}
render() {
return (
<AppContainer />
);
}
}
const mapStateToProps = state => {
return {
user: state.auth.user
}
}
export default connect(mapStateToProps, {getUserProfile})(Main);
,则意味着您实际上拥有合并在一起的两个不同存储库的等效内容。
我怀疑这是因为您在创建dev分支并进行工作之前没有先--allow-unrelated-hhistories
原始仓库。我从您的描述中得出的推论是,您做了一个clone
,签出了一个git init
分支,然后在想要合并时将远程仓库添加为dev
(这很有效,因为您的本地仓库没有遥控器。
尝试在此时合并将获得“无关的历史记录”,因为实际上这两个存储库无关。原始文件被创建并推送到GitLab,当您执行origin
创建本地文件时,创建了一个完全独立的文件。克隆原始文件将创建与相关的本地存储库,因为它共享了最初的git init
提交。
确实,这是解决此问题的唯一方法,一旦您推送到GitLab,本地和远程将同步-但是您应该始终进行克隆以避免出现此问题。
答案 1 :(得分:0)
如果像据说的那样,master
和dev
没有共同的(父)提交,那么我将尝试从master
创建一个新分支,然后全部选中从dev
提交到它:
git cherry-pick startHash^..endHash
例如git cherry-pick 1234^..5678
。
然后,您应该可以将此新分支合并到master
答案 2 :(得分:0)
创建存储库时,您可能已选中“ []使用自述文件创建存储库”。
当master
确实为空时,我看到以下选项
转到gitlab,将默认分支更改为其他分支,然后在Web界面中删除master分支(可以删除受保护的分支)。或者,
取消保护master
现在,您可以将dev
分支强制推到gitlab(例如git push -f dev:master
)。
注意:此选项对于分支机构而言是不可行的。其他人使用的存储库。在这种情况下,请执行以下操作:
git fetch gitlab master
git merge -s ours FETCH_HEAD
并推动此分支。
答案 3 :(得分:0)
您已经使用--allow-unrelated-histories
修复了(?),没有真正的理由不放弃它。但是如果您仍然想知道...
使用Git的第一个关键是要了解Git与 commits 有关。当然,这还要求您以某种相当深入的方式理解 是什么。它是什么,很简短,很简单:它是一个永久(主要)和不可变(整个)快照和一些元数据。快照包含您的所有文件-以及提交时的所有文件-元数据具有:
每个提交都是唯一的(由于许多原因,包括上述时间戳记),每个唯一提交都具有唯一的哈希ID。该哈希ID(一个大的丑陋的十六进制字符字符串)似乎是随机的,但实际上是提交的 contents 的加密校验和。它实际上也是该提交的真实名称:该ID 表示该提交,并且仅该提交。没有其他提交将具有该哈希ID。该哈希ID始终表示那个提交。
Git实际上通过哈希ID来找到提交。因此,哈希ID至关重要。当然,人类也无法记住。因此,Git为我们提供了一种记住最新哈希ID的方法,这种方式就是分支名称,例如master
或dev
。
名称仅需记住 last 提交,因为每个提交都可以自己记住其父级的哈希。就是说,给定一个只有三个提交的小型存储库,我们用一个大写字母替换实际的哈希ID,我们可以这样绘制:
A <-B <-C <-- master
名称master
记住C
的哈希ID。 C
本身(通过哈希ID检索的实际提交)会记住B
的哈希ID,而B
本身会记住A
的哈希ID。
当某些东西记住其他提交的哈希ID时,我们说这是指向的提交。因此,名称master
指向C
,C
指向B
,而B
指向A
。这三个提交-C
,然后是B
,然后是A
- 是存储库中的历史记录。
请注意,A
并未指向任何地方。从字面上讲是不可以的,因为这是第一次提交。没有更早的提交。因此,事实并非如此,Git将此称为 root 提交。所有非空存储库都必须至少具有一个root提交。多数人可能只有一个……而您的却只有两个。
让我们快速了解制作分支的更常规方法。假设我们只有master
所指向的这三个提交。我们要求Git创建一个 new 分支名称,指向与master
相同的提交:
A--B--C <-- dev (HEAD), master
这两个名称都标识提交C
,因此,提交C
都在两个分支上,并且都是 tip提交,这两个分支都在这两个分支上。但是现在我们重新提交。使用常规编辑以及git add
和git commit
进行新提交的过程将创建新快照,添加我们的姓名,电子邮件和时间戳等,并使用 current 提交C
作为已保存的哈希,并构建新的提交。新的提交有一些笨拙的哈希ID,但我们将其称为D
:
A--B--C <-- dev (HEAD), master
\
D
由于D
的父母是C
,因此D
指向C
。但是现在神奇的事情发生了:Git将D
的哈希ID写入当前的分支名称(附加了一个HEAD
),现在我们有了:
A--B--C <-- master
\
D <-- dev (HEAD)
,瞧,我们有一个新的分支。 (好吧,我们之前曾提到过C
。尽管大多数人不喜欢这样思考,但他们想调用D
分支。实际上,分支是{{ 1}}!)
随着时间的流逝,我们向两个分支都添加了一些提交:
D-C-B-A
我们A--B--C-----J----K----L <-- master
\
D--E--F--G--H--I <-- dev
和git checkout master
。 Git将为我们找到合并基础提交,其中git merge dev
和dev
不同。那显然是提交master
,因为那是过去两个分支重新结合的地方。 Git将比较C
与C
来了解我们在L
上所做的更改,比较master
与C
来了解我们在I
上所做的更改,并合并更改。 Git将 combined 更改应用于 dev
中的快照(应用于合并基础),并进行新的 merge commit {{1 }}照常在我们当前的C
分支上进行,更新该分支的名称,以便M
指向HEAD
:
master
M
的特殊之处在于它具有两个向后链接:就像所有提交一样,它返回到A--B--C-----J----K----L--M <-- master (HEAD)
\ /
D--E--F--G--H--I <-- dev
,但是它有第二个父级{{1 }},这是分支M
的当前提示提交。但是,除了两个父母之外,它很普通:它具有照常拍摄的快照,以及我们的姓名,电子邮件和时间戳以及一条日志消息。
Git中没有任何东西可以阻止您进行额外的root提交。有点棘手。假设以某种方式,您这样做:
L
一旦遇到这种情况,I
只会给您一个错误。这是因为查找合并基础的常用方法(从两个分支技巧开始并向后工作)永远找不到共同的提交。
添加dev
告诉Git 假装在两个分支之前 有一个特殊的空提交:
A <-- master
B--C--D--...--L <-- dev (HEAD)
现在,Git可以比较git checkout master; git merge dev
与--allow-unrelated-histories
来查看您在 A <-- master (HEAD)
0
B--C--D--...--L <-- dev
上所做的更改,以及0
与A
来查看它们在{{ 1}}。在master
上,您添加了每个文件。在0
上,您还添加了每个文件。只要它们是不同的文件,组合这两个更改的方法就是将L
提交的dev
文件添加到master
提交的{ {1}},将这些更改应用于空的null提交,然后提交结果,并让父母回到dev
和master
:
A
有一个dev
选项L
,用于设置此状态。但这可能不是您所做的。设置的状态是使用A
创建新的空存储库时所处的相同状态:
L
没有分支机构,但是Git会说您是A---------------M <-- master (HEAD)
/
B--C--D--...--L <-- dev
。您不能在git checkout
上:它不存在。但是您是,即使它不存在。 Git管理此问题的方式是将名称 git checkout --orphan
放入git init
(实际上是[no commits] <-- [no branches]
)中,而无需首先创建名为on branch master
的分支。它无法创建分支,因为分支名称必须包含有效的哈希ID,并且没有。
因此,当您运行master
时,Git会检测到此异常状态:master
表示HEAD
但.git/HEAD
不存在。这就是触发Git进行我们的根提交master
的原因。然后,Git将git commit
的哈希ID写入分支,它创建分支,现在我们有了:
HEAD
这正是我们想要的。
但是假设,当我们处于这种奇怪的尚未提交状态时,我们运行:
master
这告诉Git:将名称master
放入A
中。即使没有A
,它也可以毫无抱怨地做到这一点。然后我们进行第一次提交,但出于显而易见的原因,我们选择A <-- master (HEAD)
作为其哈希ID的单字母替代:
git checkout -b dev
同时,先在这里运行dev
,然后运行HEAD
,然后执行一些操作,然后master
,我们将转到$ WebHostingProvider-无论是GitHub还是GitLab或Bitbucket或其他任何东西-并使用其为我建立新的存储库 clicky按钮。它们通常具有一个选项:使用README和/或LICENSE文件等创建初始提交。如果该选项被选中-或者未选中不选项-则继续进行第一次提交和B
:
B <-- dev (HEAD)
现在,您将存储库连接到他们的存储库,并让Git下载他们没有的任何提交:
git init
您现在可以继续添加大量提交,而无需注意您的git checkout -b dev
分支与其git commit
分支(您的Git正在调用master
)无关。
稍后,您运行:
A <-- master (HEAD)
您的Git通知您没有 A <-- origin/master
B <-- dev (HEAD)
,但是您确实有dev
。因此,您的Git为您创建一个master
,指向与origin/master
相同的提交,并将您的git checkout master
附加到新的master
上: / p>
origin/master
和瞧,你在泡菜里。