将pull请求移动到git中另一个分支的最佳方式



我有两个分支,masterdevmaster应该是dev的子集。我对master进行了一些提交,需要将这些提交移动到dev。但是,master中的一些错误提交发生在其他有效提交之间。

所以目前看起来是这样的:

master
A - B - C - D - E - F - G - H - I
dev
A - B - - - - - E - - - G 
                          
                            - - - J - K - L

但我需要让它看起来像这样:

master
A - B - - - - - E - - - G
dev
A - B           E       G
             /      /   
        C - D       F       H - I - J - K - L

所以本质上,我需要将C-DFH-Imaster移动到dev

基本上,如果我在masterdev之间进行比较,我需要从master中提取不在dev中的所有内容,并将其从master中删除。

我知道这有点乱,主要是因为我们中途更改了流程。老实说,我正试图弄清楚它是如何一开始就处于这种状态的。我甚至不确定dev是在什么时候从master分支出来的。

因此,我只是想找出目前清理混乱的最佳方法,今后,这不应该是一个问题(现在我们已经"修复"了我们的流程)。

我看过cherry-pickmergerebase,但我不确定哪一个在这里合适。我最初想的是cherry-pick,但由于master应该是dev的子集,我想知道merge还是rebase在这里更合适。

此外,仅供参考,没有人直接从这两个分支中的任何一个分支工作,也没有人从自己的分支工作,如果这对解决方案有影响的话。

更新

所以我做了mastergit logdev:

git checkout master
git log --graph --oneline --all --abbrev-commit --decorate > ../master.txt
git checkout dev
git log --graph --oneline --all --abbrev-commit --decorate > ../dev.txt

然后对这两张图进行了比较。这让我对所发生的事情有了更好的了解(幸运的是,更清晰):

--->*   de80f1b (HEAD, origin/master, origin/HEAD, master) Merge pull request #168 from nebula101/support-lf-newlines
    |  
    | * 8b6e985 (origin/pr/168) Add support for the LF line ending
    * |   b966002 Merge pull request #170 from nebula101/fc_alphanumeric
    |   
    | * | 7bf0c25 (origin/pr/170) Add NNID
    | * | 060671d Add XBox360 and PSN to fc tool
    * | |   8089053 Merge pull request #169 from nebula101/small-changes
    |    
    | * | | 7ef0317 (origin/pr/169) Update noticeboard header text
    | * | | ebe7d80 Add festive avatars
    | * | | 06dc673 Add 'Austria' to the list of countries
    | * | | e04d1a5 Fix a small typo
    | * | | d08d254 Fix images in view_view.asp
    | * | | 761c09c Fix items_list.asp
    | * | | 45096b7 Add Halloween avatars
    | * | | c05806f Fix age in profiles
    | * | | 5afdcbd Fix a typo in noticeboard_responses.asp
    | * | | e254a33 Chenge 'CNB edit should alert users' default
    | | |/  
    | |/|   
--->| | | * 3e3e829 (origin/dev, dev, AngelWings666-master) Merge pull request #181 from Quintinius/master
    | | | *   2165f08 (Quntinius-master) Merge pull request #183 from jeradrose/dev
    | | | |
    ....

基本上,唯一的区别是用--->标记的线,masterHEAD在顶部线上,devHEAD在底部标记的线上。

换句话说,唯一要做的就是将三个拉取请求(8b6e9857ef03177bf0c25)合并到master而不是dev

我认为GitHub上的观点让我感到困惑,因为作为拉取请求的一部分进行的提交更早(按时间顺序),但直到最后合并时才提交。

那么,我需要做些什么才能将这三个pull请求移动到dev?我知道如何在这些提交之前将master的HEAD移回,只是不确定将这些合并拉取请求转移到dev的最佳方式。

好吧,我对github一无所知,但要在您自己的本地回购中做到这一点:

首先,让我们确保在拉请求提交上有标记——分支或标记名称,这些标记就在合并提交之前,在图形日志输出的"右侧"。其中有三个(数字169、170和168的顺序略为奇数)。它们是提交8b6e985(#168)、7bf0c25(#170)和7ef0317(#169)。

碰巧,它们都已经有了很好的标记,origin/pr/168origin/pr/170origin/pr/169。因此,第一步是:检查标签是否存在,它们确实存在,完成了。

现在,让我们修复master,然后将结果强制推回到origin(这假设没有其他人拾取这些,或者如果他们拾取了,他们知道如何从强制推中恢复):

git status            # make sure everything is clean
git show master~3     # make sure this is the right commit

假设这些看起来是正确的,让我们进入master并告诉git将其(使用--hard)重置为master~3,即备份三个左侧父提交:

git checkout master
git reset --hard master~3

现在,我们已经从分支master中"删除"了三个合并提交,方法是使标签指向图中后面的三个节点。这三个合并提交的名称HEADmaster不再可访问。它们仍然可以通过名称origin/masterorigin/HEAD访问,但我们即将更改:

git push -f origin master  # anyone else using this is out of luck

假设origin允许这种强制推送,那么它现在也有三个合并提交不可访问(并且可能会很快对它们进行垃圾收集)。这也至少改变了我们的origin/master副本,可能也改变了origin/HEAD副本,所以现在我们看不到合并(尽管它们仍然存在,并且由于reflog条目,将持续大约90天)。


旁白:如果不起作用怎么办?如果远程回购不允许强制推送,则必须"恢复合并"。这可以用git revert来完成,这只是有点烦人,因为它会使以后的重新合并更加困难。让我们把它排除在这个答案之外。:-)


最后,您希望进行新的合并,将这些提交链引入dev。所以进入分支dev:

git checkout dev

然后执行合并。可能有一些更自动的方法可以用于拉取请求和github,但这将起作用:

git merge origin/pr/169  # bring in pull request 169's chain of commits
# do any fixing-up required, here - usually the merge will just work
# automatically and make a commit for you
git merge origin/pr/170  # bring in #170's single commit
# and fix-up if needed here, too
git merge origin/pr/168  # bring in #168's single commit
# and again here

事实上,如果你喜欢的话,你可以用"章鱼合并"同时合并这三个。不用三个单独的合并命令,您可以使用一个:

git merge origin/pr/169 origin/pr/170 origin/pr/168

gitmerge文档中描述了章鱼合并(尽管不是很好)。

首先检查master分支:

git checkout master

然后查看日志以查看分支的提交:

git log

现在,您将看到您的提交列表,以及每个提交的哈希:

提交a0b6a63955a4dc9a2154e0a0de3b2e8ee6bef2作者:Kevin Bowersox日期:2013年11月25日星期一09:51:14-0500

Commit to update

提交d132fc724a7f749168a95383a3b376b1c4f699ef作者:Kevin Bowersox日期:2013年11月25日星期一09:34:40-0500

removed interceptor

将要移动到dev的提交的哈希值复制到:

例如,第二个提交散列是:d132fc724a7f749168a95383a3b376b1c4f699ef

现在切换到dev分支:

git checkout dev

然后使用cherry-pick选择性地合并来自master的提交

git cherry-pick d132fc724a7f749168a95383a3b376b1c4f699ef

最新更新