- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在拆分 git 存储库的一部分以创建一个新的存储库,并尝试使用 git filter-branch
来维护正在移动到新项目的文件的历史记录.我知道 --subdirectory-filter
但这不是一个好的解决方案,因为我提取的文件没有完全映射到一个子目录。目前我找到的最好的选择是--index-filter
,用法如下:
git filter-branch -f --index-filter 'git read-tree --empty && git reset -q "${GIT_COMMIT}" -- <list of files>' --prune-empty -f
这似乎可行,但我希望能够以编程方式生成要保留的文件列表,以便我可以迭代地优化此列表。我目前正在尝试获取我想保留在另一个文件中的文件列表,并将其附加到代表每次提交要执行的命令的字符串中,如下所示:
tmp=$(cat ~/to_keep.txt) && git filter-branch -f --index-filter 'git read-tree --empty && git reset -q "${GIT_COMMIT}" -- '$tmp --prune-empty -f
不幸的是,这会导致
fatal: bad flag '--prune-empty' used after filename
即使只是回显文件似乎也会造成麻烦:
tmp=$(echo a.txt b.txt) && git filter-branch -f --index-filter 'git read-tree --empty && git reset -q "${GIT_COMMIT}" -- '$tmp --prune-empty -f
fatal: ambiguous argument 'b.txt': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
我之前也尝试过连接字符串:
tmp1=$(echo a.txt b.txt) && tmp2='git read-tree --empty && git reset -q "${GIT_COMMIT}" -- ' && tmp3=${tmp2}${tmp1} && git filter-branch -f --index-filter $tmp3 --prune-empty -f
fatal: ambiguous argument 'read-tree': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
我假设这只是串联,并没有像我在 shell 中预期的那样发生。有谁知道我怎样才能使这项工作?如果您也能解释这些错误的含义,那就太好了。谢谢。
最佳答案
各种...-filter
的每个参数s 必须是单个字符串。该字符串保存为 shell 变量:
--index-filter)
filter_index="$OPTARG"
;;
在适当的时候,过滤器分支脚本(位于 git-core
子目录中,例如 /usr/libexec/git-core
或 /usr/local/libexec/git-core
)执行以下操作:
eval "$filter_index" < /dev/null ||
die "index filter failed: $filter_index"
(使用 /bin/sh -c "$filter_commit" ...
运行的提交过滤器除外)。
因此您的假设是正确的,您需要做的是使文件列表成为单个以空格分隔的字符串的一部分。
最简单的方法是从您的原始命令开始:
git filter-branch -f --index-filter \
'git read-tree --empty && git reset -q "${GIT_COMMIT}" -- <list of files>' \
--prune-empty -f
(当您有静态列表时有效)并修改它以从 ~/to_keep.txt
中提取动态列表.我将原件分成三行,部分原因是出于展示目的,但也是因为我们现在可以只关注中间那一行。
[编辑以修复评论中提到的换行问题。让我们创建一个别名或 shell 函数,xc
, 将换行符转换为空格]
xc() {
tr '\n' ' '
}
"git read-tree --empty && git reset -q \"\${GIT_COMMIT}\" -- $(xc < ~/to_keep.txt)" \
或:
'git read-tree --empty && git reset -q "${GIT_COMMIT}" -- '"$(xc < ~/to_keep.txt)" \
或者,正如您尝试的那样(但有一个变化):
'git read-tree --empty && git reset -q "${GIT_COMMIT}" -- '"$tmp" \
(已设置 tmp=$(xc < ~/to_keep.txt)
)。
请注意,如果任何文件名包含空格,则这些都无法纠正。例如,假设一个文件名为 a file
(嵌入空白)。 eval
将在空格处打断参数,git reset
命令将获取名称 a
和 file
作为两个单独的参数。
只要您没有任何此类文件名,就无需担心解决这个问题。
另一个潜在的问题是如果这个文件列表变得很长。您可能会遇到内核对可以发送到一个文件的参数数量的限制。您应该可以使用 xargs
解决这个问题(并且,就此而言,通过一些工作和使用 -0
来处理文件名中的空白)。
关于git - 如何将以编程方式生成的文件列表传递给 `git filter-branch`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19507282/
我试图让 Branch.io 在 Android 上工作,但我遇到了: myapplication.MainActivity cannot be cast to android.app.Applica
当我执行 git branch 时,我知道我在分支 v0.2 上。 git branch v0.1 * v0.2 但是当我执行 git push 时它说“你当前分支的上游分支与你当前分支的名称不
在使用 Git GUI 检查远程分支 releases/rel_5.4.1 之后,当我尝试 push 时看到了这个意外的错误消息: fatal: The upstream branch of your
SO 上有一个相关问题处理如何更改 push 命令的参数以避免出现此消息: fatal: The upstream branch of your current branch does not mat
arc feature [branch-name] 和 git branch [branch-name] 有什么区别? 他们似乎都创建了一个新分支。 最佳答案 arc feature [branch-
FIFO、LIFO 和LC Branch and Bound 有什么区别? 最佳答案 Branch & Bound 通过使用估计边界来限制可能解决方案的数量来发现完整搜索空间内的分支。不同的类型(FI
有人知道这两个切换和跟踪远程分支的命令之间的区别吗? git checkout -b branch origin/branch git checkout --track origin/branch 我
关于 git-svn 工作流程有很多问题,但我一直无法弄清楚这一点: This section of the svn book谈到 SVN 的一个常见做法:创建一个分支,并在主干更新时不断合并主干中的
我正在构建一个控制 git 存储库的 PHP 应用程序。我有一个执行命令 git status 的同步函数,虽然没有返回“你的分支是最新的”,但可能会提前采取必要的行动,比如远程或本地分支。 我还构建
是否可以使用 branch.io 创建自定义链接,例如 https://example.app.link/fzmLEhobLD所以我可以用我的自定义 10 位参数(如 amitpp8888)控制 fz
我从 github 克隆了一个分支,它的名字是 dev。我已经开始使用它, pull 和推送代码更改并确保我的本地存储库与远程存储库保持同步。我要开始实现一个新功能,因此创建了一个新分支,如下所示:
我们有一个发布模型,为简单起见,我们假设每月 1 次。所以,我们通常会去: Jan -> trunk trunk -> Feb trunk trunk et
使用 Branch.io HTTP API 创建的链接不会在 Branch 门户中显示为快速链接。快速链接很方便,因为它们在一个 View 中显示“点击”、“打开”等内容 用于创建链接的 API:li
我创建了一个分支,当我第一次从源代码合并到分支时,出现了一大堆旧的变更集,它说没有合并,但它们在分支之前就存在,我确认它们在那里。 例子: 假设当 Source 中有 9 个变更集时,我从 Sourc
这是关于我为什么这样做 不是 收到错误“致命:当前分支 A 没有上游分支”。 我删除了 远程 分公司 一个 使用命令 git push origin :A . 然后我切换到本地 分支 A 使用命令 g
我正在使用 clover 插件来检查我的 java 代码测试覆盖率。 我为所有行编写了单元测试。当我点击红线时,它显示“true分支执行了2次,分支执行了0次”。这是什么意思?我该如何解决这个问题?
很确定我误解了 git。 我的目标 我在 github 上有一个带有“master”分支的私有(private)存储库。 我还想有一个生产分支,我会将所有更改从 master 推送到该分支。 然后我想
我将一个相当老的主题分支重新定位到 master 上。由于在 rebase 期间有很多冲突,我想将旧主题分支与 rebased 分支进行比较,以确保我没有意外删除或搞砸主题上的任何更改。我最接近的是比
我正在尝试将我的一个项目推送到 github,但我一直收到此错误: peeplesoft@jane3:~/846156 (master) $ git push fatal: The current b
Jenkins Git 插件根据我的引用规范在控制台输出中生成了以下命令 下面两个命令有什么区别?他们的输出看起来没什么不同。我在下面给出了他们的输出: 命令 1: git fetch --no-ta
我是一名优秀的程序员,十分优秀!