找到一个特定的藏品我该如何展示它?
Found a specific stash how do I show it?
通过以下命令,我找到了一个包含某个未跟踪文件的存储区:
git rev-list -g stash | xargs -n1 git ls-tree -r | sort -u | grep widget
这条命令returns:
100644 blob 05e25619a6f2649b7d635b5aa897cbfc68a4f15d widget/app.css
我现在如何显示这个藏品?
我试过了:
git stash show -p stash@{100644}
返回了什么 stash@{100644} is not a valid reference
谢谢
就这样:
git show 05e2561
存储仅使用常规 git 提交,就像其他任何提交一样。
编辑:
正如 OP 在评论中提到的那样,上面的命令只显示了一个 blob,而不是一个提交。
我现在唯一的想法是:
git stash list
获取存储中所有提交哈希的列表。然后对于每个提交哈希,执行:
git show --name-only abcd1234
替换实际的提交哈希。我确定可以编写 shell 脚本来自动执行此操作。
但正如我在评论中所说,如果您有大量的存储提交,并且您正在使用存储进行 long-term 存储,那么您就做错了 git
。您需要学习如何使用分支,或者您可能需要做的只是更频繁地提交 master
。
请问,为什么使用 stash
而不是 commit
? stash 只是幕后的提交,但经过伪装并变得更加复杂。我经常使用 git
而 从不 使用 stash
。如果我需要保存工作并处理其他事情,我只是进行正常提交。
如果您必须使用 stash
,它应该仅供非常 short-term 使用,同时您可以节省您的工作以处理另一项任务。你的储藏室应该几乎总是空的。
如其他答案所述:100644
不是提交哈希,也不是隐藏编号。您构建的命令实际上不会跟踪生成此特定 ls-tree
条目的提交 ID。
如果你想找到包含文件 widget/app.css
的隐藏文件,例如:
# if you have more than 50 stashes, replace '50' with a number big enough
for i in {0..50}; do
if git rev-parse --verify -q stash@{$i}:widget/app.css; then
echo "stash@{$i}"
fi
done
考虑使用这个(未经测试):
git log -g stash --format='%H %gD' |
while read hash rel; do
git ls-tree -r $hash | sed "s:^:$rel :"
done |
grep widget
说明
注意:
git rev-list -g stash | xargs -n1 git ls-tree -r | sort -u | grep widget
不会产生相当您想要的输出。你得到了:
100644 blob 05e25619a6f2649b7d635b5aa897cbfc68a4f15d widget/app.css
这是 git ls-tree -r
输出中的一行。这些输出行的格式是 mode type hash
tabpath
(with文字制表符)。 mode
,在本例中为 100644
,来自一组有限且固定的可能性:100644
表示 blob 即不可执行。 (type
字段由模式决定,因此它是多余的。)blob 的 hash
是blob的hash ID:事实上,除了160000
,它被称为commit
,代表一个gitlink,hash总是一些内部的Git此存储库中的对象哈希。 None 其中曾经是隐藏提交哈希 ID 或相对编号。也就是说,其中 none 可以作为 stash@{<em>number</em>}
.
如果我们 return 到 git rev-list -g stash
命令,这将简单地遍历 stash reflog。它与 运行ning git reflog stash
相似,除了它不是以下形式的输出:
<hash> stash@{0}: <subject>
<hash> stash@{1}: <subject>
.
.
.
它只生成哈希 ID。因此 git rev-list
的输出包含您想要打印的信息。但是该输出进入 xargs -n1 git ls-tree -r
,因此 xargs
吃掉输出并将其提供给 git ls-tree -r
,后者将其吃掉并且不再打印出来。
然后,要获得所需的信息,您需要修改或替换 xargs
命令。允许您实现目标的修改是在每个 git ls-tree -r
行的左侧打印提交哈希 ID and/or stash-relative 名称。
要获得 stash-relative 名称,更改或替换 git rev-list
输出可能是明智的。不幸的是 git rev-list --format='%H %gD'
,这是处理这个问题的合乎逻辑的方法,但不起作用。我们必须使用 git log
,它有一个缺陷:git log
是一个 porcelain 命令而不是管道命令,因此它服从用户配置,这可能会改变它的行为.1 但我们对此无能为力,所以我们不妨继续努力。
1在我看来 git log
需要一个 --porcelain
标志 la git status
,尽管我一直想知道为什么这flag 拼写为 --porcelain
而不是 --plumbing
.
替代序列
我们将从:
开始
git log -g stash --format='%H %gD'
和 运行 它的输出通过一个将获取哈希的命令,使用 git ls-tree -r
列出哈希在左侧的提交的全部内容,并在每一行前加上 reflog-relative %gD
输出和一个 space。我们将为这些使用普通的 sh
编程结构,尽管这会有点慢:
git log -g stash --format='%H %gD' |
while read hash rel; do
git ls-tree -r $hash | sed "s:^:$rel :"
done
在这里,我们 运行 git ls-tree -r
对散列进行处理,并将其输出通过 sed
、stdin-stream 编辑器进行管道传输。编辑命令是用相对引用替换行首(^
)。我们可以使用冒号 :
字符作为分隔符,因为我们知道任何分支名称中都不能出现冒号。2 这意味着扩展 $ref
不会意外触发一个 end-of-delimiter 序列。我们对 sed
命令参数使用双引号,以便 $ref
does 得到扩展,并且加上 shell 的 while read
循环结构——解释整个循环。
我们可以删除 sort -u
,因为没有理由对这些进行排序,并且 uniq
-ing 每一行似乎没有效率,但我们仍然希望最终的 | grep widget
到这个小 git log | while
one-liner 到一个解决方案中,该解决方案查找包含将匹配 widget
的任何路径字符串的存储,例如 stowidgetname
(Stow ID,Get Name)。
2冒号不是唯一的选择;参见 the git check-ref-format
documentation。然而,冒号在视觉上是有区别的并且 non-problematic。通常的斜杠定界符通常是一个糟糕的选择,因为引用日志名称可能包含斜杠。在我们的特定情况下,我们知道 ref 名称是 stash
,它不包含斜杠,但是使用适用于其他名称的东西是很好的,我们应该尝试重新使用这个扩展的 one-line脚本。 $rel
作为 reflog-relative 扩展,将是引用名称后跟 @{
后跟一系列数字后跟 }
,所以 @{}
和数字以及任何有效 ref-name 个字符都是 错误 个选择。一般来说,控制字符是不好的选择,因为它们很难被看到。这使得规则 4 中的 space、波浪号、插入符号和冒号成为显而易见的候选者。插入符是我们的 beginning-of-line 字符,所以这是一个糟糕的选择,而 space 在视觉上是模糊的,所以我们只使用波浪号和冒号。我选了冒号
通过以下命令,我找到了一个包含某个未跟踪文件的存储区:
git rev-list -g stash | xargs -n1 git ls-tree -r | sort -u | grep widget
这条命令returns:
100644 blob 05e25619a6f2649b7d635b5aa897cbfc68a4f15d widget/app.css
我现在如何显示这个藏品?
我试过了:
git stash show -p stash@{100644}
返回了什么 stash@{100644} is not a valid reference
谢谢
就这样:
git show 05e2561
存储仅使用常规 git 提交,就像其他任何提交一样。
编辑:
正如 OP 在评论中提到的那样,上面的命令只显示了一个 blob,而不是一个提交。
我现在唯一的想法是:
git stash list
获取存储中所有提交哈希的列表。然后对于每个提交哈希,执行:
git show --name-only abcd1234
替换实际的提交哈希。我确定可以编写 shell 脚本来自动执行此操作。
但正如我在评论中所说,如果您有大量的存储提交,并且您正在使用存储进行 long-term 存储,那么您就做错了 git
。您需要学习如何使用分支,或者您可能需要做的只是更频繁地提交 master
。
请问,为什么使用 stash
而不是 commit
? stash 只是幕后的提交,但经过伪装并变得更加复杂。我经常使用 git
而 从不 使用 stash
。如果我需要保存工作并处理其他事情,我只是进行正常提交。
如果您必须使用 stash
,它应该仅供非常 short-term 使用,同时您可以节省您的工作以处理另一项任务。你的储藏室应该几乎总是空的。
如其他答案所述:100644
不是提交哈希,也不是隐藏编号。您构建的命令实际上不会跟踪生成此特定 ls-tree
条目的提交 ID。
如果你想找到包含文件 widget/app.css
的隐藏文件,例如:
# if you have more than 50 stashes, replace '50' with a number big enough
for i in {0..50}; do
if git rev-parse --verify -q stash@{$i}:widget/app.css; then
echo "stash@{$i}"
fi
done
考虑使用这个(未经测试):
git log -g stash --format='%H %gD' |
while read hash rel; do
git ls-tree -r $hash | sed "s:^:$rel :"
done |
grep widget
说明
注意:
git rev-list -g stash | xargs -n1 git ls-tree -r | sort -u | grep widget
不会产生相当您想要的输出。你得到了:
100644 blob 05e25619a6f2649b7d635b5aa897cbfc68a4f15d widget/app.css
这是 git ls-tree -r
输出中的一行。这些输出行的格式是 mode type hash
tabpath
(with文字制表符)。 mode
,在本例中为 100644
,来自一组有限且固定的可能性:100644
表示 blob 即不可执行。 (type
字段由模式决定,因此它是多余的。)blob 的 hash
是blob的hash ID:事实上,除了160000
,它被称为commit
,代表一个gitlink,hash总是一些内部的Git此存储库中的对象哈希。 None 其中曾经是隐藏提交哈希 ID 或相对编号。也就是说,其中 none 可以作为 stash@{<em>number</em>}
.
如果我们 return 到 git rev-list -g stash
命令,这将简单地遍历 stash reflog。它与 运行ning git reflog stash
相似,除了它不是以下形式的输出:
<hash> stash@{0}: <subject>
<hash> stash@{1}: <subject>
.
.
.
它只生成哈希 ID。因此 git rev-list
的输出包含您想要打印的信息。但是该输出进入 xargs -n1 git ls-tree -r
,因此 xargs
吃掉输出并将其提供给 git ls-tree -r
,后者将其吃掉并且不再打印出来。
然后,要获得所需的信息,您需要修改或替换 xargs
命令。允许您实现目标的修改是在每个 git ls-tree -r
行的左侧打印提交哈希 ID and/or stash-relative 名称。
要获得 stash-relative 名称,更改或替换 git rev-list
输出可能是明智的。不幸的是 git rev-list --format='%H %gD'
,这是处理这个问题的合乎逻辑的方法,但不起作用。我们必须使用 git log
,它有一个缺陷:git log
是一个 porcelain 命令而不是管道命令,因此它服从用户配置,这可能会改变它的行为.1 但我们对此无能为力,所以我们不妨继续努力。
1在我看来 git log
需要一个 --porcelain
标志 la git status
,尽管我一直想知道为什么这flag 拼写为 --porcelain
而不是 --plumbing
.
替代序列
我们将从:
开始git log -g stash --format='%H %gD'
和 运行 它的输出通过一个将获取哈希的命令,使用 git ls-tree -r
列出哈希在左侧的提交的全部内容,并在每一行前加上 reflog-relative %gD
输出和一个 space。我们将为这些使用普通的 sh
编程结构,尽管这会有点慢:
git log -g stash --format='%H %gD' |
while read hash rel; do
git ls-tree -r $hash | sed "s:^:$rel :"
done
在这里,我们 运行 git ls-tree -r
对散列进行处理,并将其输出通过 sed
、stdin-stream 编辑器进行管道传输。编辑命令是用相对引用替换行首(^
)。我们可以使用冒号 :
字符作为分隔符,因为我们知道任何分支名称中都不能出现冒号。2 这意味着扩展 $ref
不会意外触发一个 end-of-delimiter 序列。我们对 sed
命令参数使用双引号,以便 $ref
does 得到扩展,并且加上 shell 的 while read
循环结构——解释整个循环。
我们可以删除 sort -u
,因为没有理由对这些进行排序,并且 uniq
-ing 每一行似乎没有效率,但我们仍然希望最终的 | grep widget
到这个小 git log | while
one-liner 到一个解决方案中,该解决方案查找包含将匹配 widget
的任何路径字符串的存储,例如 stowidgetname
(Stow ID,Get Name)。
2冒号不是唯一的选择;参见 the git check-ref-format
documentation。然而,冒号在视觉上是有区别的并且 non-problematic。通常的斜杠定界符通常是一个糟糕的选择,因为引用日志名称可能包含斜杠。在我们的特定情况下,我们知道 ref 名称是 stash
,它不包含斜杠,但是使用适用于其他名称的东西是很好的,我们应该尝试重新使用这个扩展的 one-line脚本。 $rel
作为 reflog-relative 扩展,将是引用名称后跟 @{
后跟一系列数字后跟 }
,所以 @{}
和数字以及任何有效 ref-name 个字符都是 错误 个选择。一般来说,控制字符是不好的选择,因为它们很难被看到。这使得规则 4 中的 space、波浪号、插入符号和冒号成为显而易见的候选者。插入符是我们的 beginning-of-line 字符,所以这是一个糟糕的选择,而 space 在视觉上是模糊的,所以我们只使用波浪号和冒号。我选了冒号