我已经看了很多关于如何使用Git进行改组的文章,这是有意义的......或者至少我认为它确实如此。但是,我正在努力解决以下问题......
对于这种情况,我们有以下分支:
好的,现在让我们说origin / master提前1次提交。所以,我从文章中得知,我正在开发的开发团队是在jheigs分支上做以下事情:
$ git add ...
$ git commit ...
$ git status (ensure everything is up-to-date locally)
$ git pull (again, check and ensure that everything is ready to go)
$ git pull --rebase origin master
$ git push (defaulting to origin/jheigs)
当rebase运行正常时,我遇到的是origin / jheigs和本地jheigs有HEAD提交不匹配(给定上面的rebase),所以有时我可能需要拉,然后推,这可能会导致冲突。我感到困惑的是......我应该使用:
$ git push --force origin jheigs (?)
第二个问题......现在,让我们说我已经推动并且jheigs已经使用origin / master正确地重新定位了。没有冲突存在,我的jheigs和origin / jheigs现在领先于1次提交。好的,过了一天,我需要做出更多改变。所以我在jheigs上进行了这些更改并添加/ commit。但是,origin / master没有其他更新。从本质上讲,我仍然领先于origin / master的1次提交(很快就会是2次)。我仍然遵循上述相同的流程吗?或者我只是添加/提交并推送到origin / jheigs而不进行重新定位,因为我已经领先于origin / master?
我很抱歉这是如此之长,但我想我已经想到了这一点并且它不像我想象的那么顺利。我想小心变基础,所以感谢任何帮助!
答案 0 :(得分:2)
嗯,首先,我会(并且确实)完全避免git pull
,或者大多数:它本来是方便的,但事实证明 方便。它只运行git fetch
,然后是第二个Git命令,它会影响您检出的任何分支。有时我不想要或不需要取物;其他时候,我想环顾一下发生了什么当 fetch运行时,之前我做任何第二个命令来影响当前分支。
正如您可能已经阅读过的那样,git rebase
实际上是关于复制(某些)提交。你的存储库中有一些提交集合,现在,无论出于什么原因,一些提交都没有亮相,你想要做出更新,更好,更漂亮,更有光泽的提交。
使所有这些有意义的方法是绘制提交图。请记住,有多个克隆 - 不同的存储库包含大多数相同的提交集,但不完全相同的集合涉及!
您可以让Git为您执行此操作:git log --all --decorate --oneline --graph
或git log(with)A DOG。不过,一开始手工做是很好的锻炼。此外,当你手工完成时,你可以水平绘制它们,这往往更有意义。
请记住,每个由其唯一哈希ID标识的提交都是只读的。每个提交都指向其父提交。分支名称(如master
或jheigs
)或远程跟踪名称(如origin/master
或origin/jheigs
,指向(记录哈希ID) )提示提交,Git从这些提示向后工作:
...--C--D--E <-- master
\
F--G <-- jheigs (HEAD)
这可能是存储库的图形片段,其中提交E
是master
的提示,而E
指向D
,而您是添加了两个自己的提交:G
,这是jheigs
的提示,并指向F
,之前,您添加F
指向{{1} }}
请注意,此处,提交D
及更早版本位于两个分支上。
D
会将 1 的一些提交复制到新的和改进的提交中。例如,您可能希望将git rebase
复制到新的F
,其主要区别在于F'
附加到F'
,而不是E
{1}}:
D
将 F' [new and improved!]
/
...--C--D--E <-- master
\
F--G <-- jheigs (HEAD)
复制到F
后,您现在可以将F'
复制到新版本G
:
G'
现在所有的提交都是&#34; on&#34; (可从 F'-G' [new and improved!]
/
...--C--D--E <-- master
\
F--G <-- jheigs (HEAD)
到达,但jheigs
上的不已被复制到新版本,您可以让Git剥离master
标签关闭提交jheigs
并将其粘贴到G
:
G'
旧的,沉闷的 F'-G' <-- jheigs (HEAD)
/
...--C--D--E <-- master
\
F--G [abandoned]
和F
提交昨天如此闪亮和好看,现在是垃圾,取而代之的是闪亮的新G
和F'
。这是因为您的分支名称G'
现在指向最后一个新复制的提交。
1 此复制就像jheigs
一样完成。根据您使用的rebase命令,实际上 可以使用git cherry-pick
完成。
git cherry-pick
和fetch
上图是您的存储库,但此处涉及第二个存储库。他们有自己的分支名称和他们自己的提交。您拥有的提交也是共享提交哈希ID。你可能会有一些他们不承认的承诺;可能会有一些他们认为你没有的承诺。
如果您认为他们可能会提交您的承诺,则应该运行push
或git fetch
。这让你的Git在名为git fetch origin
的名单下的URL中调用他们的Git。你的Git调用他们的Git并让他们列出他们的分支名称给出的所有提交(按哈希ID)。
如果他们有你没有的提交,你的Git现在会下载这些提交。您的Git也更改其分支机构名称,例如origin
或master
,以便他们阅读jheigs
和origin/master
。这些新名称不会干扰您的分支名称。
现在你已经拥有了他们拥有的所有提交,以及之前提交的所有提交,你的存储库可能看起来像这样 - 让我们假设你还没有完成origin/jheigs
但是:
git rebase
您的 H <-- origin/master
/
...--C--D--E <-- master
\
F--G <-- jheigs (HEAD), origin/jheigs
是您的 分支机构名称的Git记忆。这意味着他们的 origin/*
标识了提交master
。您已经提交了H
,感谢H
。 他们的 git fetch
标识提交jheigs
,就像你的一样。
如果您现在运行G
,您的Git会将您的git rebase master
和F
复制到新的G
和F'
,并在提交后生成G'
{1}},这是E
点的地方。您可能希望在提交master
之后让它们出现。
在这里,您可以非常轻松地执行此操作:您只需运行H
即可。这告诉你的Git找到你的git rebase origin/master
提交的提交(即F
和G
) origin/master
(即master
无论如何,你可以记住)并在提交H
之后放置副本。结果如下:
F'-G' <-- jheigs (HEAD)
/
H <-- origin/master
/
...--C--D--E <-- master
\
F--G <-- origin/jheigs
请注意,origin/*
名称均未移动,您自己的master
也未移动。但是,您调用jheigs
的他们的 origin/jheigs
仍会记住提交G
。
现在您需要git push --force jheigs
,告诉他们:丢弃提交F
和G
,转而支持新的F'
和G'
。一旦他们同意这样做,你的Git会记住他们的jheigs
指向G'
:
F'-G' <-- jheigs (HEAD), origin/jheigs
/
H <-- origin/master
/
...--C--D--E <-- master
由于没有名称可以找到它们,因此提交F
和G
似乎完全消失。
请注意,可能有第三个 Git存储库,第四个或更多存储库,其中包含另一个origin/jheigs
。如果是这样,所有其他存储库必须采取某些操作(例如运行git fetch
)以获取新提交并更新其自己的origin/jheigs
名称。
此外,他们可能已经在您的提交之上构建了自己的提交,然后您决定抛弃您的提交以支持新的和改进的提交。如果是这样,他们可能会被迫复制他们的提交,就像您复制了他们一样。这甚至可能是一件好事,或者可能让他们恼火。
因此,如果您要重新提交其他人拥有或可能拥有的提交,您应该合理地确定为他们工作是可以的。如果没有其他人拥有原始提交,那么复制和替换它们显然是安全的。如果其他人都同意这种复制替换假设发生,那么它仍然没问题。如果这样做可以改变,那么这样做是否有意义。
答案 1 :(得分:0)
当rebase运行良好时,我遇到的是origin / jheigs和本地jheigs的HEAD提交不匹配(给定上面的rebase)
是的,但区别在于你额外的非推动工作。在git pull --rebase
之后,上游HEAD将是您本地HEAD的祖先。
因此有时我可能需要拉动然后按
这通常是正确的做法
可能会导致冲突。
它不应该,除非有人在你的拉动和推动之间推动(在这种情况下,你需要再次进行,以结合他们的工作)。
好的,过了一天,我需要做出更多改变。所以我在jheigs上进行了这些更改并添加/ commit。但是,origin / master没有其他更新。从本质上讲,我仍然领先于origin / master的1次提交(很快就会是2次)。我仍然遵循上述相同的流程吗?或者我只是添加/提交并推送到origin / jheigs而不进行重新定位,因为我已经领先于origin / master?
要么是好的。如果上游尚未移动,git pull --rebase
将无效。