我的存储库中的网络图如下:
M--------------M
| ↑
├-->1---1---1--┘
|
└-->2---2
其中:M
是master
上的推送提交,1
是branch-1
上的推送提交,而2
是branch-2
上的推送提交。
如您所见,来自branch-1
的提交被推送,请求“拉出请求”并合并到master
中。
我在branch-2
上,我正在执行任务。
我需要掌握源代码才能完成它们。
第一个问题:我应该怎么做才能将源代码从master传输到我的branch-2
?
我正在考虑:
git fetch origin
git rebase origin/master
或:
git pull origin --rebase master
第二个问题:如果在branch-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
是“ fetch
和merge
”的快捷方式,因此您也可以这样做
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 configure
拉to 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
以上两种操作均假设您位于您感兴趣的分支上。在这两种情况下,远程分支都不会以任何方式进入操作的第一部分。更改后,只是考虑了不同的推送选项。