有什么办法让git将master中的文件添加到其他10个分支中?

Ser*_*ult 3 git

有没有办法告诉git在每个其他分支中添加一个新文件?

不是git checkout <branch>; git merge master每一个分支,是有添加快捷键的newfile到下面每一个分支?

     master
       +-----newfile
       |
      --- 
    /  |  \
   /   |   \
  /    |    \
foo   bar   baz
Run Code Online (Sandbox Code Playgroud)

编辑:这是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
Run Code Online (Sandbox Code Playgroud)

Mar*_*ger 5

有几种方法可以解决这个问题.在我看来,其他评论/答案中的大多数建议(截至撰写本文时)都是可疑的.这里有不同选项的概述,有利有弊.

首先,最终历史可以是(至少)三种不同的选择.每个人都有利弊.有点.更像每个人都有缺点,而职业选手则没有其他方式的缺点.

  • 它可能看起来像文件"始终存在",因为在创建受影响的分支之前.最重要的是,这是历史改写,这会带来后果.

  • 它看起来像每个分支独立添加的文件.该文件可能最终会出现难以阅读的历史记录,并且存在很多可避免的合并冲突的可能性.但是,它不会改写历史.

  • 它看起来像文件被添加一次,然后合并到每个分支.有些人真的讨厌合并提交,甚至作为一个并不特别讨厌合并提交的人,我认为这种方法会导致一个混乱的分支拓扑.但是,它避免了历史重写,并将继续发展; 即它在功能上是最干净的选择,但在美学上粗糙.

仔细看看每一个:


重写历史:

如果您单独使用您的仓库,并且您从未做过任何使您现有的提交ID("哈希")重要的事情,那么这是一个相当有吸引力的选择.即使您共享回购,只要您与回购的其他用户协调,您就可以完成此工作.

对于重大改写,我的一般建议是与每个人协调,以确定所有工作将被推送到回购的设定日期/时间.然后每个人都丢弃他们的克隆,你重写,每个人都重新克隆.如果那不实用,那么大改写可能不是一个好主意; 但是如果你想要考虑它,请阅读git rebase文档中的"从上游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
Run Code Online (Sandbox Code Playgroud)

然后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
Run Code Online (Sandbox Code Playgroud)

问题是,如果你的历史很大,那么这个过程很慢.您可以通过使用工作树的ramdisk(请参阅-d选项)或使用a --index-filter而不是a 来加快速度--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