将更改从“主”转移到我的分支

时间:2018-08-16 12:15:06

标签: git merge rebase pull-request pull

我的存储库中的网络图如下:

M--------------M
|              ↑
├-->1---1---1--┘
|
└-->2---2

其中:Mmaster上的推送提交,1branch-1上的推送提交,而2branch-2上的推送提交。

如您所见,来自branch-1的提交被推送,请求“拉出请求”并合并到master中。

我在branch-2上,我正在执行任务。

我需要掌握源代码才能完成它们。

第一个问题:我应该怎么做才能将源代码从master传输到我的branch-2

我正在考虑:

git fetch origin
git rebase origin/master

或:

git pull origin --rebase master

第二个问题:如果在branch-2上进行第二次提交后发生本地更改,该怎么办?我想做与上述相同的事情?

2 个答案:

答案 0 :(得分:1)

更新-我忘了回答第二个问题


第一个问题

您既可以将master合并到分支中,也可以将rebase分支合并到主节点上的以后提交,或者cherry-pick引入需要的更改的提交。该做什么取决于您(和您的团队,如果适用)要使用哪种工作流程。

merge的优点是它不会重写任何历史记录,并且不会重复任何提交。在某些方面,它是最简单的操作,但确实会创建许多人认为更复杂的历史。 (对于哪种历史记录“更好”,没有一个客观的答案;这取决于您如何使用历史记录。)如果决定合并,则可以执行类似的操作

git checkout branch-2
git merge master

这假设您的本地管理员是最新的。如果不是,您可以更新它,也可以

git fetch
git checkout branch-2
git merge origin/master

默认情况下,pull是“ fetchmerge”的快捷方式,因此您也可以这样做

git checkout branch-2
git pull origin/master

我个人通常不以这种方式使用pull;仅在从上游更新分支时才使用它。但这仍然是一个有效的选择。

rebase的优点在于,它避免了合并提交,并且创建了一些人更喜欢的线性历史记录,并且通常不需要您保留重复的提交(即,它会创建提交的副本,但是完成后,您通常可以丢弃原件)。历史记录无法反映软件的实际编写方式,特别是它可能包含无法干净构建的提交,即使您以其他方式维护“干净签入”策略也是如此。这是一个历史重写;如果您rebase的分支已经与其他人共享(即在任何时候都被push绑定到原点),则可能会引起问题[1]。

如果您决定进行变基,可以说

git rebase master branch-2

与合并一样,您可以首先fetch, and update母版from its upstream or substitute起源/母版for母版as needed. You can also configureto do a变基instead of a合并`,但这不是“安全”配置,只有在对所有涉及的操作都非常熟悉的情况下才应该这样做。

cherry-pick的优点是它避免了创建合并提交,也避免了任何历史记录的重写。但是,它会创建重复的提交,这也会使历史复杂化。如果您希望在少量提交中将所有想要的更改引入master中,则可能是一个不错的选择。如果您最终要回到merge分支回到master,尽管合并冲突并不难解决,但它可能会增加合并冲突的机会。如果您最终将rebase分支到master,那不应该成为问题(因为rebase具有针对cherry-pick引入的冲突的特定保护。)如果选择此方法,首先确定您需要复制的提交,然后

git checkout branch-2
git cherry-pick <commit>

其中<commit>是可解析为所需提交的表达式-例如其提交ID(哈希)或相对表达式(例如master~2将是第二个父级,即倒数第3个)提交-在master分支上。)

第二个问题

如果您有未提交的本地更改,则需要小心一点。 git防止数据丢失的最有效保护措施不适用于工作树副本。 git通常会 尝试避免删除工作树中的数据,除非您提供的命令暗示您希望它覆盖工作树。 (不幸的是,有时不清楚哪个命令会像这样工作。)

因此,最安全的做法是在(合并,变基或选择之前)存储更改。

git stash

然后恢复它们

git stash pop

请注意,这可能会导致合并冲突(因为本地更改可能会影响与添加到分支中的提交相同的代码块)。另外,默认情况下,这会取消所有本地更改的暂存。如果需要将暂存的更改和未暂存的更改分开,可以说

git stash --index pop

但是,如果在pop期间发生合并冲突,则在给定--index选项时该命令将失败。 (到那时,您要么没有使用--index选项,要么经历更多涉及的箍以应用更改。如果需要,我可以输入“更多涉及的箍”。)


[1]通常,如果要对共享分支进行历史记录重写,则需要与拥有该分支副本的每个人进行协调。如果您不这样做,那么他们自然地尝试解决他们遇到的错误可能会撤消重写。人们反对在分布式存储库中这可能是不切实际的。如果不切实际,则不应重写历史记录。有关更多信息,请参见“从上游变基恢复”下的git rebase文档。 https://git-scm.com/docs/git-rebase

答案 1 :(得分:0)

您尝试执行的操作最好通过合并或重新定基来实现。

推和拉只是您要尝试做的事情。他们只是确保您的回购本地副本已与远程副本同步。所有实际操作都完全在本地完成。如果分支上有本地提交,则将使用它们。

要使master进入分支,您可以基于master或合并master。如果您是在个人分支上工作,并且有权强制推送非快进提交,则rebase可以使您的历史记录更加整洁:

git rebase master
git push -f

另一方面,如果您正在协同工作,或者没有强制推送权限,请使用合并:

git merge master
git push

以上两种操作均假设您位于您感兴趣的分支上。在这两种情况下,远程分支都不会以任何方式进入操作的第一部分。更改后,只是考虑了不同的推送选项。