【问题标题】:Is it possible to search through Git Stash items?是否可以搜索 Git Stash 项目?
【发布时间】:2017-07-22 04:16:39
【问题描述】:

所以我这周正在学习如何使用 Git Stash,并发现所有这些 stash 都在我的系统上累积。我放错了一些代码,现在我有十几个代码 0-11 的存储区。

有没有一种方法可以让我在这些存储中搜索存储中文件中的字符串值以找到我正在寻找的代码? 要么 我是否只需要通过并重新应用每个存储来搜索/查找我要查找的代码?


2021/03/18:只是我发现的其他信息的更新。

您可以创建一个 git 别名来搜索您的所有分支

修改你的 .gitconfig 文件,然后通过 'git stash-search '

调用
[alias]
  stash-search = "!f() { git show $(git stash list | cut -d\":\" -f 1) | grep \"$@\" ; }; f" 

【问题讨论】:

  • git stash show -p stash@{n} | grep "john cena" 是我认为的唯一选择。当然,您可以围绕它编写自己的脚本。
  • @AndrejsCainikovs 成功了!太感谢了。我一直忘记 grep 的力量
  • @AndrejsCainikovs 把它作为答案,我会标记它。

标签: git search


【解决方案1】:

git stash show -p stash@{n} | grep "john cena" 是我认为的唯一选择。

当然,您可以围绕它编写自己的脚本。

【讨论】:

  • @LibinVarghese,oneliner:git show $(git stash list | cut -d":" -f 1) | grep "john cena"
  • 请注意,存储散列或名称的 git show 与存储散列或名称的 git stash show 非常不同。这是因为每个stash@{n} 都引用了一个不是明智合并的提交,但git show 认为它,并显示它是错误的。
  • 另外,请注意,可以为 stash 命名。在这种情况下,您需要通过它的名称来引用,而不是默认的 stash@{n}。
  • 它没有回答关于items 的问题,而不是单个itemcut 的评论是正确的,但 Joshua (stackoverflow.com/a/57601163/1416144) 的答案使用 for 的别名要好得多 - 还跟踪存储号。
【解决方案2】:

git grep 命令接受一个“树”对象:

概要

git grep [-a | --text] [-I] [--textconv] [-i | --ignore-case] [-w | --word-regexp]
              [-v | --invert-match] [-h|-H] [--full-name]
              [-E | --extended-regexp] [-G | --basic-regexp]
              [-P | --perl-regexp]
              [-F | --fixed-strings] [-n | --line-number]
              [-l | --files-with-matches] [-L | --files-without-match]
              [(-O | --open-files-in-pager) [<pager>]]
              [-z | --null]
              [-c | --count] [--all-match] [-q | --quiet]
              [--max-depth <depth>]
              [--color[=<when>] | --no-color]
              [--break] [--heading] [-p | --show-function]
              [-A <post-context>] [-B <pre-context>] [-C <context>]
              [-W | --function-context]
              [--threads <num>]
              [-f <file>] [-e] <pattern>
              [--and|--or|--not|(|)|-e <pattern>...]
              [ [--[no-]exclude-standard] [--cached | --no-index | --untracked] | <tree>...]
              [--] [<pathspec>...]

现在考虑一个 stash 条目是一个从 在您调用git stash 时工作树的内容 它的两个父母是HEAD的州 以及索引中的状态;引用手册:

一个 stash 表示为一个提交,其树记录 工作状态 目录,它的第一个父目录是HEAD 的提交 创建存储时。 第二个父节点的树记录了索引的状态,当 stash 被创建,它成为HEAD 提交的子项。 祖先图如下所示:

              .----W
             /    /
       -----H----I

其中HHEAD 提交, I 是记录索引状态的提交, 而W 是一个记录工作树状态的提交。

所以你可以有树的地方来grep你的存储条目:

  • git grep [options] term stash@{n} 会 grep 那个 W 提交 对于term,即 它会 grep 工作树文件的保存状态。

  • 要 grep 隐藏条目的索引状态,您需要参考 给W的第二个父母;这是使用^2 后缀完成的:

     git grep [options] term stash@{n}^2
    
  • 要 grep 存储条目的基线提交的状态 - 最少 有趣的案例——参考它的第一个父节点:

     git grep [options] term stash@{n}^1
    

