我已经从SVN导入到Git,现在我有一个大分支,像这样:
- 在功能C上工作
- 在功能B上工作
- 在功能C上工作
- 在功能C上工作
- 在功能B上工作
- 在特征A上工作
我想要A、B、C的独立特性分支。我正在挑选新分支的提交,但这并没有将它们从原始分支中删除,所以我必须手动跟踪我已经删除的提交。
大约有800个提交需要拆分,可能有50个特性/错误修复。
最好能在git日志中以某种方式反映出我已经提取的那些,这样我就知道哪些是我已经做过的。这可能吗?
我可以重定整个分支的基,跳过我已经取出的提交,但我担心这会导致很多冲突。我不想每次提交一次就解决500个冲突。
将提交从一个超级分支拉到更小的功能分支,同时跟踪进度的最佳方法是什么?
6条答案
按热度按时间dgsult0t1#
在这个例子中,我使用了interactive rebase。
在
HEAD
上,创建分支A
、B
和C
。同时创建一个“备份”分支(您可以将其命名为backup
),以防出现问题而需要恢复原始的HEAD
。然后,在你希望它们开始的提交中创建一个分支,也许在一个方便的稳定提交中。叫它
new_trunk
或者别的什么。然后,执行交互式
rebase
s,并挑选出您希望保留在该分支中的提交。使用这种方式,它基本上就像批量执行cherry-pick
。完成后,您应该有3个分支,从
new_trunk
开始具有单独的历史记录,如果您仍然需要,则有一个backup
分支反映旧的HEAD
。qeeaahzv2#
就我个人而言,我真的会考虑这样大的变化的利弊(如果你已经这样做了,再一次)。如果你遇到了冲突(这是一个大的rebase/cherry-pick,很烦人,很难解决),你可能会有坚韧的时候,合并功能回到你的“主”分支。
冻结你的大分支,让它“完成”(或“足够好”),并在上面创建新的特性分支,这不是更好/更容易吗?(或者只排除一些分支?)
但对于你的问题:
如果你想自动跟踪更改/丢失的提交,可以使用git cherry命令。
如果在cherrypicking或rebase特性分支时没有冲突,您可以使用以前的代码和一些额外的管道:
这将打印(并保存到名为“remaining”的文件)featureBranch中缺少的提交。你可以在bigBranch上的交互式rebase中添加这个,以丢弃你不想要的提交。(也许你可以使用“艾德”编辑器作为git编辑器来编写更多的脚本,并将命令传递给交互式rebase的标准输入,但我没有尝试过。
bhmjp9jg3#
为了进一步简化willoller's answer,
制作特征分支,并备份,以防
然后 checkout 一个特性分支,并从你希望它们开始的提交中进行交互式变基
如果你想让一些特性分支共享一些提交来保持你的树的整洁,不要在开始的时候创建后面的特性分支,但是一旦你有了一个重新定基的特性分支,然后使用共享的提交引用作为你的下一个 safecommit
xesrikrc4#
我刚刚发现的另一种方法是使用“git notes”。
http://alblue.bandlem.com/2011/11/git-tip-of-week-git-notes.html
这个特性允许添加注解到现有的提交中,而不需要实际改变分支/要求变基。一种跟踪哪些提交被取出的方法是给每个提交添加一个git note:
Cherry-picked to features\xyz 925a5239d4fbcf7ad7cd656020793f83275ef45b
这在很大程度上可以帮助手动处理-您可以编写一个小脚本来选择特定分支的提交,然后将相关的git note添加回原始提交。
或者,如果你想变得非常时髦,你可以通过以下方式自动化整个过程:
1.在每个提交中添加一个git note,说明你希望它被选中到哪个功能分支:
TOCHERRYPICK: features\xyz
1.编写一个脚本来扫描所有的git notes,并自动创建所有的feature分支和cherry-pick正确选择的commit。然后,它可以将git note更改为
CHERRYPICKED: features\xxx at 925a5239d4fbcf7ad7cd656020793f83275ef45b
,以允许稍后重新运行该工具以挑选更多的提交。1.如果你真的很想在提交被选中时突出它,你也可以自动创建一个具有类似名称的标签:
CHERRYPICKED:<branch>:SHA
sz81bmfz5#
老实说,我不会这样做,除非你有一个巨大的提交列表,需要分开,他们是非常独立的功能,即。不改变同一行,因为这会产生冲突。
正如其他人所建议的,为每个特性创建一个新的分支,并使用
git rebase --interactive
来包含所需的提交。为确保不会丢失,请通过以下方式创建
git-rebase-todo
文件的内容:您可以使用类似于以下命令创建提交列表
显示提交44 e19。这会给予你一个这样的文件
编辑时(要添加分类:功能a、B、c等)可能看起来像我的
sorted.txt
然后用您喜欢的脚本语言编写脚本,将排序后的列表转换为
git-rebase-todo
文件的集合。你的剧本可能和我刚写的很像。该脚本逐行读取提交排序文件,并以空格字符{ }拆分以获得两个字段
branch
和commit
,并接受子字符串(从10个字符开始)作为提交的描述。描述不是必需的,但它对我们人类检查错误很有用。然后将一行代码放入适当的
git-rebase-todo
文件中,为每个功能创建一个文件。我通过执行一个非常丑陋的Windowsecho string >> file
命令破解了这个问题。这将创建多个文件,例如我的文件
a.txt
整件事都很丑陋。我不推荐它,除非你必须这样做,并且擅长写脚本。
前段时间我写了上面的文字,我对事情有了一点反思。上面我暗示这是一个很大的工作,不值得做,但我已经看到的情况下,它看起来像有人做了上述,这是非常值得的。
我记得Visual Studio for MFC/C++的版本,其中每个新版本都有编译器更改,IDE更改,MFC改进,并在更高版本的Windows上运行。这意味着,如果你想让你的编译器远离VS 6和Windows XP,你可能不得不改变语言来满足编译器,改变函数调用来满足MFC等。
现在假设微软在开发Visual Studio时每周进行一次备份,有人有条不紊地采取了旧备份并将代码更改提交到Git等版本控制系统中。然后他们开始对变化进行分类。。
等等的。
微软可以为每一个都创建分支,并开始拥有最新和最好的IDE(包括
c
),在最新的Windows上运行,并且仍然能够使用他们编写的语言(没有a
)和库(没有b
)编译旧的遗留程序。以前被遗留软件束缚的开发人员可以以逻辑和增量的方式进行改进,例如语言更改和库更改彼此独立,并且在最新和最好的Visual Studio上进行,而无需通过所有中间版本。
示例
现在我并不是说这就是已经发生的事情,但在我看来,Visual Studio的最新版本在允许旧程序更新方面要好得多,而不是扔掉和(永远不会?)重写,在我看来是由于版本控制和将旧软件更改组织成逻辑分支:编译器版本、DLL/库版本。
因此,我可以看到将大量旧提交拆分到不同分支的情况可能是值得的。
在Visual Studio 2019中,我可以添加以下行
配置文件,并设法编译和运行一个旧的Windows程序,该程序无法编译和链接VS 2015和VS 2017。看起来很像微软的某个人已经将性能和安全改进重新基于一些旧软件,而忽略了经常伴随现代化而来的
breaking changes
。ehxuflar6#
//在develop分支上