我有两个分支,master
和dev
,master
应该是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-D
、F
和H-I
从master
移动到dev
。
基本上,如果我在master
和dev
之间进行比较,我需要从master
中提取不在dev
中的所有内容,并将其从master
中删除。
我知道这有点乱,主要是因为我们中途更改了流程。老实说,我正试图弄清楚它是如何一开始就处于这种状态的。我甚至不确定dev
是在什么时候从master
分支出来的。
因此,我只是想找出目前清理混乱的最佳方法,今后,这不应该是一个问题(现在我们已经"修复"了我们的流程)。
我看过cherry-pick
、merge
和rebase
,但我不确定哪一个在这里合适。我最初想的是cherry-pick
,但由于master
应该是dev
的子集,我想知道merge
还是rebase
在这里更合适。
此外,仅供参考,没有人直接从这两个分支中的任何一个分支工作,也没有人从自己的分支工作,如果这对解决方案有影响的话。
更新:
所以我做了master
的git log
和dev
:
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
| | | |
....
基本上,唯一的区别是用--->
标记的线,master
的HEAD
在顶部线上,dev
的HEAD
在底部标记的线上。
换句话说,唯一要做的就是将三个拉取请求(8b6e985
、7ef0317
和7bf0c25
)合并到master
而不是dev
。
我认为GitHub上的观点让我感到困惑,因为作为拉取请求的一部分进行的提交更早(按时间顺序),但直到最后合并时才提交。
那么,我需要做些什么才能将这三个pull请求移动到dev
?我知道如何在这些提交之前将master的HEAD
移回,只是不确定将这些合并拉取请求转移到dev
的最佳方式。
好吧,我对github一无所知,但要在您自己的本地回购中做到这一点:
首先,让我们确保在拉请求提交上有标记——分支或标记名称,这些标记就在合并提交之前,在图形日志输出的"右侧"。其中有三个(数字169、170和168的顺序略为奇数)。它们是提交8b6e985
(#168)、7bf0c25
(#170)和7ef0317
(#169)。
碰巧,它们都已经有了很好的标记,origin/pr/168
、origin/pr/170
和origin/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
中"删除"了三个合并提交,方法是使标签指向图中后面的三个节点。这三个合并提交的名称HEAD
或master
不再可访问。它们仍然可以通过名称origin/master
和origin/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