^&lt;n&gt; 表示法在git help revisions 手册中有说明:

&lt;rev&gt;^,例如HEAD^, v1.5.1^0 后缀 ^ 到修订 参数表示该提交对象的第一个父级。 ^&lt;n&gt; 表示 &lt;n&gt;th 父级(即&lt;rev&gt;^ 等同于&lt;rev&gt;^1)。作为一个 特殊规则,&lt;rev&gt;^0 表示提交本身,并且在以下情况下使用 &lt;rev&gt; 是引用提交的标记对象的对象名称 对象。

TL;DR

对于顶部存储条目,使用

  • git grep whatever stash@{0} grep 的状态是什么 工作树。
  • git grep whatever stash@{0}^2 grep 的状态是什么 索引。

【讨论】:

  • @Elijah,它有助于理解存储条目——虽然在某些方面“特别”——在所有其他方面只是真正的合并提交,你可以用它们做任何你想做的事情与任何其他提交。
【解决方案3】:

单线:

git grep whatever $(git stash list -q | cut -d":" -f 1)

并且 git grep 可以方便地输出带有存储名称和文件名称的更改行:

stash@{43}:common/ot/whatever.js:exports.whatever = (foo, deps) => {
stash@{44}:common/ot/whatever.js:exports.whatever = (foo, deps) => {

【讨论】:

  • 这不会搜索存储中更改的代码。它搜索整个生成的工作树,包括在隐藏提交中未更改的文件。 (因此,如果我以这种方式在我的 stash 中搜索“whatever”,每个 stash 都会显示来自相同长期未触及文件的相同匹配行)
【解决方案4】:

添加到 Andrejs Cainikovs 回答您可以添加 seq 来搜索所有内容 seq 0 5 | xargs -I {} git stash show -p stash@{\{\}} | grep your_pattern

【讨论】:

    【解决方案5】:

    有一些有用的想法in this gist and discussion thread

    首先,列出匹配的存储很容易(有或没有 -i,取决于大小写)

    git stash list -i -G<regexp>
    

    如果没有太多需要挖掘的内容,您可以添加 -p 以完整打印匹配的存储。

    git stash list -i -p -G<regexp>
    

    为“真实”案例提供更多功能,添加到.gitconfig

    [alias]
        stashgrep = "!f() { for i in `git stash list --format=\"%gd\"` ; \
                  do git stash show -p $i | grep -H --label=\"$i\" \"$@\" ; done ; }; f"
    

    然后您可以使用您喜欢的任何 grep 参数 (-w, -i) 调用 git stashgrep。例如,

    git stashgrep -i <regexp>
    

    这与上面的一些答案不同,因为它预先添加了存储 ID,以向您显示每个差异的来源:

    % git stashgrep -i tooltip
    stash@{5}: //            resetBatchActionTooltip();
    stash@{5}:         addAcceleratorsAndTooltips(lToolMenu, lToolButton, iListener, iTool);
    stash@{5}:     private void addAcceleratorsAndTooltips(AbstractButton lToolMenu,
    stash@{5}:+        String lToolTip = iTool.getToolTipText();
    stash@{5}:             lToolButton.setToolTipText(lToolTip);
    stash@{20}:+    private static final String invalidSelectionTooltip = "Invalid selection.  Please choose another.";
    stash@{20}:-    private final String invalidSelectionTooltip = "Invalid selection.  Please choose another.";
    stash@{20}:                         ((JTextField)lComponent).setToolTipText(
    

    【讨论】:

    • 对我来说,这比接受的答案要好,因为它提供了存储 ID。如果我不知道结果来自哪个存储区,那么接受的答案对我没有多大用处。
    【解决方案6】:

    git stash list -S "my string" 在 Git 2.28 上工作,以查找添加或删除 "my string" 的补丁。

    我不知道这个功能已经存在多久了;该文档暗示它应该接受与git log 相同的所有选项,包括-S,但我清楚地记得几年前无法以这种方式搜索。

    【讨论】:

    • 这应该是公认的答案
    猜你喜欢
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 2017-06-03
    • 2023-02-23
    • 1970-01-01
    相关资源
    最近更新 更多