Git filter-branch如何仅获取已更改的文件?

5
我们希望在一个大型代码库上运行git filter-branch重新格式化PHP文件。由于我们有超过21k个提交,每次filter-branch提交时phpcbf都想要格式化整个代码库。是否可能只获取每个提交更改的文件并对它们进行特定的格式化?类似于…
git filter-branch --tree-filter \
 'FILES=$(<something> | grep .php) php /usr/local/bin/phpcbf.phar $FILES || true'
1个回答

5
我找到了解决方案:
git filter-branch --tree-filter 'phpcbf $(\
  git show $GIT_COMMIT --name-status | egrep ^[AM] |\
    grep .php | cut -f2)' -- --all

简要说明一下它的作用:

  • git show $GIT_COMMIT --name-status 将返回该提交中所有修改过的文件。
  • egrep ^[AM] 仅筛选出已添加和已修改的状态。无需尝试格式化正在删除的文件。
  • grep .php 仅格式化 PHP 文件。
  • cut -f2 从列表中删除状态前缀,因此我们只得到原始文件路径。

有关更多详细信息,请参见我的博客文章:https://elliot.land/post/reformatting-your-codebase-with-git-filter-branch


1
Elliot的解决方案让我完成了98%的工作。似乎在filter-branch期间,git diff的某些行为已经改变(我正在运行git 2.10.2)。它一直在与我的最新HEAD进行比较,而不是过滤后提交的父级。我能够稍微修改Elliot的代码使其正常工作。在过滤期间,我使用了git show $GIT_COMMIT --name-status而不是git diff --cached --name-status$GIT_COMMIT在每个filter-branch步骤中都会自动设置。 - Andy Fowler
我发现 git show $GIT_COMMIT --name-only --pretty=oneline|tail -n +2git show $GIT_COMMIT --name-status | egrep ^[AM] 更健壮。请注意,它还会返回已删除的文件,因此您可能需要测试文件是否存在。 - Gabriel Devillers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接