有没有办法告诉git将一个新文件添加到其他每个分支中?
而不是每个分支的git checkout <branch>; git merge master,是否有一个快捷方式来添加新文件到每个分支下面?
master
+-----newfile
|
---
/ | \
/ | \
/ | \
foo bar baz编辑:这是我想出的bash脚本(如果实现了需要进行一些清理),但希望有一个更好的方法。
MSG='added newfile which contains a method to workaround issue IS-797'
for branch in $(git branch | grep -v master | sed 's#^[ *\t]##g'); do
echo merging into $branch
git checkout $branch && git merge master -m "$MSG"
done发布于 2018-09-14 15:42:53
有几种方法可以解决这个问题。在我看来,其他评论/回答中的大部分建议(在本文撰写时)都是值得怀疑的。这里列出了不同的选项,并给出了利弊。
首先,对于最终历史是什么样的,有三个不同的选项(至少)。每一种都有优缺点。说大也大吧。更像是每个人都有缺点,优点是他们没有其他方式的缺点。
更详细地研究每一个方面:
重写历史:
如果您单独使用回购,而且您从未做过任何使您现有提交ID ("hashes")重要的事情,那么这是一个相当有吸引力的选项。即使您共享回购,只要您与回购的其他用户协调,也可以使其工作。
对于大型重写,我的一般建议是与每个人协调,以有一个固定的日期/时间,当所有的工作将被推送到回购。然后每个人都放弃他们的克隆,你做重写,每个人重新克隆。如果这不实用,那么大重写可能不是一个好主意;但是如果您想要考虑它,请阅读git rebase文档中的“从上游重基中恢复”,以获得更多关于将要发生的事情的信息。
虽然我认为rebase是进行历史重写的典型方式,但在这种情况下,它几乎肯定是错误的。如果你有很多分支,你必须做很多次。如果你有一个复杂的历史,它变得很难做正确。特别是,它没有很好地处理合并(即使是最近增加的改进)。
相反,您可以使用git filter-branch。简单的方法是使用--tree-filter。然后,将文件的副本放在工作树之外的某个地方。
git filter-branch --tree-filter 'cp /path/to/stored/copy/of/file path/to/file/in/worktree' -- --all然后,filter-branch将继续签出历史记录中的每个提交,运行cp命令将文件添加到该提交的工作树中,并编写一个包含结果内容的新提交。然后将分支从旧的提交转移到新的提交。如果您有标记并希望它们移动,那么添加一个--tag-name-filter参数,如下所示
git filter-branch --tree-filter 'cp /path/to/stored/copy/of/file path/to/file/in/worktree' --tag-name-filter cat -- --all这方面的问题是,如果您的历史记录很大,这个过程是缓慢的。您可以通过为工作树使用ramdisk (请参阅-d选项)或使用--index-filter而不是--tree-filter (但这需要使用不同的命令直接更新索引)来加快速度。
每个分支添加文件
这就是cherry-pick会给你的。因为问题是如何使过程自动化,所以不清楚为什么有人用cherry-pick来评论它,好像它是一个解决方案。这个过程和合并一样是手动的(也是可脚本的)。
唯一的区别是,当您这样做时,git创建独立的提交,分别在每个分支上添加文件。
可以使用与合并相同的基本脚本,只需将merge命令替换为cherry-pick命令即可。
合并
为此,您已经制定了一个合理的解决方案--您需要一个脚本。我要注意的唯一想法是,git for-each-ref通常是一个更适合输入脚本的命令,而不是git branch。https://git-scm.com/docs/git-for-each-ref
发布于 2018-09-14 14:21:15
您可以使用git rebase来实现它,但是请阅读为什么不使用这篇文章中的git重基。
发布于 2018-09-14 15:56:50
如果您已经在master上提交了它,我将在每个分支上选择它。到目前为止,这似乎是最简单和最健壮的脚本;一个分支的失败对于其他分支来说应该是无关紧要的。
commit='deadbeef'
for branch in $(git branch | sed -n '/master/!s#^[ *\t]##p'); do
echo "cherry-picking onto $branch"
git checkout "$branch" && git cherry-pick "$commit"
done顺便提一句,请注意小写shell变量的首选项,引用,在每一行只期望有一个匹配时,不要在sed中使用sed标志,并且避免使用grep。
在sed脚本中使用\t并不完全是可移植的;也许可以尝试使用[*[:space:]]而不是[ *\t]。
当然,与将所有master合并到每个分支相比,选择一个单独的提交当然要具体得多,对于其他挣扎于此的人来说,这很可能是一个完全不可能的。
https://stackoverflow.com/questions/52333842
复制相似问题